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

  2013-09-11 16:02:52

转自:http://blog.csdn.net/hugang012070/article/details/8916203

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

 

  1. // 程序员面试题精选100题(25):求从1到n的正数中1出现的次数  
  2. // 如 f(253) = (2!=0) * 100 + 2 * f(99) + (5!=0) * 10 + 5 * f(9) + (3!=0) * 1 + 3 * 0;  
  3. // (2!=0)*100:100-199中百位出现的1的次数,2 * f(99):1-99,100-199中十位和个位出现的1的个数(1-199统计完)  
  4. // (5!=0)*10:210-219中十位出现的1的次数,5 * f(9):200-249中个位出现的1的个数(200-249统计完)  
  5. // (3!=0) * 1:251中个位出现1的次数,3 * 0:250-253中上一位出现1的个数(不存在),(250-253统计完)  
  6. // 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  
  7. int NumberOfOneBetween1AndN(unsigned int n)  
  8. {  
  9.     // PowerBase10:表示10的幂数,依次为1,10,100...  
  10.     // f_PowerBase10Minus1:依次为f(0),f(9),f(99)...  
  11.     int PowerBase10 = 1, f_PowerBase10Minus1 = 0;  
  12.     int firstDigit;  
  13.     int NumberOfOne = 0;  
  14.     // 依次从低位到高位统计,如上例,依次累加250-253,200-249,1-199中1的个数  
  15.     while (n != 0)  
  16.     {  
  17.         firstDigit = n % 10;  
  18.         n = n / 10;  
  19.         NumberOfOne += (firstDigit != 0) * PowerBase10 + firstDigit * f_PowerBase10Minus1;  // 将当前位对应的1的个数累加到NumberOfOne  
  20.         f_PowerBase10Minus1 = PowerBase10 + 10 * f_PowerBase10Minus1;   //递推求出f_PowerBase10Minus1  
  21.         PowerBase10 *= 10;  
  22.     }  
  23.     return NumberOfOne;  
  24. }  

       

posted @ 2013-09-11 16:03  永不止步,永无止境  阅读(282)  评论(0)    收藏  举报