洛谷 P1015 回文数 解题思路及答案

题目:

解题思路:  首先考虑到 M它的进制是未知的,并且100位之内,显然我们传统的 int、long long型就不能满足其要求,故这里考虑 用数组进行存储 

又因为  不知道输入的时候M是多少位 直接用 int型 数组显然不方便,也不太现实。这里就用到我们 之前的帖子(P1009 高精度算法)里面讲的  用   字符型数组  转换  整形数组 。   整型数组里面存储的是 M这个数的每一位!!!

洛谷 P1009 阶乘之和 (高精度算法)-优快云博客

整体代码为:

#include<stdio.h>
#include<string.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	char arr1[100] = "0";
	scanf("%s", arr1);
	int arr2[150] = { 0 };
	int arr3[150] = { 0 };
	int zu=strlen(arr1);
	int i = 0;
	int g = 0;
	int step = 0;

	for (i = 0; i <= zu - 1; ++i)
	{
		if (arr1[zu - i - 1] >= 'A')
		{
			arr2[i] = arr1[zu - i - 1] - 'A';
			arr2[i] += 10;
		}
		else
		arr2[i] = arr1[zu - i - 1] - '0';
	}


  int jin = 0;
	
  do {
	  for (g = 149; g >= 0; --g)
	  {
		  if (arr2[g] != 0)
			  break;
	  }
	  for (i = 0; i <= g; ++i)
		  arr3[i] = arr2[g - i];

	  int floag = 1;
	  for (i = 0; i <= g / 2 + 1; ++i)
	  {
		  if (arr2[i] != arr3[i])
		  {
			  floag = 0;
			  break;

		  }
	  }
	  if (floag == 1)
	  {
		  printf("STEP=%d", step);
		  break;
	  }
	  else
	  {
		  step++;
		  jin = 0;
		  for (i = 0; i <=799; ++i)
		  {
			  arr2[i] = arr2[i] + arr3[i] + jin;
			  jin = arr2[i] / n;
			  arr2[i] = arr2[i] % n;
		  }


	  }
  } while (step <= 30);

  if (step == 31)
	  printf("Impossible!");


		return 0;
}

代码分析

字符数组 用来接收输入的数字    在内存中字符是以ASC||码进行储存的

因为数字有100位 后面会 反复地加  存在进位  所以 数组大小 150 比较合适 

arr2[150]      arr3[150]     

然后就是下面,因为可能得进制有2~10 以及16  所以要分类讨论 

2~10 进制的话 其可能的数字就是 0~9   所以减去 字符‘0’  即可 得到的就是实际输入的数字

16进制的话 有ABCDEF    这道题的测试点是默认输入大写字母哈!!!!

 所以 这部分输入的数字  单独拎出来     最后+10 就好

依旧是倒着存  因为后边好进位   整体知识点和 高精度算法一样    不多赘述

