在从 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为数字长度遍历


参考资料:            《编程之美》        电子工业出版社方法

相关文章
相关标签/搜索