《编程之美》- 2.4 - 1的个数

题目

2.4 1的数目
给定一个十进制正整数N,写下从1开始,到N所有整数,然后数一下其中出现的所有“1”的个数。
例如:N = 2 则在1,2中只出现了1个“1”
N = 12 则在1~12中出现了5个“1”
实现一个函数:返回1到N之间出现的“1”的个数,比如f(12) = 5;
问:满足条件f(N) = N 的最大的N是多少?

分析

解析见:

《编程之美》P132

《程序员代码面试指南》P429

代码

/*
2.4 1的数目

给定一个十进制正整数N,写下从1开始,到N所有整数,然后数一下其中出现的所有“1”的个数。

例如:N = 2 则在1,2中只出现了1个“1”
N = 12 则在1~12中出现了5个“1”

实现一个函数:返回1到N之间出现的“1”的个数,比如f(12) = 5;
问:满足条件f(N) = N 的最大的N是多少?
*/

#include <iostream>
#include <cstdlib>

using namespace std;

/*方法一:复杂度O(nlogn)*/
int count1(int n)
{
	int iCount = 0;
	while (n != 0)
	{
		iCount += (n % 10 == 1) ? 1 : 0;
		n /= 10;
	}//while

	return iCount;
}

int sum1s(int n)
{
	int iCount = 0;
	for (int i = 1; i <= n; ++i)
	{
		iCount += count1(i);
	}//for

	return iCount;
}

/*方法二:复杂度O(N的位数) 《编程之美》p134*/
int sum1s_2(int n)
{
	int iCount = 0;
	int iFactor = 1;

	int iLowerNum = 0, iCurrNum = 0, iHigherNum = 0;

	while (n / iFactor != 0)
	{
		iLowerNum = n - (n / iFactor) * iFactor;
		iCurrNum = (n / iFactor) % 10;
		iHigherNum = n / (iFactor * 10);

		switch (iCurrNum)
		{
		case 0:
			iCount += iHigherNum * iFactor;
			break;
		case 1:
			iCount += iHigherNum * iFactor + iLowerNum + 1;
			break;
		default:
			iCount += (iHigherNum + 1) * iFactor;
			break;
		}//switch

		iFactor *= 10;
	}//while
	return iCount;
}

/*方法三:复杂度O(logN*logN) 《程序员代码面试指南》 P429*/
int lenOfN(int n)
{
	int len = 0;
	while (n != 0)
	{
		++len;
		n /= 10;
	}//while
	return len;
}

int powerBaseOf10(int base)
{
	return pow(10, base);
}

int sum1s_3(int n)
{
	if (n < 1)
	{
		return 0;
	}//if

	int len = lenOfN(n);
	if (1 == len)
	{
		return 1;
	}//if

	int tmp1 = powerBaseOf10(len - 1);
	int first = n / tmp1;
	int firstOneNum = first == 1 ? n % tmp1 + 1 : tmp1;
	int otherOneNum = first * (len - 1) * (tmp1 / 10);

	return firstOneNum + otherOneNum + sum1s_3(n % tmp1);
}

int main()
{
	cout << sum1s(12) << endl;
	cout << sum1s_2(12) << endl;
	cout << sum1s_3(12) << endl;

	system("pause");
	return 0;
}
    原文作者:逆風的薔薇
    原文地址: https://blog.csdn.net/fly_yr/article/details/51385210
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