从1到n整数中1出现的次数

44 篇文章 0 订阅
43 篇文章 0 订阅

/*
输入一个整数n,求从1到n这个n个整数的十进制表示中1出现的次数。例如,输入12,
从1到12这些整数中包含1的数字有1,10,11,12。1一共出现了5次
*/

#include "iostream"
#include "algorithm"

using namespace std;

int count1Num(int num)
{
	int count = 0;
	while (num != 0)
	{
		if (num % 10 == 1)
			count++;
		num = num / 10;
	}
	return count;
}
//暴力求解
int Count1Appearance0(int n)
{
	if (n <= 0)
		return 0;
	int count = 1;
	int i = 10;
	while (i <= n)
	{
		count += count1Num(i);
		i++;
	}
	return count;
}

//第二种方法,找规律,一位一位看
int numberOf1(const char* strN)
{
	if (!strN || *strN < '0' || *strN >'9' || *strN == '\0')
		return 0;

	int first = *strN - '0'; //最高位

	unsigned int length = static_cast<unsigned int>(strlen(strN));

	if (length == 1 && first == 0)
		return 0;
	if (length == 1 && first > 0)
		return 1;

	//假设strN是“21345”,numFirstDigit是数字10000-19999的第一个位中的数目
	int numFirstDigit = 0;
	if (first > 1)
		numFirstDigit = pow(10, length - 1);
	else
		numFirstDigit = atoi(strN + 1) + 1;//atoi(strN+1)除开最高位剩下的位数1345

	//numOtherDigits是1345~21345除了第一位之外的数位中的数目
	int numOtherDigits = first * (length-1) * pow(10, length - 2);

	//numRecursive是1-1345中1的数目
	int numRecursive = numberOf1(strN + 1);

	return numFirstDigit + numOtherDigits + numRecursive;
}

int Count1Appearance1(int n)
{
	if (n <= 0)
		return 0;
	char strN[50];
	sprintf_s(strN, "%d", n);
	return numberOf1(strN);
}


#include "ctime"
void test()
{
	clock_t t0 = clock();
	cout << Count1Appearance0(999999) << endl;
	cout << clock() - t0 << "ms" << endl;
	cout << endl;
	t0 = clock();
	cout << Count1Appearance1(999999) << endl;
	cout << clock() - t0 << "ms" << endl;
	
}

int main()
{
	test();
	return 0;
}
运行结果:

600000
87ms

600000
1ms


算法0的复杂度:O(n*lg(n))。算法1:lg(n)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值