编程之美 2.4 “1”的数目及扩展问题
2017-05-31 16:26
176 查看
问题描述:
给定一个十进制整数N,求出从1到N的所有整数中出现”1”的个数。
例如:N=2,1,2出现了1个“1”。
N=12,1,2,3,4,5,6,7,8,9,10,11,12。出现了5个“1”。
解题思路:
1.计算从1到N经历的每个数中1的个数相加
其中数字i(1=<i<=N)中1的数目:分解出i的个位、十......最高位,分别判别是否等于1,等于则总数目加1
此程序时间复杂度:
编程之美书上写的是:
。
此程序很简单,需注意:求i各个位上数的过程中会破坏i,故要在求之前保存好i,在判别完后恢复i。
2.使用列举法寻找规律,进行数学归纳,用代码表示
归纳过程不再赘述,编程之美书上有,这里更正书里的一个错误:135页倒数第二段最后一句,114应改为14,123+1改为13+1。
归纳规律为:十进制表示第i为出现1的次数与第i位上的数字有关,设第i位上的数为p,i位以上的数字为高位数字,以下的数字为低位数字,如1700030,对于第三位来说,高位数字为1700,低位数字为30,则p满足以下规则:
p=0 高位数字*(10^(i-1))
p=1 高位数字*(10^(i-1))+低位数字+1
p=2 (高位数字+1)*(10^(i-1))
程序如下:
1.要准确的求取低位数字、当前位数字、高位数字;
2.每个case之后要break,降低时间复杂度
3.记得factor要累乘,从而target不同位
此程序的时间复杂度为N的十进制位数,即
改进:
对于上述分类归纳,可以进一步归纳,可以看出,无论p为几,该位“1”的个数均包括高位数字*(10^(i-1)),P不同时附加的值不同。P为0或1,附加的值是(低位数字+1)*p;p为其他,附加的值是10^(i-1)。
在程序中,只需要定义变量addnum,利用条件表达式,addnum=p>1?10^(i-1):(低位数字+1)*p;从而避免了繁琐的switch语句。
扩展问题:
给定一个十进制整数N,求出从1到N的所有整数二进制表达中出现”1”的个数。
对于这个问题,我们同样枚举二进制表达每一位上出现“1”的次数,总结归纳,可得:
第i位上“1”出现的次数=高位*(2^(i-1))+第i位数字+低位数字
程序为:
此程序的时间复杂度为N的二进制位数,即
。
给定一个十进制整数N,求出从1到N的所有整数中出现”1”的个数。
例如:N=2,1,2出现了1个“1”。
N=12,1,2,3,4,5,6,7,8,9,10,11,12。出现了5个“1”。
解题思路:
1.计算从1到N经历的每个数中1的个数相加
其中数字i(1=<i<=N)中1的数目:分解出i的个位、十......最高位,分别判别是否等于1,等于则总数目加1
#include <iostream> using namespace std; typedef unsigned long long int mm; mm numberof1(mm N){ mm num=0; for(mm i=1;i<=N;i++){ mm m=0,j=i; while(i!=0){ m=i%10; if(m==1) num++; i=i/10; } i=j; } return num; }
此程序时间复杂度:
编程之美书上写的是:
。
此程序很简单,需注意:求i各个位上数的过程中会破坏i,故要在求之前保存好i,在判别完后恢复i。
2.使用列举法寻找规律,进行数学归纳,用代码表示
归纳过程不再赘述,编程之美书上有,这里更正书里的一个错误:135页倒数第二段最后一句,114应改为14,123+1改为13+1。
归纳规律为:十进制表示第i为出现1的次数与第i位上的数字有关,设第i位上的数为p,i位以上的数字为高位数字,以下的数字为低位数字,如1700030,对于第三位来说,高位数字为1700,低位数字为30,则p满足以下规则:
p=0 高位数字*(10^(i-1))
p=1 高位数字*(10^(i-1))+低位数字+1
p=2 (高位数字+1)*(10^(i-1))
程序如下:
mm quicknumof1(mm N){ mm low=0,cur=0,high=0,num=0,factor=1; while((N/factor)!=0){ low=N-(N/factor)*factor; cur=(N/factor)%10; high=(N/factor)/10; switch(cur){ case 0: num+=high*factor; break; case 1: num+=high*factor+(low+1); break; default: num+=(high+1)*factor; break; } factor*=10; } return num; }程序中注意:
1.要准确的求取低位数字、当前位数字、高位数字;
2.每个case之后要break,降低时间复杂度
3.记得factor要累乘,从而target不同位
此程序的时间复杂度为N的十进制位数,即
改进:
对于上述分类归纳,可以进一步归纳,可以看出,无论p为几,该位“1”的个数均包括高位数字*(10^(i-1)),P不同时附加的值不同。P为0或1,附加的值是(低位数字+1)*p;p为其他,附加的值是10^(i-1)。
在程序中,只需要定义变量addnum,利用条件表达式,addnum=p>1?10^(i-1):(低位数字+1)*p;从而避免了繁琐的switch语句。
扩展问题:
给定一个十进制整数N,求出从1到N的所有整数二进制表达中出现”1”的个数。
对于这个问题,我们同样枚举二进制表达每一位上出现“1”的次数,总结归纳,可得:
第i位上“1”出现的次数=高位*(2^(i-1))+第i位数字+低位数字
程序为:
mm quicknumofbinary1(int N){ int lowdigit=0,curdigit=0,highdigit=0,num=0,factor=1; while((N/factor)!=0){ lowdigit=N-(N/factor)*factor; curdigit=(N/factor)%2; highdigit=(N/factor)/2; num+=highdigit*factor+curdigit+lowdigit; factor*=2; } return num; }
此程序的时间复杂度为N的二进制位数,即
。
相关文章推荐
- 编程之美--2.4 1的数目之扩展问题
- 编程之美--高效率算出1的数目之扩展问题
- 读书笔记之编程之美 - 2.4 1的数目
- 编程之美 2.4 “1”的数目
- 编程之美2.4扩展问题
- 编程之美-2.4 1的数目
- 1的数目_扩展问题
- 最近碰到个问题,关于php扩展编程如何返回数组的问题
- 编程之美 2.3 寻找发帖水王扩展问题
- [zz]编程之美-重建二叉树扩展问题1 2
- 编程之美---->蚂蚁爬杆之扩展问题,第i个蚂蚁什么时候走出木杆
- 编程之美-快速寻找满足条件的2个数(扩展问题)的一个解法的注释
- 编程之美3.11扩展问题
- 编程之美-2.4-1的数目
- 编程之美-程序改错及扩展问题
- 编程之美---小飞的电梯调度问题 1.8 扩展2
- 编程之美--发帖水王及扩展问题
- 编程之美-重建二叉树扩展问题1 2
- 编程之美 寻找发帖水王 扩展问题
- 编程之美---快速寻找满足条件的两个数---扩展问题