剑指offer面试题17——打印从1到最大的n位数

题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数999

 

思路:

        越是看着简单的问题,越是要注意一些边界条件或者特殊情况。比如这道题,题目没有说n的范围,那么int和long long都有可能会溢出,所以这道题就需要用字符串或者数组来表示最大的数。首先分为两个步骤来解决这个问题,第一步是在字符串表达式的数字上模拟加法:第二步是把字符串表达的数字打印出来。

注意:

        有两个需要注意的地方,第一个是判断什么时候停止在number上加一,这里我们发现只有在最大数的时候比如“99. ..99”时加上1,才会在第一个字符(下标为0)的基础上产生进位,而其他所有的情况都不会产生进位。第二个是在输出字符串的时候,前面的0,比如099前面的0是不输出的,要预先进行判断。

代码:

void PrintToMaxOfNDigits(int n)
{
	if (n <= 0)
		return;
	char* number = new char[n + 1];
	memset(number, '0', n);
	number[n] = '\0';
	while (!Increment(number))
	{
		PrintNumber(number);
	}
	delete[]number;
}

bool Increment(char* number)
{
	bool isOverflow = false;
	int nTakeOver = 0;
	int nLength = strlen(number);
	for (int i = nLength - 1; i >= 0; i--)
	{
		int nSum = number[i] - '0' + nTakeOver;
		if (i == nLength - 1)
			nSum++;
		if (nSum >= 10)
		{
			if (i = 0)
				isOverflow = true;
			else {
				nSum -= 10;
				nTakeOver = 1;
				number[i] = '0' + nSum;
			}

		}
		else {
			number[i] = '0' + nSum;
			break;
		}
	}
	return isOverflow;
}

void PrintNumber(char* number)
{
	bool isBeginning0 = true;
	int nLength = strlen(number);
	for (int i = 0; i < nLength; ++i)
	{
		if (isBeginning0 && number[i] != '0')
			isBeginning0 = false;
		if (!isBeginning0)
		{
			printf("%c", number[i]);
		}
	}
	printf("\t");
}

复习:

       这道题稍微有点绕,就是Increment函数用字符串模拟数字的加法。还有就是while循环里面,用函数作为判断的表达式,这里num是不断在变化的,所以while循环会一直执行下去,直到到达最大的数字。

思路2:

      这里是把所需要输出的数字看做全排列,首先将number[0]设置从‘0’到‘9’,然后递归地设置后面的每一位字符(都是从‘0’到‘9’),当设置最后一位结束之后就可以输出这个字符串了。

代码:



void PrintNumber(char* number)
{
	bool isBeginning0 = true;
	int nLength = strlen(number);
	for (int i = 0; i < nLength; ++i)
	{
		if (isBeginning0 && number[i] != '0')
			isBeginning0 = false;
		if (!isBeginning0)
		{
			printf("%c", number[i]);
		}
	}
	printf("\t");
}

void Print1ToMaxOfNDigits(int n)
{
	if (n <= 0)
		return;
	char* number = new char[n + 1];
	number[n] = '\0';

	for (int i = 0; i < 10; i++)
	{
		number[0] = '0' + i;
		Print1ToMaxOfNDigitsRecursively(number, n, 0);

	}
	delete[] number;
}

void Print1ToMaxOfNDigitsRecursively(char* number, int length, int index)
{
	if (index = length - 1)
	{
		PrintNumber(number);
		return;
	}

	for (int i = 0; i < 10; i++)
	{
		number[index + i] = '0' + i;
		Print1ToMaxOfNDigitsRecursively(number, length, index + 1);
	}
		
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值