面试题16:打印从1到最大的n位数
1 题目
输入数字n,按顺序打印从1到最大的n位十进制数。比如输入3,则打印出1,2,3一直到最大的3位数999.
2 思路
1.由于没有确定输入n的范围,当输入n很大的时候,会存在需要输出的数的类型溢出问题。
2.在字符串上模拟加法的解放。
3.只有对“9999”加1的时候,才会在第一位上,产生进位。其他情况不会在第一个字符上产生进位。
4.打印时,需考虑到数字前面的补的0不应该打印出来,需要做个简单的判断,检测到第一个不为0后,才开始打印输出
3 代码示例
void PrintToMaxNDigits(int n)
{
//输入是否合法
if(n<0)
return;
// 定义字符串,用0补齐
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型上,字符和整型1-9对应关系见下图
int nSum = number[i] - '0' + nTakeOver;
// 个位数加+1
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;
}
// 考虑字符串前面的0
void PrintNumber(char* number)
{
bool isBeginning0 = true;
// 求其长度
int nLength = strlen(number);
for (int i = 0; i < nLength; ++i)
{
//遍历循环,知道第一个部位0,才可以输出
if (isBeginning0 && number[i] != '0')
isBeginning0 = false;
if (!isBeginning0)
{
printf("%c", number[i]);
}
}
printf("\t");
}
左侧列为十进制,最右侧列为对应字符