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

25.整数中1出现的次数(从1到n整数中1出现的次数)

题目内容:

剑指offer-整数中1出现的次数(从1到n整数中1出现的次数)_第1张图片

代码及思路:

1.当输入数字不是很大的时候可以使用这种最简单的方法,但是当输入n非常大时,需要大量的计算,该种方法运算效率很低

#include
#include
using namespace std;
class solution
{
	public:
		int NumberOf1Between1AndN_Solution(int n)
		{
			if (n <= 0)
				return 0;
			int num = 0;
			//当数字不大的时候可以用该种方法
			while (n)
			{
				if (n % 10 == 1)
					num++;
				n /= 10;
			}
			return num;
		}
};
void main()
{
	solution* object = new solution;
	int num;
	cin >> num;
	int res;
	res = object->NumberOf1Between1AndN_Solution(num);
	cout << res << endl;
	
}

2.针对更大的输入的有效做法,思路就是将数字范围进行拆分多段进行分别求解

#include
#include
#include
using namespace std;
class solution
{
	public:
		int NumberOf1Between1AndN_Solution(int n)
		{
			if (n <= 0)
				return 0;
			char str[50];
			sprintf(str, "%d", n); //将数字n转换为字符串str
			return numberof1(str);
		}
		int numberof1(const char* str)
		{
			if (!str || *str<'0' || *str>'9' || *str == '\0')
				return 0;
			int first = *str - '0';//得到第一个数字
			unsigned int length =static_cast(strlen(str)); //计算字符串 str 的长度,直到空结束字符,但不包括空结束字符
			//位数为1时的两种情况
			if (length == 1 && first == 0)
				return 0;
			if (length == 1 && first > 0)
				return 1;
			//以str="21345"为例
			//numFirstDigit是10000-19999中第一位中的数目
			int numFirstDigit = 0;
			if (first > 1)
			{
				numFirstDigit = PowerBase10(length - 1); //万位出现1的次数为10000次
			}
			else if (first == 1) //如果万位是1如12345,则1出现在10000-12345范围内,万位出现1的个数为2345+1次
				numFirstDigit = atoi(str + 1) + 1;  //去掉最高位数字之后剩下的数字加1
			//numOtherDigits是1346-21345除了第一位之外的数位中的个数
			int numOtherDigits = first*(length - 1)*PowerBase10(length - 2);   //1346-21345可以划分为1346-11345,11346-21345:每一段从剩下4位当中随意选择一位为1,其余的三位从0-9中任意选择,因此一共出现次数为2x4x10^3=8000
			//numRecursive是1-1345中的个数
			int numRecursive = numberof1(str + 1);
			return numFirstDigit + numOtherDigits + numRecursive;
		}
		int PowerBase10(unsigned int n)
		{
			int res = 1;
			for (int i = 0; i < n; i++)
			{
				res *= 10;
			}
			return res;
		}
};

void main()
{
	solution* object = new solution;
	int num;
	cin >> num;
	int res;
	res = object->NumberOf1Between1AndN_Solution(num);
	cout << res << endl;
	
}

 

你可能感兴趣的:(剑指offer部分题)