题目
输入数字n,顺序打印从1到最大的n位十进制数,如输入3,打印出1,2,3一直到最大的三位数999
思路
n位十进制有可能大到无法保存在算术类型中,所以要一个容器来存储数字。
-
在字符串上存储数字并递增数字。
见increment函数 -
打印字符串中的数字。
见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);
}
}