<think> 我们正在讨论Scrapy框架中的扩展中间件。根据之前的对话,用户已经了解Scrapy有四种核心中间件类型:爬虫中间件、下载器中间件、扩展中间件(Extensions)和项目管道(Item Pipelines)。现在用户特别询问关于自定义扩展中间件的方法和示例。 扩展中间件(Extensions)是通过Scrapy的信号系统(signals)来工作的,它们可以在Scrapy运行的各个阶段插入自定义逻辑。创建自定义扩展需要以下步骤: 1. **定义扩展类**:创建一个类,并实现必要的方法。 2. **连接到信号**:在类中连接到Scrapy的各种信号(例如`spider_opened`, `spider_closed`等)。 3. **注册扩展**:在Scrapy的配置文件中启用扩展。 下面是一个自定义扩展的示例,该扩展在爬虫启动和关闭时打印日志,并在爬虫运行期间定期打印统计信息(模拟定时监控功能): ```python import logging from scrapy import signals from scrapy.exceptions import NotConfigured logger = logging.getLogger(__name__) class MyExtension: """自定义扩展,用于监控爬虫运行状态""" def __init__(self, stats, interval=60.0): # 初始化统计信息和间隔时间 self.stats = stats self.interval = interval # 定时任务句柄 self.task = None @classmethod def from_crawler(cls, crawler): # 获取配置中的间隔时间,如果没有配置则使用默认值60秒 interval = crawler.settings.getfloat('MYEXT_INTERVAL', 60.0) # 如果扩展未启用,则抛出异常 if not crawler.settings.getbool('MYEXT_ENABLED', True): raise NotConfigured # 创建扩展实例 ext = cls(crawler.stats, interval) # 连接信号 crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened) crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed) return ext def spider_opened(self, spider): """爬虫启动时执行""" logger.info(f"Spider opened: {spider.name}") # 启动定时任务 from twisted.internet import task self.task = task.LoopingCall(self.log_stats, spider) self.task.start(self.interval) def log_stats(self, spider): """定时记录统计信息""" stats = self.stats.get_stats() logger.info(f"Spider {spider.name} stats: {stats}") def spider_closed(self, spider): """爬虫关闭时执行""" logger.info(f"Spider closed: {spider.name}") # 停止定时任务 if self.task and self.task.running: self.task.stop() ``` 在项目的`settings.py`中启用该扩展: ```python EXTENSIONS = { 'myproject.extensions.MyExtension': 500, # 优先级设为500 } MYEXT_ENABLED = True # 默认已启用,此项可省略 MYEXT_INTERVAL = 30.0 # 设置间隔时间为30秒 ``` 这个扩展做了以下事情: - 在爬虫启动时开始一个定时任务,每隔一段时间(通过`MYEXT_INTERVAL`设置)打印一次统计信息。 - 在爬虫关闭时停止定时任务。 注意: - 扩展类必须实现`from_crawler`类方法,用于创建扩展实例并连接信号。 - 使用`crawler.signals.connect`来连接信号处理函数。 - 扩展的执行顺序由`EXTENSIONS`设置中的优先级数值决定(数值越小越先执行)。 通过这种方式,我们可以轻松地扩展Scrapy的功能,例如实现监控、报警、资源清理等。 §§相关问题§§ 1. Scrapy扩展中间件如何接入外部监控系统(如Prometheus)? 2. 如何在Scrapy扩展中处理异常并发送警报? 3. Scrapy的信号系统支持哪些关键生命周期事件? </think> ### Scrapy自定义扩展中间件方法与示例 在Scrapy框架中,自定义扩展中间件(Extensions)是通过订阅**事件系统(signals)**实现的全局功能增强组件。它不属于请求/响应流水线,但能访问Scrapy核心对象(如crawler、stats),常用于监控、通知等场景。 #### 创建方法 1. **定义扩展类** 需实现`from_crawler`类方法和事件处理方法: ```python from scrapy import signals class MyExtension: def __init__(self, crawler): self.crawler = crawler @classmethod def from_crawler(cls, crawler): ext = cls(crawler) # 订阅事件 crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened) crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed) return ext def spider_opened(self, spider): print(f"爬虫启动: {spider.name}") def spider_closed(self, spider, reason): print(f"爬虫关闭: {spider.name}, 原因: {reason}") ``` 2. **注册扩展** 在`settings.py`中激活: ```python EXTENSIONS = { 'myproject.extensions.MyExtension': 500, # 数值表示优先级 } ``` #### 实用示例 **定时性能监控扩展** 每60秒记录爬虫状态: ```python from twisted.internet import task class StatsMonitorExtension: def __init__(self, crawler): self.stats = crawler.stats self.interval = 60 # 秒 self.task = None @classmethod def from_crawler(cls, crawler): ext = cls(crawler) crawler.signals.connect(ext.spider_opened, signals.spider_opened) crawler.signals.connect(ext.spider_closed, signals.spider_closed) return ext def spider_opened(self, spider): self.task = task.LoopingCall(self.log_stats, spider) self.task.start(self.interval) def log_stats(self, spider): stats_data = { "pages": self.stats.get_value('response_received_count', 0), "items": self.stats.get_value('item_scraped_count', 0), "errors": self.stats.get_value('log_count/ERROR', 0) } print(f"[监控] {spider.name}状态: {stats_data}") def spider_closed(self, spider, reason): if self.task and self.task.running: self.task.stop() ``` #### 关键特性 1. **事件订阅机制**: - `engine_started`/`engine_stopped`:引擎启停 - `spider_opened`/`spider_closed`:爬虫启停 - `item_scraped`:数据项抓取成功 - `item_dropped`:数据项被丢弃[^3] 2. **核心对象访问**: ```python def from_crawler(cls, crawler): # 获取配置 interval = crawler.settings.getfloat('STATS_INTERVAL', 60) # 访问统计收集器 stats = crawler.stats # 访问爬虫配置 spider_settings = crawler.spider.settings ``` 3. **执行优先级控制** 通过`EXTENSIONS`字典的值调整顺序(值越小优先级越高)[^1] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值