现在的位置: 首页 > 综合 > 正文

统计所有0到n之间所有含有数字1的数字和

2018年05月28日 ⁄ 综合 ⁄ 共 1119字 ⁄ 字号 评论关闭

实现函数int func(unsigned n),其中n为正整数,返回从1到n(包含1和n)之间出现的1的个数,如

func(13)=6,func(9)=1。(注意:不能将整数转化为字符串)

这是网上一位兄弟的分析:

分析:

这个问题可以分解为:对于一个有digit位的数,可以统计其每个位上出现1的次数,遍历每个位,累计的次数即为出现1的次数之和

对于数n,可以把它分成三段,高位段most,当前位cur,低位段least,每一段分别为一个整数。对于一个有digit位的数,假设当前位是左数第i位(从1开始),则设一个临时变量tmp为10的digit-i次方,即比least多一位的最小整数。

                     如数123456,为6位数,digit=6,设当前为左起第3位,则i=3,most=12,cur=3, least=456,tmp=1000。

                    如果当前位大于1,则从1到n间出现在当前位出现的1的个数是most*tmp+tmp;

                    如果等于1,则是 most*tmp+least+1;

                    如果小于1,则为most*tmp。

实现:

int func(unsigned n)
{
    int count = 0;
    int digit = (int)log10(n) + 1;
    int most, cur, least, tmp;
    int i; 

    for (i=0; i<digit; ++i)
    {
        tmp = (int)pow(10, digit-i-1);
        most = n / tmp / 10;
        cur = (n / tmp) % 10;
        least = n % tmp;
        count += most * tmp;
        if (cur > 1)
        {
            count += tmp;
        }
        else if (cur == 1)
        {
            count += least + 1;
        }
    }
    return count;
} 

 

如果可以将整数转化成字符串的话,就简单了,只是代价比较大

int fun(const unsigned int n)
{
     char str[50];
     int i, j;
     int num = 0;//存储n中的个数
     int len;//len为转换后的字符串的长度,也即原整数的位数
     for(i=1; i<=n; ++i)
     {
         ultoa(i, str, 10); //ultoa函数将unsigned int转化为char *型字符串
         len = strlen(str);
         for(j=0; j<len; ++j)
         {
              if('1' == str[j])
                   ++num;
         }
     }
     return num;
}

注:char *ultoa(unsigned long value, char *string, int radix); 

功能:转换一个radix进制的无符号长整型数为字符串

抱歉!评论已关闭.