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

题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。

例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。

当最高位为1时:

如:1234 ,1的个数记为f(n)

分为两段,1~999,1000~1234 

第一段:1~999 的个数 1*3*(10^2); 其中1为最高位,3为(长度-1),2为(长度-2)

第二段:1000~1234 的个数:f(234)+(234+1)

当最高位数不为1时:

如2254:分为两段:1~1999,2000~2254

第一段:2*3*(10^2)+10^3 

第二段:f(254)

#include <stdio.h>
#include <stdlib.h>
//查找在1到N中 有多少个1
//比如 1,2,3...11,12 共有5个1
int Num1of1_nByStr(char *nstr,unsigned int);
int PowerBase10(unsigned int n);
int Num1of1_n(unsigned int n)
{
	char nstr[50];
	sprintf(nstr,"%u",n);
	//printf("%s\n",nstr);
	return Num1of1_nByStr(nstr,strlen(nstr));
}
int Num1of1_nByStr(char *nstr,unsigned int length)
{
	if(!nstr|| length==0 || *nstr < '0' || *nstr > '9' || *nstr == '\0' )
			return 0;
	if(length ==1 )
	{
		if(*nstr==0)return 0;
		else return 1;
	}
	int firstDigit=*nstr-'0';
	if(firstDigit >1)
	{
		return PowerBase10(length-1) + firstDigit*(length-1)*PowerBase10(length-2)+Num1of1_nByStr(nstr+1,length-1);
	}
	else
	{
		return firstDigit*(length-1)*PowerBase10(length-2)+atoi(nstr+1)+1 + Num1of1_nByStr(nstr+1,length-1);
	}

}
//10的n次方
int PowerBase10(unsigned int n)
{
	int result = 1;
	unsigned int i;
	for(i = 0; i < n; ++ i)
		result *= 10;

	return result;
}
int main(void) {
	printf("%d",Num1of1_n(1755322));
	return EXIT_SUCCESS;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值