问题:给定一个十进制正整数N,写下从1到N的所有整数,然后数一下其中出现的所有1的个数。
书上解法一:
最简单的方法从1遍历每一个数,算算每个数中1出现的次数,具体代码如下:
1: unsigned int countInteger(int n)
2: {
3: unsigned int num = 0;
4: while(n != 0)
5: {
6: num += (n % 10 == 1) ? 1:0;
7: n /= 10;
8: }
9: return num;
10: }
11: void OneNumber(unsigned int n)
12: {
13: unsigned int Icount = 0;
14: for (int i = 1; i <= n; ++i)
15: {
16: Icount += countInteger(i);
17: }
18: cout<<"Icount="<<Icount<<endl;
19: }
书上解法二:
我们分析一下312这个数,个位上出现1的情况是:_ _ 1,显然前面两位数决定了个位上为1的数出现多少次,00 1->31 1 共有31 + 1 = 32个。那么十位上呢?_ 1 _,当百位上为0时,0 1 0 –>0 1 9共10个数,百位不为0呢?1 1 0->1 1 9,2 1 0->2 1 9,3 1 0->3 1 9,共30个。因此我们发现个位不对十位产生影响,除非没有百位。那么百位呢?1 00->1 99 共一百个,最高位和最低位一样,都受到它后面的和前面的数的影响。具体代码如下:
1: void SumNum(unsigned int n)
2: {
3: unsigned int iCount = 0;//
4: unsigned int iFactor = 1;//
5: unsigned int iLowerNum = 0;//当前位上的低位上的数字
6: unsigned int iCurNum = 0;//分别记录个位、十位..上的数字
7: unsigned int iHigherNum = 0;//当前位上的高位上的数字
8:
9: while((n / iFactor) != 0)
10: {
11: iLowerNum = n - (n / iFactor)*iFactor;
12: iCurNum = (n / iFactor) % 10;
13: iHigherNum = n / (iFactor*10);
14:
15: switch(iCurNum)
16: {
17: case 0:
18: iCount += iHigherNum*iFactor;
19: break;
20: case 1:
21: iCount += iHigherNum * iFactor + iLowerNum + 1;
22: break;
23: default:
24: iCount += (iHigherNum + 1)*iFactor;
25: break;
26: }
27: iFactor = iFactor * 10;
28: }
29: cout<<"iCount="<<iCount<<endl;
30: }