第八节:Asp.Net Core整合Log4net(官方的、微软的两种)
一. 整合Log4net
1. 简单说明
对于log4net 官方的程序集而言,从2.0.7开始就支持.Net Core了,这里我们采用的是2.0.8,虽然好久没更新了,但不影响使用。Core版本与普通的.Net版本下的使用方法非常类似,仅仅多了一步【创建日志仓储对象】CreateRepository而已,在实际框架封装中,建议把ILoggerRepository和ILog对象设置成单例的。
.Net 版本的Log4Net参考:https://www.cnblogs.com/yaopengfei/p/9428206.html
2. 使用步骤
声明:【使用的是log4net官方程序集,MyLog02项目直接Nuget Log4net 程序集即可,使用的是该层中的Xml文件下的log4net.xml配置文件】
(1).通过Nuget安装【log4net 2.0.8】,并将log4net.xml配置文件拷贝到Xml文件夹下,将其生成操作改为“嵌入的资源”.
PS:log4net.xml文件与.Net版本下使用的一致,直接拷贝过来的,代码如下:
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <!-- 一. 添加log4net的自定义配置节点-->
- <configSections>
- <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
- </configSections>
- <!--二. log4net的核心配置代码-->
- <log4net>
- <!--1. 输出途径(一) 将日志以回滚文件的形式写到文件中-->
- <!--模式一:全部存放到一个文件夹里-->
- <appender name="log0" type="log4net.Appender.RollingFileAppender">
- <!--1.1 文件夹的位置(也可以写相对路径)-->
- <param name="File" value="D:\CoreLog\" />
- <!--相对路径-->
- <!--<param name="File" value="Logs/" />-->
- <!--1.2 是否追加到文件-->
- <param name="AppendToFile" value="true" />
- <!--1.3 使用最小锁定模型(minimal locking model),以允许多个进程可以写入同一个文件 -->
- <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
- <!--1.4 配置Unicode编码-->
- <Encoding value="UTF-8" />
- <!--1.5 是否只写到一个文件里-->
- <param name="StaticLogFileName" value="false" />
- <!--1.6 配置按照何种方式产生多个日志文件 (Date:日期、Size:文件大小、Composite:日期和文件大小的混合方式)-->
- <param name="RollingStyle" value="Composite" />
- <!--1.7 介绍多种日志的的命名和存放在磁盘的形式-->
- <!--1.7.1 在根目录下直接以日期命名txt文件 注意"的位置,去空格 -->
- <param name="DatePattern" value="yyyy-MM-dd".log"" />
- <!--1.7.2 在根目录下按日期产生文件夹,文件名固定 test.log -->
- <!--<param name="DatePattern" value="yyyy-MM-dd/"test.log"" />-->
- <!--1.7.3 在根目录下按日期产生文件夹,这是按日期产生文件夹,并在文件名前也加上日期 -->
- <!--<param name="DatePattern" value="yyyyMMdd/yyyyMMdd"-test.log"" />-->
- <!--1.7.4 在根目录下按日期产生文件夹,这再形成下一级固定的文件夹 -->
- <!--<param name="DatePattern" value="yyyyMMdd/"OrderInfor/test.log"" />-->
- <!--1.8 配置每个日志的大小。【只在1.6 RollingStyle 选择混合方式与文件大小方式下才起作用!!!】可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志,
- 超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。-->
- <param name="maximumFileSize" value="10MB" />
- <!--1.9 最多产生的日志文件个数,超过则保留最新的n个 将value的值设置-1,则不限文件个数 【只在1.6 RollingStyle 选择混合方式与文件大小方式下才起作用!!!】
- 与1.8中maximumFileSize文件大小是配合使用的-->
- <param name="MaxSizeRollBackups" value="5" />
- <!--1.10 配置文件文件的布局格式,使用PatternLayout,自定义布局-->
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="记录时间:%date %n线程ID:[%thread] %n日志级别:%-5level %n出错类:%logger property: [%property{NDC}] - %n错误描述:%message%newline %n%newline"/>
- </layout>
- </appender>
- <!--模式二:分文件夹存放-->
- <!--文件夹1-->
- <appender name="log1" type="log4net.Appender.RollingFileAppender">
- <param name="File" value="D:\CoreLog\OneLog\" />
- <param name="AppendToFile" value="true" />
- <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
- <Encoding value="UTF-8" />
- <param name="StaticLogFileName" value="false" />
- <param name="RollingStyle" value="Composite" />
- <param name="DatePattern" value="yyyy-MM-dd".log"" />
- <param name="maximumFileSize" value="10MB" />
- <param name="MaxSizeRollBackups" value="5" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="记录时间:%date %n错误描述:%message%newline %n%newline"/>
- </layout>
- <!--下面是利用过滤器进行分文件夹存放,两种过滤器进行配合-->
- <!--与Logger名称(OneLog)匹配,才记录,-->
- <filter type="log4net.Filter.LoggerMatchFilter">
- <loggerToMatch value="OneLog" />
- </filter>
- <!--阻止所有的日志事件被记录-->
- <filter type="log4net.Filter.DenyAllFilter" />
- </appender>
- <!--文件夹2-->
- <appender name="log2" type="log4net.Appender.RollingFileAppender">
- <param name="File" value="D:\CoreLog\TwoLog\" />
- <param name="AppendToFile" value="true" />
- <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
- <Encoding value="UTF-8" />
- <param name="StaticLogFileName" value="false" />
- <param name="RollingStyle" value="Composite" />
- <param name="DatePattern" value="yyyy-MM-dd".log"" />
- <param name="maximumFileSize" value="10MB" />
- <param name="MaxSizeRollBackups" value="5" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="记录时间:%date %n错误描述:%message%newline %n%newline"/>
- </layout>
- <!--下面是利用过滤器进行分文件夹存放,两种过滤器进行配合-->
- <!--与Logger名称(TwoLog)匹配,才记录,-->
- <filter type="log4net.Filter.LoggerMatchFilter">
- <loggerToMatch value="TwoLog" />
- </filter>
- <!--阻止所有的日志事件被记录-->
- <filter type="log4net.Filter.DenyAllFilter" />
- </appender>
- <!--2. 输出途径(二) 记录日志到数据库-->
- <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
- <!--2.1 设置缓冲区大小,只有日志记录超设定值才会一块写入到数据库-->
- <param name="BufferSize" value="1" />
- <!--2.2 引用-->
- <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
- <!--2.3 数据库连接字符串-->
- <connectionString value="data source=localhost;initial catalog=LogDB;integrated security=false;persist security info=True;User ID=sa;Password=123456" />
- <!--2.4 SQL语句插入到指定表-->
- <commandText value="INSERT INTO LogInfor ([threadId],[log_level],[log_name],[log_msg],[log_exception],[log_time]) VALUES (@threadId, @log_level, @log_name, @log_msg, @log_exception,@log_time)" />
- <!--2.5 数据库字段匹配-->
- <!-- 线程号-->
- <parameter>
- <parameterName value="@threadId" />
- <dbType value="String" />
- <size value="100" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%thread" />
- </layout>
- </parameter>
- <!--日志级别-->
- <parameter>
- <parameterName value="@log_level" />
- <dbType value="String" />
- <size value="100" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%level" />
- </layout>
- </parameter>
- <!--日志记录类名称-->
- <parameter>
- <parameterName value="@log_name" />
- <dbType value="String" />
- <size value="100" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%logger" />
- </layout>
- </parameter>
- <!--日志信息-->
- <parameter>
- <parameterName value="@log_msg" />
- <dbType value="String" />
- <size value="5000" />
- <layout type="log4net.Layout.PatternLayout">
- <conversionPattern value="%message" />
- </layout>
- </parameter>
- <!--异常信息 指的是如Infor 方法的第二个参数的值-->
- <parameter>
- <parameterName value="@log_exception" />
- <dbType value="String" />
- <size value="2000" />
- <layout type="log4net.Layout.ExceptionLayout" />
- </parameter>
- <!-- 日志记录时间-->
- <parameter>
- <parameterName value="@log_time" />
- <dbType value="DateTime" />
- <layout type="log4net.Layout.RawTimeStampLayout" />
- </parameter>
- </appender>
- <!--(二). 配置日志的的输出级别和加载日志的输出途径-->
- <root>
- <!--1. level中的value值表示该值及其以上的日志级别才会输出-->
- <!--OFF > FATAL(致命错误) > ERROR(一般错误) > WARN(警告) > INFO(一般信息) > DEBUG(调试信息) > ALL -->
- <!--OFF表示所有信息都不写入,ALL表示所有信息都写入-->
- <level value="ALL"></level>
- <!--2. append-ref标签表示要加载前面的日志输出途径代码 通过ref和appender标签的中name属性相关联-->
- <!--<appender-ref ref="AdoNetAppender"></appender-ref>-->
- <appender-ref ref="log0"></appender-ref>
- <appender-ref ref="log1"></appender-ref>
- <appender-ref ref="log2"></appender-ref>
- </root>
- </log4net>
- </configuration>
(2).创建日志仓储对象, 在框架封装的时候,建议把该对象封装成单例的。
- ILoggerRepository repository = LogManager.CreateRepository("myRespository");
(3).加载XML文件,前提要先把xml属性改为“嵌入的资源”,这里主要有两种方式,一种是反射的方式加载,需要加上“程序集名称”,如下面代码中的“MyLog”;另外一种是文件的方式,直接定位到文件路径即可。
A:反射
- Assembly assembly = Assembly.GetExecutingAssembly();
- var xml = assembly.GetManifestResourceStream("MyLog.Xml.log4net.xml");
- XmlConfigurator.Configure(repository, xml);
B:文件加载
- var file = new FileInfo(Directory.GetCurrentDirectory() + "/Xml/log4net.xml");
- XmlConfigurator.Configure(repository, file);
(4).创建日志对象,
如: ILog log = LogManager.GetLogger(repository.Name, "all");
特别注意:这里和.Net平台有区别,第一个参数必须是仓储对象的名称,建议直接这么写:repository.Name,第二个参数就是以前.Net 平台下类似的,可以随意起名,如果要分文件存储的话,要配合xml文件中的过滤器,<filter type="log4net.Filter.LoggerMatchFilter"><loggerToMatch value = "OneLog" /></ filter >,实现分文件夹存储。
(5). 开开心心的使用Info、Debug等方法写入日志即可。
完整代码如下:
- //1.创建日志仓储对象
- ILoggerRepository repository = LogManager.CreateRepository("myRespository");
- //2.加载xml文件
- //2.1 反射的方式加载
- //Assembly assembly = Assembly.GetExecutingAssembly();
- //var xml = assembly.GetManifestResourceStream("MyLog.Xml.log4net.xml");
- //XmlConfigurator.Configure(repository, xml);
- //2.2 文件的方式加载
- var file = new FileInfo(Directory.GetCurrentDirectory() + "/Xml/log4net.xml");
- XmlConfigurator.Configure(repository, file);
- //3. 创建日志对象
- ILog log = LogManager.GetLogger(repository.Name, "all");
- ILog OneLog = LogManager.GetLogger(repository.Name, "OneLog");
- //4. 写入日志
- log.Info("alllog");
- OneLog.Info("oneLog");
二. 分层封装使用
1.声明:
MyLog02层仅仅需要添加对Utils层的引用,不需要再引入任何程序集。
2.目的:
在Utils层中封装Log4net,然后可以在其它层中通过引用,直接调用。
3. 步骤:
(1). 给Utils层通过Nuget安装【log4net 2.0.8】,并将log4net.xml配置文件拷贝到Xml文件夹下,将其生成操作改为“嵌入的资源”。
(2). 新建LogUtils类,对log4net进行封装,其中日志仓储对象利用静态变量做成单例的。
代码如下:
- public class LogUtils
- {
- //日志仓储(单例模式,静态变量,程序在第一次使用的时候被调用,由clr保证)
- private static ILoggerRepository loggerRepository;
- //1. 适用于全部文件夹
- public static ILog log;
- //2. OneLog文件夹
- public static ILog log1;
- //3. TwoLog文件夹
- public static ILog log2;
- //声明文件夹名称(这里分两个文件夹)
- static string log1Name = "OneLog";
- static string log2Name = "TwoLog";
- /// <summary>
- /// 初始化Log4net的配置
- /// xml文件一定要改为嵌入的资源
- /// </summary>
- public static void InitLog4Net()
- {
- //1. 创建日志仓储(单例)
- loggerRepository = loggerRepository ?? LogManager.CreateRepository("myLog4net");
- //2. 加载xml文件
- Assembly assembly = Assembly.GetExecutingAssembly();
- var xml = assembly.GetManifestResourceStream("Utils.Xml.log4net.xml");
- log4net.Config.XmlConfigurator.Configure(loggerRepository, xml);
- //3. 创建日志对象
- log = LogManager.GetLogger(loggerRepository.Name,"all");
- log1 = LogManager.GetLogger(loggerRepository.Name, log1Name);
- log2 = LogManager.GetLogger(loggerRepository.Name, log2Name);
- }
- /************************* 五种不同日志级别 *******************************/
- //FATAL(致命错误) > ERROR(一般错误) > WARN(警告) > INFO(一般信息) > DEBUG(调试信息)
- #region 00-将调试的信息输出,可以定位到具体的位置(解决高层封装带来的问题)
- /// <summary>
- /// 将调试的信息输出,可以定位到具体的位置(解决高层封装带来的问题)
- /// </summary>
- /// <returns></returns>
- private static string getDebugInfo()
- {
- StackTrace trace = new StackTrace(true);
- return trace.ToString();
- }
- #endregion
- #region 01-DEBUG(调试信息)
- /// <summary>
- /// DEBUG(调试信息)
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="logName">文件夹名称</param>
- public static void Debug(string msg, string logName = "")
- {
- if (logName == "")
- {
- log.Debug(getDebugInfo() + msg);
- }
- else if (logName == log1Name)
- {
- log1.Debug(msg);
- }
- else if (logName == log2Name)
- {
- log2.Debug(msg);
- }
- }
- /// <summary>
- /// Debug
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="exception">错误信息</param>
- public static void Debug(string msg, Exception exception)
- {
- log.Debug(getDebugInfo() + msg, exception);
- }
- #endregion
- #region 02-INFO(一般信息)
- /// <summary>
- /// INFO(一般信息)
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="logName">文件夹名称</param>
- public static void Info(string msg, string logName = "")
- {
- if (logName == "")
- {
- log.Info(getDebugInfo() + msg);
- }
- else if (logName == log1Name)
- {
- log1.Info(msg);
- }
- else if (logName == log2Name)
- {
- log2.Info(msg);
- }
- }
- /// <summary>
- /// Info
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="exception">错误信息</param>
- public static void Info(string msg, Exception exception)
- {
- log.Info(getDebugInfo() + msg, exception);
- }
- #endregion
- #region 03-WARN(警告)
- /// <summary>
- ///WARN(警告)
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="logName">文件夹名称</param>
- public static void Warn(string msg, string logName = "")
- {
- if (logName == "")
- {
- log.Warn(getDebugInfo() + msg);
- }
- else if (logName == log1Name)
- {
- log1.Warn(msg);
- }
- else if (logName == log2Name)
- {
- log2.Warn(msg);
- }
- }
- /// <summary>
- /// Warn
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="exception">错误信息</param>
- public static void Warn(string msg, Exception exception)
- {
- log.Warn(getDebugInfo() + msg, exception);
- }
- #endregion
- #region 04-ERROR(一般错误)
- /// <summary>
- /// ERROR(一般错误)
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="logName">文件夹名称</param>
- public static void Error(string msg, string logName = "")
- {
- if (logName == "")
- {
- log.Error(getDebugInfo() + msg);
- }
- else if (logName == log1Name)
- {
- log1.Error(msg);
- }
- else if (logName == log2Name)
- {
- log2.Error(msg);
- }
- }
- /// <summary>
- /// Error
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="exception">错误信息</param>
- public static void Error(string msg, Exception exception)
- {
- log.Error(getDebugInfo() + msg, exception);
- }
- #endregion
- #region 05-FATAL(致命错误)
- /// <summary>
- /// FATAL(致命错误)
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="logName">文件夹名称</param>
- public static void Fatal(string msg, string logName = "")
- {
- if (logName == "")
- {
- log.Fatal(getDebugInfo() + msg);
- }
- else if (logName == log1Name)
- {
- log1.Fatal(msg);
- }
- else if (logName == log2Name)
- {
- log2.Fatal(msg);
- }
- }
- /// <summary>
- /// Fatal
- /// </summary>
- /// <param name="msg">日志信息</param>
- /// <param name="exception">错误信息</param>
- public static void Fatal(string msg, Exception exception)
- {
- log.Fatal(getDebugInfo() + msg, exception);
- }
- #endregion
- }
(3). 对“MyLog”项目添加对“Utils”的引用,然后在Startup类中ConfigureServices方法中进行初始化Log4net,如下:
- LogUtils.InitLog4Net();
(4).根据情况进行调用。
如:LogUtils.Info("我是二哈"); LogUtils.Info("我是二哈1", "OneLog");
三. 微软出品的日志程序
1. 声明:
微软的日志扩展库中新增了对Log4Net的支持,仅仅需要在MyLog2项目中引入微软自己的 【Microsoft.Extensions.Logging.Log4Net.AspNetCore】 2.2.11即可,不需要再重复引入log4net官方程序集。
2. 使用步骤:
(1). 通过Nuget安装程序集【Microsoft.Extensions.Logging.Log4Net.AspNetCore】,版本号:2.2.11
(2). 在Xml文件夹中新建一个log4net2.xml的配置文件,并将其改为 “始终复制!!!”【这里和前面处理配置文件的方式不同哦】
(3). 在Startup类中的Configure方法中先注入ILoggerFactory对象,然后初始化log4net,代码如下:
- loggerFactory.AddLog4Net("Xml/log4net2.xml");
解释:这里加载的是bin最终目录下的文件,所以步骤②中要将其改为“始终复制”(即复制到bin的最终目录下),如果这里不写参数,默认加载的是bin最终目录下的log4net.config文件。
(4). 在控制器里通过构造函数注入ILogger对象,注入的时候一定要注意<out TCategoryName> ,需要传入一个值。
(5). 进行调用,这里有两种方式区分日志级别:Log(LogLevel.Warning, "LogLevel.Warning"); 或者LogWarning("LogLevel.Warning");
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
第八节:Asp.Net Core整合Log4net(官方的、微软的两种)的更多相关文章
- 第三节:Windows平台部署Asp.Net Core应用(基于IIS和Windows服务两种模式)
一. 简介 二. 文件系统发布至IIS 三. Web部署发布至IIS 四. FTP发布至IIS 五. Windows服务的形式发布 ! 作 者 : Yaopengfei(姚鹏飞) 博客地址 ...
- ASP.NET Core整合Zipkin链路跟踪
前言 在日常使用ASP.NET Core的开发或学习中,如果有需要使用链路跟踪系统,大多数情况下会优先选择SkyAPM.我们之前也说过SkyAPM设计确实比较优秀,巧妙的利用Diagnosti ...
- asp.net core 集成 log4net 日志框架
asp.net core 集成 log4net 日志框架 Intro 在 asp.net core 中有些日志我们可能想输出到数据库或文件或elasticsearch等,如果不自己去实现一个 Logg ...
- Asp.net core 使用log4net作为日志组件,记录日志到本地。
原文:Asp.net core 使用log4net作为日志组件,记录日志到本地. GitHub demo :https://github.com/zhanglilong23/Asp.NetCore.D ...
- ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式
由于ASP.NET Core应用是一个同时处理多个请求的服务器应用,所以在处理某个请求过程中抛出的异常并不会导致整个应用的终止.出于安全方面的考量,为了避免敏感信息的外泄,客户端在默认的情况下并不会得 ...
- ASP.NET Core 整合Autofac和Castle实现自动AOP拦截
前言: 除了ASP.NETCore自带的IOC容器外,我们还可以使用其他成熟的DI框架,如Autofac,StructureMap等(笔者只用过Unity,Ninject和Castle). 1.ASP ...
- ASP.NET Core使用log4net记录日志
.NET常用的日志组件有NLog.Log4net等,.NET CORE下微软也自带了日志组件,到目前为止还没用过,而我本人常用的是log4net,下面简单讲讲.NET CORE下怎么使用log4net ...
- .NET Core整合log4net以及全局异常捕获实现2
Startup代码 public static ILoggerRepository repository { get; set; } public Startup(IConfiguration con ...
- ASP.NET Core 集成测试中模拟登录用户的一种姿势
不管哪种用户验证方式,最终都是在验证成功后设置 HttpContext.User ,后续处理环节通过 HttpContext.User 获取用户信息.如果能直接修改 HttpContext.User ...
随机推荐
- BUAA-OO-2019 第四单元总结
UML作业架构设计 这一单元的作业本质上是对数据之间的联系进行解析,并重新建立数据结构以方便查询的工作,这就要求我们了解各种UmlElement的结构以及他们之间的关系是如何组织的. 第十三次作业 在 ...
- django framework插件使用1
安装 REST框架要求以下内容: Python(3.5.3.6.3.7) Django(1.11.2.0.2.1.2.2) pip install djangorestframework pip in ...
- php获取ssl验证的https页面的源码
$response = "https://faculty.xidian.edu.cn/system/resource/tsites/tsitesencrypt.jsp?id=_tsites_ ...
- 通过async实现协程的延迟执行及结果获取
在上一次https://www.cnblogs.com/webor2006/p/12022065.html对于协程的async和wait进行了初步的学习,其可以加速执行的性能,其实对于async它是提 ...
- python脚本测试websocket接口协议
import websocket url = 'wss://host:port/rt/tr' #websocket连接地址 ws = websocket.create_connection(url) ...
- LCD编程_简单测试
首先,需要编写一个led_test.c的文件,依据代码框架,在led_test.c中我们能够看到的只是led.c.我们是看不到led_controller.c的.比如说,在led_test.c中,需要 ...
- 配置Maven环境变量-Eclipse/Idea添加Maven
1. 文件下载 官网下载地址:http://maven.apache.org/download.cgi 下方有我提供的下载链接. 由于下载缓慢,提供一份我的下载链接:https://www.lanzo ...
- Pandas | 28 与SQL比较
由于许多潜在的Pandas用户对SQL有一定的了解,因此本文章旨在提供一些如何使用Pandas执行各种SQL操作的示例. 文件:tips.csv - total_bill,tip,sex,smoker ...
- axios post方式请求x-ww格式的数据
//使用axios时,要确定是json格式还是x-www格式的,axios默认是json格式的,如果是x-ww格式需要做如下配置: let url = "/hehe/site/getcomm ...
- 搜索法 | 1103 dfs搜索:符合条件的多项式
其实这题我已经写过两遍了,但都是在看过算法笔记的情况下写的.方法不难,只要能想出来. 找到一个项数为k,每项为p次幂,和为n,并且在有多个结果的情况下要求数字之和最大的一个多项式.如果数字之和相等.还 ...