/* 题目: 打印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; //字符串最后一位是 ‘ ’,这里做了减1操作。 //printf("length %d ", 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 << ' '; } void formOneToNum(int num) { if (num <= 0) { cout << "重新输入" << endl; return ; } //字符串 结尾要加入 ,所以长度加1 char *number = new char[num + 1]; memset(number, '0', num); number[num] = ' '; while (!isOverFlow(number)) { printNumber(number); } delete[]number; } int main() { cout << "请输入数字长度. "; int number = 0; cin >> number; formOneToNum(number); return 0; }