1的数目

来源:互联网 发布:流程图软件 安卓 编辑:程序博客网 时间:2024/04/29 22:56
《编程之美》第2.4节:1的数目

题目:给定一个十进制整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有"1"的个数。

方法一:暴力枚举,肯定能够算出来,但是这样的复杂度为O(NlgN)。

方法二:寻找规律,用公式计算,复杂度为O(lgN)。当某一位的数为0时,这个位上出现1的总次数就等于其高位数字乘以其所在位的权重,加入21023,百位为0,则其出现1的个数为21*100,100是0所在位的权重。如果为1,则等于其高位数字乘以其所在位置的权重,然后加上其低位数字再加1,如21123,出现1的个数为21*100+23+1,+1的原因是由于100这个特殊的情况。如果当前位不为0也不为1,则等于其高位数字+1在乘以其所在位置的权重,如21223,出现1的个数(21+1)*100,其中+1的原因是:当前位已经大于1了,因此相当于1已经出现了。

#include<iostream>using namespace std;unsigned long count1InAnInteger1(unsigned long n){unsigned long result=0;for(int i=1;i<=n;i++){unsigned long temp=i;while(temp){if(temp%10==1)result++;temp/=10;}}return result;}unsigned long count1InAnInteger2(unsigned long n){unsigned long result=0;unsigned long high=0,low=0,temp=n,bit=0,pow10=1;int curr=0;while(pow10<=temp){low=temp%pow10;high=temp/pow10/10;curr=high%10;switch(curr){case 0:result+=high*pow10;break;case 1:result+=high*pow10+low+1;break;default:result+=(high+1)*pow10;break;}pow10*=10;}return result;}int main(){cout<<count1InAnInteger1(10000)<<endl;cout<<count1InAnInteger2(10000)<<endl;system("pause");return 0;}


0 0