从1到N整数中1出现的次数

来源:互联网 发布:ubuntu login password 编辑:程序博客网 时间:2024/05/16 06:28
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11,12,1一共出现了5次。

一、暴力求解,不被推荐

class Solution{public:    int NumberOf1Between1AndN( unsigned int n )    {        int number = 0;        for ( int i = 0; i <= n; i++ )        {            number += NumberOf1( i );        }        return number;    }    int NumberOf1( unsigned int n )    {        int number = 0;        while ( n )        {            if ( n % 10 == 1 )                number++;            n = n / 10;        }        return number;    }};

二、从数字规律着手解决

class Solution{public:    int NumberOf1Between1AndN( int n )    {        if ( n <= 0 )            return 0;        char strN[50];        sprintf( strN, "%d", n );        return NumberOf1( strN );    }    int NumberOf1( const char *strN )    {        if ( !strN || *strN < '0' || *strN > '9' || *strN == '\0' )            return 0;        int first = *strN - '0';        unsigned int length = static_cast<unsigned int>( strlen( strN ) );        if ( length == 1 && first == 0 )            return 0;        if ( length == 1 && first > 0 )            return 1;        int numFirstDigit = 0;        if ( first > 1 )            numFirstDigit = PowerBase10( length-1 );        else if ( first == 1 )            numFirstDigit = atoi( strN+1 ) + 1;        int numOtherDigits = first * ( length-1 ) * PowerBase10( length-2 ); //有些疑惑        int numRecursive = NumberOf1( strN+1 );        return numFirstDigit+numOtherDigits+numRecursive;    }    int PowerBase10( unsigned int n )    {        int result = 1;        for ( unsigned int i = 0; i < n; ++i )            result *= 10;        return result;    }};