從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;


}


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