编程练习1——统计数字问题

该程序用于统计一本总页数为n的书中,页码从1到n中每个数字0到9出现的次数。通过读取'input.txt'文件获取页数,结果输出到'output.txt'。算法基于递推关系,考虑到前导0的情况,并递归处理不同位数的页码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

         一本书的页码从自然数1开始顺序编码直到自然数n。数的页码按照通常习惯编排,每个页码都不含多余的前导数字0.例如:

06,006等。数字统计问题要求对给定书的总页数n,统计出书的全部页码中分别用到多少次0,1,2,...,9

Input : 数据由"input.txt"文件提供,每个文件只有一行,给出表示书的总页数的整数n。

Output : 将程序输出的结果输出到“output”文件中。输出文件有10行,第k行中的数字表示用到数字k-1的次数。

分析:考察由0,1,2,...,9组成的m位数,共有10^m个m位数(考虑前导0),在这些数中0到9这10个数字用到的次数都相同,设为f(n).

则f(n)满足下面的递推关系:

图片

据此可从高位到低位进行统计,再减去多余的前导0的个数

算法:

/**
 * 数字统计算法
 *  n 待统计的数,m为n的位数
 *  设h是n的最高位 ,除去n的最高位h不看,剩下的m-1位数总的
 *  数字统计即是0到9的可重排列共10^(m-1)个,在这10^(m-1)个
 *  数字中0到9各分别出现了(m-1)*10^(m-2)次(注:书上的递推公式)
 *  而最高位包含这样的区间共h个,他们分别是:
 *  I1=[0,10^(m-1)-1],I2=[1*10^(m-2),2*10^(m-1)],...,Ih=[(h-1)*10(m-1), h*10^(m-1)]
 *  且|Ii| = 10^(m-1) i = 1,2,...,h(每个区间中的整数个数);
 *  结论1:从而从[0,h*10^(m-1)]内不包括最高位m位,0到9各出现了h*(m-1)*10^(m-2)次
 *  结论2:0到h-1这些数在最高位出现了10^(m-1)次
 *  结论3:h出现了 n%10^(m-1) + 1次
 *  对h以后的m-1位数做以上操作即可
 *
 *  前导0的计算算法:
 *  考虑一m为的数n,h为最高位
 *  在结论2中0为m位出现了10^(m-1)次
 *  00为最高位和次高为出现了10^(m-2)次
 *  一次类推
 */

### 关于算法分析实验中的统计数字问题 #### 实验目标 在算法分析课程中,统计数字问题是常见的练习之一。该类问题通常涉及处理大量数据并从中提取有用的信息。对于此类问题的研究不仅有助于理解基础的数据结构和算法设计原则,还能够提升编程技能以及解决实际应用的能力。 #### 数据预处理阶段 为了有效地完成统计工作,在接收原始输入之前应该先定义好如何解析这些信息。例如,在某些情况下可能需要读取文件作为输入源;而在其他场景下,则可能是通过标准输入获取一系列数值[^2]。 #### 排序与计数策略的选择 当面对大量的无序整数列表时,选择合适的排序方法至关重要。不同的排序技术具有各自的特点: - 对于较小规模的数据集可以选择简单直观的方法如插入排序或选择排序; - 当涉及到更大范围内的元素排列时,更高效的算法比如快速排序、归并排序会更加适用; - 特殊情形下还可以考虑采用特定类型的优化版本,像针对几乎已有序列的希尔排序能显著减少不必要的操作次数从而提高性能表现[^5]。 此外,如果仅需知道各个唯一值出现频率而不关心其相对顺序的话,那么可以直接利用哈希表(字典)来进行高效地频次记录,这相比传统意义上的完全排序要更快捷方便得多[^3]。 #### Python实现案例 下面给出一段基于Python语言编写的用于解决上述提到的任务——即统计一组给定范围内自然数出现次数的程序片段: ```python from collections import Counter def count_numbers(data, lower_bound=0, upper_bound=100): filtered_data = [num for num in data if lower_bound <= num <= upper_bound] counter = Counter(filtered_data) result = {i:counter[i] for i in range(lower_bound, upper_bound+1)} return dict(sorted(result.items())) # 测试函数 test_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]*10 + list(range(1, 101)) print(count_numbers(test_list)) ``` 此段代码首先过滤掉不在指定区间内的任何异常值,接着运用`collections.Counter()`来构建一个映射关系存储每个符合条件项的数量。最后按照键值升序整理输出结果以便阅读查看。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值