统计1到n出现的1的个数(不能用字符串)

转http://blog.chinaunix.net/uid-8615291-id-2456793.html


题目:
 
实现函数int func(unsigned n),其中n为正整数,返回从1到n(包含1和n)之间出现的1的个数,如func(13)=6,func(9)=1。(注意: 不能将整数转化为字符串,剑指offer中的方法不能用
 
分析:
 
对于数n,可以把它分成三段,高位段most,当前位cur,低位段least,每一段分别为一个整数。对于一个有digit位的数,假设当前位是左数第i位,则设一个临时变量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;如果小于,则为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 = (/ tmp) % 10;
        least = n % tmp;

        count += most * tmp;
        if (cur > 1)
        {
            count += tmp;
        }
        else if (cur == 1)
        {
            count += least + 1;
        }
    }

    return count;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值