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

题目

输入数字n,顺序打印从1到最大的n位十进制数,如输入3,打印出1,2,3一直到最大的三位数999

思路

n位十进制有可能大到无法保存在算术类型中,所以要一个容器来存储数字。

  1. 在字符串上存储数字并递增数字。
    见increment函数

  2. 打印字符串中的数字。
    见printnumber函数。

非递归版本

在这里插入图片描述

bool increment(string& number)
{
	int nlength = number.size();
	int ntakeover = 0; //保存进位数字
	bool canincrement = true;

	for (int i = nlength - 1; i >= 0; i--)
	{

		int nsum = number[i] - '0' + ntakeover;	//array[i] - '0'  ASCLL码值相减,将字符转为int型
		if (i == nlength - 1)	//只有在最后一位才进行+1操作
			nsum++;

		if (nsum >= 10) //进位
		{
			if (i == 0)	//已经移动到数组第一位了,再进位溢出
				canincrement = false;
			else
			{
				nsum -= 10;
				//ntakeover++;  //错误1 ntakeover定义在循环外 值不会重置,会一直递涨,实际上进位表示只能为1
				ntakeover = 1;
				//number[i] = number[i] - '0' + nsum; //错误2 这里应该是把int转为字符型存入number
				number[i] = '0' + nsum;
			}
		}
		else
		{
			//number[i] = number[i] - '0' + nsum;	//错误3 同2
			number[i] = '0' + nsum;
			break;
		}
	}
	return canincrement;
}

void printnumber(string &number)
{
	bool isbeginning0 = true;
	int nlength = number.size();

	for (int i = 0; i < nlength; ++i)
	{
		if (isbeginning0 && number[i] != '0')
			isbeginning0 = false;
		if (!isbeginning0)
			cout << number[i];
	}

	cout << "\t";
}

void printToMaxOfNDigits(int n)
{
	if (n <= 0)
		return;

	string number(n, '0');

	while (increment(number)) //数组没有溢出,还能增加
	{
		printnumber(number);
	}
}

需要用到的知识点

用ascii码将char和int进行转换:

	char c = '0';
	cout << c - '0' + 6 << endl;  //int 6
	cout << c + 6;	//char 54

犯的错误

见代码注释,主要是解题逻辑,对变量含义理解不够。

递归版本

printnumber函数和非递归版本相同。

void printToMaxOfNDigitsRecursively(string& number, int length, int index)
{
	if (index == length - 1) //string下标从0开始,已经设置到最后一位了
	{
		printnumber(number);
		return;
	}

	for (int i = 0; i < 10; ++i)
	{
		number[index + 1] = i + '0'; //递归结束会打印number,所以要提前设置
		printToMaxOfNDigitsRecursively(number, length, index + 1);
	}
}

void printToMaxOfNDigits(int n)
{
	if (n <= 0)
		return;

	string number(n, '0');

	for (int i = 0; i < 10; ++i)
	{
		number[0] = i + '0';
		printToMaxOfNDigitsRecursively(number, n, 0);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值