程序员面试题精选100题:求从1到n的正数中1出现的次数

// 程序员面试题精选100题(25):求从1到n的正数中1出现的次数
// 如 f(253) = (2!=0) * 100 + 2 * f(99) + (5!=0) * 10 + 5 * f(9) + (3!=0) * 1 + 3 * 0;
// (2!=0)*100:100-199中百位出现的1的次数,2 * f(99):1-99,100-199中十位和个位出现的1的个数(1-199统计完)
// (5!=0)*10:210-219中十位出现的1的次数,5 * f(9):200-249中个位出现的1的个数(200-249统计完)
// (3!=0) * 1:251中个位出现1的次数,3 * 0:250-253中上一位出现1的个数(不存在),(250-253统计完)
// f(0) = 0,f(9) = (9!=0) * 1 + 3 * 0 = 1,f(99) = (9!=0) * 10 + 9 * f(9) + (9!=0) * 1 + 9 * 0 = 20
int NumberOfOneBetween1AndN(unsigned int n)
{
	// PowerBase10:表示10的幂数,依次为1,10,100...
	// f_PowerBase10Minus1:依次为f(0),f(9),f(99)...
	int PowerBase10 = 1, f_PowerBase10Minus1 = 0;
	int firstDigit;
	int NumberOfOne = 0;
	// 依次从低位到高位统计,如上例,依次累加250-253,200-249,1-199中1的个数
	while (n != 0)
	{
		firstDigit = n % 10;
		n = n / 10;
		NumberOfOne += (firstDigit != 0) * PowerBase10 + firstDigit * f_PowerBase10Minus1;	// 将当前位对应的1的个数累加到NumberOfOne
		f_PowerBase10Minus1 = PowerBase10 + 10 * f_PowerBase10Minus1;	//递推求出f_PowerBase10Minus1
		PowerBase10 *= 10;
	}
	return NumberOfOne;
}
        欢迎转载,转载请注明出处 http://blog.csdn.net/hugang012070/article/details/8916203

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值