统计数字问题
问题描述:
一本书的页码从自然数1 开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如,第6 页用数字6 表示,而不是06 或006 等。数
字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2,…,9。
编程任务:
给定表示书的总页码的10 进制整数n (1≤n≤109) 。编程计算书的全部页码中分别用到多少次数字0,1,2,…,9。
数据输入:
输入数据由文件名为input.txt的文本文件提供。每个文件只有1 行,给出表示书的总页码的整数n。
结果输出:
程序运行结束时,将计算结果输出到文件output.txt中。输出文件共有10行,在第k行
输出页码中用到数字k-1 的次数,k=1,2,…,10。
输入文件示例 输出文件示例
input.txt
11
output.txt
1
4
1
1
1
1
1
1
1
1
解题思路1:根据输入的数字Num,从1到Num 一 一统计每个数字出现的次数。
算法时间复杂度:
O(n*log10(n))
算法:
for(i
=
1;
i
<=
n;
i++)
{
t
=
i;
while(t)
{
count[t%
10]++;
//count数组是每个数字出现次数的计数器
t/=
10;
}
}
{
}
f(n)=10*f(n-1)+10^(n-1)
f(n-1)=10*f(n-2)+10^(n-2)
f(n-2)=10*f(n-3)+10^(n-3)
f(2)=10f(1)+10^1
可见:f(n)=10^(n-1)+(n-1)*10^(n-1)
即:f(n)=n*10^(n-1),利用此公式计算每个数字的出现次数,计算0的出现次数时,最后减去多余的前导0的出现次数即可。
举例(取区间法):
比如计算32871,从高位向低位看,可以看到该数包含3个0000~9999的区间(0~9999,10000~19999,20000~29999),即每个数字出现的次数为3f(4),其中多余的前导0出现在0000~9999区间中,经观察可知多了10^3+10^2+10^1+1个0。(0000-0999,10^3个0;000-099,10^2个0;00-09,10^1个0;开始的0,10^0个0)
其中,最高位上1,2共出现10^4次。接着计算30000~32871,此处最高位的3