- 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
- 首先是暴力做法:
int Count1In1ToN(int n)
{
int count = 0;
while(n >= 1){
count += CountNumber1(n);
n--;
}
return n;
}
int CountNumber1(int n)
{
int count = 0;
while(n > 0){
if(n % 10 == 1)
count++;
n /= 10;
}
return count;
}
编程之美上的方法:
//大体的思路是这样的:
//假设N=abcde,这里a,b,c,d,e分别是十进制数N的各个位数上的数字。如
//果要计算百位上出现1的次数,它会受到三个因素影响:百位数上的数字
//,百位以下的数字,百位以上的数字。
//a、如果百位上的数字为0,则百位出现1的次数由更高位决定。如12013,
// 则可以知道百位出现1的情况可能是100~199,1100~1199,2100~2199。
// 11100~11199,一共1200个。也就是由更高位数字(12)决定,并且等
// 于更高位数字(12)*当前位数(100);
//b、如果百位上数字为1,则百位上出现1的次数由更高位和低位共同决定。
// 例如对于12113,受高位的影响百位出现1的个数为等于更高位数字(12)
// *当前位数(100)=1200.但是它还受低位影响,等于低位数字(13)+1;
//c、如果百位上的数字大于1(即为2-9),则百位出现1的次数仅由更高位
// 决定,比如12213,等于更高位数字+1(12+1)*当前位数(100)=1300.
int Count1In1ToN(int n)
{
int factor = 1;
int lowerNum = 0;
int currNum = 0;
int higherNum = 0;
int count = 0;
while (n / factor != 0){
lowerNum = n - (n / factor) * factor;
currNum = (n / factor) % 10;
higherNum = n / (factor * 10);
switch (currNum){
case 0:
count += higherNum * factor;
break;
case 1:
count += higherNum * factor + lowerNum + 1;
break;
default:
count += (higherNum + 1) * factor;
break;
}
factor *= 10;
}
return count;
}