在從 1 到 n 的正數中 1 出現的次數

題目:

輸入一個整數 n,求從 1 到 n 這 n 個整數的十進制表示中 1 出現的次數。編程

例如輸入 12,從 1 到 12 這些整數中包含 1  的數字有 1, 10, 1 1 和 12, 1 一共出現了 5 次spa


代碼實現(GCC編譯經過):

#include "stdio.h"
#include "stdlib.h"

int count1(int n);
int count2(int n);

int main(void)
{
	int x;

	printf("輸入一個數:");
	scanf("%d",&x);
	printf("\n從0到%d一共遇到%d(%d)個1\n",x,count1(x),count2(x));
	
	return 0;
}

//解法一
int count1(int n)
{
	int count = 0;
	int i,t;
	
	//遍歷1到n
	for(i=1;i<=n;i++)
	{
		t=i;
		//依次處理當前遍歷到的數字的各個位
		while(t != 0)
		{
		        //若爲1則統計加一
			count += (t%10 == 1)?1:0;
			t/=10;
		}
	}
	
	return count;
}

//解法二:
int count2(int n)
{
	int count = 0;//統計變量
	int factor = 1;//分解因子
	int lower = 0;//當前處理位的全部低位
	int higher = 0;//當前處理位的全部高位
	int curr =0;//當前處理位
	
	while(n/factor != 0)
	{
		lower = n - n/factor*factor;//求得低位
		curr = (n/factor)%10;//求當前位
		higher = n/(factor*10);//求高位
		
		switch(curr)
		{
			case 0:
				count += higher * factor;
				break;
			case 1:
				count += higher * factor + lower + 1;
				break;
			default:
				count += (higher+1)*factor;
		}
		
		factor *= 10;
	}
	
	return count;
}


分析:

方法一就是從1開始遍歷到N,將其中的每個數中含有「1」的個數加起來,比較好想。code

方法二比較有意思,核心思路是這樣的:統計每一位上可能出現1的次數。it

好比123:io

個位出現1的數字:1,11,13,21,31,...,91,101,111,121編譯

十位出現1的數字:10~19,110~119class

百位出現1的數字:100~123變量

總結其中每位上1出現的規律便可獲得方法二。其時間複雜度爲O(Len),Len爲數字長度遍歷


參考資料:            《編程之美》        電子工業出版社方法

相關文章
相關標籤/搜索