欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【剑指】43.从1到n整数中1出现的次数

程序员文章站 2024-03-17 21:52:22
...

题目描述

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

算法分析

  • 参考博文:计算1至n中数字X出现的次数
  • 当计算右数第 i 位包含的 X 的个数时:
    1. 取第 i 位左边(高位)的数字,乘以 10^(i−1),得到基础值 a。
    2. 取第 i 位数字,计算修正值:
    (1) 如果大于 X,则结果为 a+10^(i−1)。
    (2) 如果小于 X,则结果为 a。
    (3) 如果等 X,则取第 i 位右边(低位)数字,设为 b,最后结果为 a+b+1。

提交代码:

class Solution {
public:
	int NumberOf1Between1AndN_Solution(int n)
	{
		/* 高、低、当前位 */
		int high, low, curr, temp;
		int result = 0, i = 1;
		/* judgeVal的出现次数,可以改为1-9中任意的数 */
		int judgeVal = 1;
		
		do {
			high = n / (int)pow(10, i);
			temp = n % (int)pow(10, i);
			curr = temp / (int)pow(10, i - 1);
			low = n % (int)pow(10, i - 1);

			result += high * (int)pow(10, i - 1);

			if (curr > judgeVal)
				result += (int)pow(10, i - 1);
			else if (curr == judgeVal)
				result = result + low + 1;

			++i;
		} while (high != 0);

		return result;
	}
};

测试代码:

// ====================测试代码====================
void Test(const char* testName, int n, int expected)
{
	if (testName != nullptr)
		printf("%s begins: \n", testName);

	Solution s;
	if (s.NumberOf1Between1AndN_Solution(n) == expected)
		printf("Solution1 passed.\n");
	else
		printf("Solution1 failed.\n");

	printf("\n");
}

void Test()
{
	Test("Test1", 1, 1);
	Test("Test2", 5, 1);
	Test("Test3", 10, 2);
	Test("Test4", 55, 16);
	Test("Test5", 99, 20);
	Test("Test6", 10000, 4001);
	Test("Test7", 21345, 18821);
	Test("Test8", 0, 0);
}

int main(int argc, char* argv[])
{
	Test();

	return 0;
}