算法1-1:统计数字问题

★问题描述:一本书的页码从自然数1开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0.例如第6页就用数字6表示,而不是06或006等。数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0.1.2.....9.

★算法设计:给定表示书的总页码的十进制整数n(1≤n≤10^9),计算书的全部页码中分别用到多少次数字0.1.2....9.

★数据输入:输入数据只有一行,表示书的总页数n

★结果输出:共10行,在第K行写出数字K-1的次数,K=1.2.3...10


首先来分析一下问题,给出一个数,比如说是一个四位数(4399),那我们可以把这个四位数分成三部分:

1-999

1000-3999

4000-4399


▲第一段1-999:

这段数字要考虑的问题是前面没有0,也就是说这999个数并不都是3位数,其实稍微算一下就能看出来总的数字个数是1*9+2*90+3*900=3*1000-111,也就是说这个前置区域的数字总个数是有规律可寻的:n*10^n-(10^n -1)/9---------本例中n=3

再来看数字的个数,1的个数也是有规律的,1位时是1个(1-9),两位时是20个(1-99,在个位时10个,在十位时十个),三位时是300个(1-999,20*10+100),也就是说1-9每位的个数是n*10^(n-1)当数的范围是1到10^n时---------本例中n=3

其他的数字2-9的地位和1是等价的,而0的个数则可以用减法减出来,用总数字个数减去1-9的数字个数:n*10^n -(10^n -1)/9减去9*n*10^(n-1)等于n*10^(n-1)-(10^n -1)/9------本例中n=3

第一段完事儿:1-9:300,0:189,总数字个数2889


▲第二段:1000-3999

如果除去千位的数字可以看出,后三位的数字都是等价的,空出的地方补了0,也就是说后三个位可以填的数字10*10*10,所以第二段的数字个数还是很好算的:0-9均是3*300(其中的3是指1000-1999,2000-2999,3000-3999三段),之后1.2.3三个数还要加上1000(作为最高位一直被加)

3000*4(三千个数,每个数四位)=10*3*300(0-9作为后三位出现的个数)+3*1000(1-3作为千位出现的次数)

第二段完事儿:1-3:1300,0和4-9:300个,1900*3+7*900=3000*4


▲第三段:4000-4399

第三段是最麻烦的,需要依次递减往下排:

先分百位段:4000-4299:这一段百位有300*3=900个数,其中0-9个数为3*20(3是十位的数,20在第一段中提到过计算的方法),然后0-2每个+100(作为百位)

之后十位段:4300-4389:这一段十位有90*2个数,其中0-9个数为9*1(9是十位的数,1的计算方法在第一段提到过),然后0-8每个+10(作为十位)

之后个位段:4390-4399:这一段各位有10个数,不用争,0-9一人一个(如果最后一位不是9,比如说是3,就是0.1.2.3挨个+1)

之后还要记得4的个数+400,3的个数+100,9的个数+10(在刚刚只计算了低位,没有计算高位)

最后第三段完事儿:10*3*20+3*100(第一段)+10*9+9*10(第二段)+10(第三段)+400+100+10=4*400=1600


过程有些繁琐,但是没有想出其他的好的方法,如果有更好的方法,欢迎在博客下面留言

你可能感兴趣的:(算法1-1:统计数字问题)