2.41的个数

问题:给定一个十进制整数N,求出从1到N的所有整数中出现”1”的个数。 

解法一:

最直接的方法就是从1开始遍历到N,将其中每一个数中含有“1”的个数加起来,就得到了问题的解。

1 int CountOne(int N){
2     int num=0;
3     while(N){
4              num+=((N%10==1)?1:0);
5              N/=10;
6              }
7     return num;
8     }

 此方法简单,容易理解,但它的问题是效率,时间复杂度为O(N * lgN),N比较大的时候,需要耗费很长的时间。

解法二:

归纳法寻找N的各位中包含1的规律:

如果当前位上的数字为0,则在该位上出现1的次数由更高位决定,等于更高位乘以当前位数(十位为10,百位为100);

如果当前位上的数字为等于1,则该位上出现1的次数由高位和低位共同决定:等于高位乘以当前位数加上低位数字加1

如果当前位上的数字大于1,则该位上出现1的次数由高位决定:等于高位数字加1然后乘以当前的位数。

int CountOne1(int N){
     int num=0;
     while(N){             
              num+=((N%10==1)?1:0);
              N/=10;
              }
     return num;
     }
int CountOne(int N){
    int iLow;
    int iCurr;
    int iHigh;
    int iCount;
    int iFactor=1;
    while(N/iFactor){
             iLow=N-(N/iFactor)*iFactor;
             iCurr=N/iFactor%10;
             iHigh=N/(iFactor*10);
             
             switch(iCurr){
                           case 0:
                                iCount+=iHigh*iFactor;
                                break;
                           case 1:
                                iCount+=iHigh*iFactor+iLow+1;
                                break;
                           default:
                                iCount+=(iHigh+1)*iFactor;
                                break;
                           }
             iFactor*=10;
    }
    return iCount;
    }

int main(){
    int N,sum=0;
    cin>>N;
    clock_t start,end;
    
    start=clock();
    /*
    for(int i=1;i<=N;++i){
            sum+=CountOne1(i);
            }
    cout<<sum<<endl;
    */
    cout<<CountOne(N)<<endl;
    end=clock();
    cout<<(double)(end-start)/CLOCKS_PER_SEC<<endl;
    system("pause");
     return 0;
    }
原文地址:https://www.cnblogs.com/relaxgirl/p/2989120.html