个位ch个数 + 十位ch个数 * 10 + 百位ch个数 * 100;同时如果某一位刚好等于ch,还需要减去多算的一部分值。
#include <stdio.h>
//整数1到n,字符ch出现的次数;如1到12,1出现5次
int count1s (int n, char ch){
int i = ch - '0';
int count = 0;
int j = 1;
int m = n;
int t = 0;
int k = 1;
if (i == 0) i = 10;
//循环比较最后一位,/10 移位
while (m > 0){
int t = i;
int count1 = 0;
while (t <= m){
count1++;
t += 10;
}
count += count1 * j;
j *= 10;
m /= 10;
}
//减去多加的部分; 如110中计算1出现个数,在计算十位时多加9,需要减去。在计算百位是也多加了89,需要减去
m = n;
j = 0;
while (m){
if (m % 10 == ch - '0'){
j = t;
if (j != 0){
int a = 0;
k = 1;
for (a = 0; a < j; a++) k *= 10;
count = count - (k - (n % k) - 1);
}
}
m /= 10;
t++;
}
return count;
}
#if 1 //普通的逐个整数比较的测试程序
//某个整数中1出现的次数
int NumberOfCh(unsigned int n, char ch)
{
int number = 0;
while (n)
{
if(n % 10 == ch - '0')
number ++;
n = n / 10;
}
return number;
}
//求1到n中所有整数中1出现的总次数
int ceshi(unsigned int n, char ch)
{
int number = 0;
int i = 1;
for(i = 1; i <= n; ++ i)
number += NumberOfCh(i, ch);
return number;
}
#endif
int main (void){
#if 0
int i = 0;
char ch = '0';
for (i = 0; i < 65535; i++){
for (ch = '0'; ch <= '9'; ch++){
if (count1s (i, ch) != ceshi (i, ch)){
printf ("%d %c\n", i, ch);
return -1;
}
}
printf ("%d\n", i);
}
#else
printf ("%d\n", count1s(1365535, '5'));
printf ("%d\n", ceshi (1365535, '5'));
#endif
}