从1到n的正数中1出现的次数

30.在从1到n的正数中1出现的次数(数组)
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。
//coder:Lee,20120318


#include<iostream>
#include<cassert>
#include <bitset> 
#include<CMATH>
using namespace std;
int GetDigit(unsigned int n)
{
int i=0;
while(n)
{
i++;
n/=10;
}
return i;
}
int NumOfOnes(unsigned int n)
{
int i=0;
while(n)
{
if(n%10==1)
i++;
n/=10;
}
return i;
}
int Count_1(unsigned int n)
{
assert(n>=1);
int num=0;
for (unsigned int i=1;i<=n;i++)
{
num+=NumOfOnes(i);
}
return num;
}
//////////////////////////////
//count numbers of one in an integer from 1 to n
//Input: n - an integer
//Output: numbers of one
int Count_2(unsigned int n)
{
assert(n>=1);
//get digits of an integer
int digit=GetDigit(n);
//if digit equel one , result must be 1
if(digit==1)
return 1;
int num=0;
//get the highest number
int highdigit=n;
int i=digit-1;
while(i--)
highdigit/=10;
//for example: n =4132 , num = 4*100 + Count_2(132)
num=highdigit*(digit-1)*pow(10,digit-2)+Count_2(n-highdigit*pow(10,digit-1));
//if 4>1 ,then num +=100,because when the highest number equel 1,we have one hundred 1s
if(highdigit>1)
num+=pow(10,digit-1);
//or we have 132 * 1
else
num+=n-highdigit*pow(10,digit-1)+1;
return num;

}




int Sum1s(int n)//expansion promble : Binary number
{
int iCount=0;
int iFactor=1;
int iLowerNum=0;
int iCurrNum=0;
int iHigherNum=0;
while (n/iFactor!=0)
{
iLowerNum=n-(n/iFactor)*iFactor;
iCurrNum=(n/iFactor)%2;
iHigherNum=n/(iFactor*2);
switch(iCurrNum)
{
case 0:
iCount+=iHigherNum*iFactor;
break;
case 1:
iCount+=iHigherNum*iFactor+iLowerNum+1;
break;
}
iFactor*=2;


}
return iCount;
}
int main()
{


cout<<Count_1(4132)<<endl;
int n=25;
cout<<"f("<<bitset<sizeof(int)*8>(n)<<")="<<bitset<sizeof(int)*8>(Sum1s(n))<<endl;
return 0;


}


非递归算法见《编程之美》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章