【剑指offer】——整数中1出现的次数(从1到n整数中1出现的次数)

题目描述

求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。

解答:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//将整型数转化为字符数组
char* NumberChangeChar(int n)
{
	if(n<0)
		return 0;
	char* str=(char*)malloc(sizeof(str)*100);
	sprintf(str,"%d",n);
	
	return str;
}
//函数功能10的n次方
int PowerBase10(unsigned int n)
{
	int result=1;

	unsigned int i=0;
	for(i;i<n;++i)
	{
		result*=10;
	}
	return result;
}

int NumberO1(char* str)
{
	//非法输入
	if(!str||*str<'0'||*str>'9'||*str=='\0')
		return 0;
	
	int begin=*str-'0';//第一位数的值
	unsigned int length=strlen(str);
	//第一位为0
	if(length==1&&begin==0)
		return 0;
	//只有一位
	if(length==1&&begin>0)
		return 1;
	//最高位为1的情况下
	int numFirstDig=0;
	//若最高位大于1
	if(begin>1)
		numFirstDig=PowerBase10(length-1);
	//若最高位小于1
	else if(begin==1)
		numFirstDig=atoi(str+1)+1;
	//其余位为1的情况下
	//例如21345,分两段(01346~11345)和(11346~21345)
	//一共5位,第一位为2,除去第一位还剩四位,固定一位,其余三位在0~9中任意选择,即10^3,四次排列组合——2*4*10^3
	int numOtherDig=begin*PowerBase10(length-2)*(length-1);
	//递归
	int numRecursive=NumberO1(str+1);
	
	return numFirstDig+numOtherDig+numRecursive;
}

int main()
{
	
	printf("%d\n",NumberO1(NumberChangeChar(21345)));
	return 0;
}

发布了160 篇原创文章 · 获赞 316 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/ShawnWang1994/article/details/99948855