1.【问题描述】
输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。
2.【问题分析】
考虑:
1.当输入的n很大时,求最大的n位数无论用整型(int)或者长整型(long long)都会溢出。即该问题会变成一个大数问题。
可以用字符串或者数组模拟数字的加法,以此来表示大数。
2.模拟数字的加法时,考虑到代码的逻辑复杂性,可以借助递归来实现。该问题递归的规模可以看做一个n层的10叉数,也就是说,当n=x时,总共有10x个数。
3.【代码示例】
/*
题目:打印从1到最大的n位数
作者:郭鹏科:
时间:2019-09-03 7:21
文件名:interviewQuestion_17.cpp
*/
#include<bits/stdc++.h>
using namespace std;
/*
描述:输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。
时间:2019-09-03 8:43
函数名:
*/
bool increment(char* number)
{
bool isoverflow = false;
int takeover = 0;
int length = strlen(number);
for (int i = length - 1; i >= 0; --i)
{
int sum = number[i] - '0' + takeover; //先将字符转换为整数
if (i == length - 1) //每次加1操作
{
++sum;
}
if (sum >= 10)
{
if (i == 0)
{
isoverflow = true;
}
else
{
sum -= 10;
takeover = 1;
number[i] = '0' + sum;
}
}
else
{
number[i] = '0' + sum;
break;
}
}
return isoverflow;
}
void printNumber(char* number)
{
bool isbegin0 = true;
int length = strlen(number);
for (int i = 0; i < length; ++i)
{
if (isbegin0 && number[i] != '0')
{
isbegin0 = false;;
}
if (!isbegin0)
{
cout <<number[i] << "";
}
}
printf("\t");
}
void printToMaxOfNDigits1(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;
}
void printToMaxOfNDigitsRecursion(char* number, int length, int index)
{
if (index == length - 1)
{
printNumber(number);
return;
}
for (int i = 0; i < 10; ++i)
{
number[index + 1] = i + '0';
printToMaxOfNDigitsRecursion(number, length, index + 1);
}
}
void printToMaxOfNDigits2(int n)
{
if (n <= 0)
{
return;
}
char *number = new char[n + 1];
memset(number, '0', n);
number[n] = '\0';
for (int i = 0; i < 10; ++i)
{
number[0] = i + '0';
printToMaxOfNDigitsRecursion(number, n, 0);
}
delete[] number;
}
int main()
{
printToMaxOfNDigits2(4);
return 0;
}