/*
题目: 打印1到最大的N为数字。
比如:输入3,打印1到999.
解题思路,这是一个大数的问题。做大数的自加运算。但是要注意2点。
(1):判断是否越界,换句话说,就是达到最大值时的判别。可以选择strcmp,但是复杂度时O(n),
因为只有在进位的时候才会有越界的可能,并且只有99...999 向上进位时才会越界,所以判断 i是否为0。
(2):输出时,注意,把0去掉,0098,变成98.
*/
#include <stdio.h>
#include <iostream>
using namespace std;
//判断是否达到最大值,退出输出。只有当最高一位实现进位的时候,就是溢出了。
bool isOverFlow(char *number)
{
int length = strlen(number) - 1; //字符串最后一位是 ‘\0’,这里做了减1操作。
//printf("length %d\n", length);
int nTakeOver = 0; //进位标志,判断是否进位
bool isoverflow = false; //是不是达到最大值
for (int i = length; i >= 0; i--) //字符串从左向右,但是数字是从右向左。
{
//第一次循环是获取最低位的数字,以后的循环用来做进位用。
int nSum = number[i] - '0' + nTakeOver;
if (i == length) //只有最低位做加1,也就是第一次。
nSum++;
if (nSum >= 10) //如果大于等于 10,就要进位
{
if (i == 0) //由于这里从1开始到length-1,就已经是数字的长度了,如果为0,就是越界了。
{
isoverflow = true;
break;
}
nTakeOver = 1;
nSum -= 10;
number[i] = '0' + nSum;
}
else //不大于10,复值,并就退出循环
{
number[i] = '0' + nSum;
break;
}
}
return isoverflow; //返回是否越界符号。
}
//打印数字,注意字符串前端为0的不打印,比如098,只打印98。
void printNumber(char *number)
{
int length = strlen(number);
bool boolSingalPrint = false;
for (int i = 0; i < length; i++)
{
if (boolSingalPrint == false && number[i] != '0')
boolSingalPrint = true;
if (boolSingalPrint == true)
cout << number[i];
}
cout << '\t';
}
void formOneToNum(int num)
{
if (num <= 0)
{
cout << "重新输入" << endl;
return ;
}
//字符串 结尾要加入 \0,所以长度加1
char *number = new char[num + 1];
memset(number, '0', num);
number[num] = '\0';
while (!isOverFlow(number))
{
printNumber(number);
}
delete[]number;
}
int main()
{
cout << "请输入数字长度.\n";
int number = 0;
cin >> number;
formOneToNum(number);
return 0;
}