面试算法(十一)打印1到最大的n位数

来源:互联网 发布:数据库统计选课门数 编辑:程序博客网 时间:2024/06/08 01:21

1、题目:输入数字n,按顺序打印出从1最大的n位十进制数。

比如输入3,则打印出1、2、3一直到最大的3位数即999。

解法:我们可以先求出最大的n位数,然后用一个循环从1开始逐个打印。但是我们注意到面试官没有规定n的范围。当输入的n很大时,会不会溢出?即大数问题。

解决办法:可以用字符串或数组表示大数。最直观的方法就是字符串里每个字符都是‘0’到‘9’之间的某一个字符,用来表示数字中的一位。因为数字最大是n位的,因此我们需要一个长度为n+1的字符串(结束符'\0')。当实际数字不够n位的时候,在字符串的前半部分补0。

首先把字符串中的每一个数字都初始化为‘0’,然后每一次为字符串表示的数字加1,再打印出来。

void PrintToMaxOfNDigits(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;}
bool Increment(char* number) { bool isOverflow = flase; int nTakeOver = 0; int nLength = strlen(number); for(int i=nLength-1; i>=0; i--) { int nSum = number[i] - '0' +nTakeOver; 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; }
void PrintNumber(char* number) { bool isBeginning0 = true; int nLength = strlen(number); for(int i=0; i<nLength; ++i) { if(isBeginning0 && number[i] != '0') isBeginning0 = false; if(! isBeginning0) { printf("%c", number[i]); } } printf("\t"); }


2、如果我们在数字前面补0的话,就会发现n位所有十进制数其实就是n个从0到9的全排列。即把数字的每一位都从0到9排列一遍,就得到了所有的十进制数。打印时数字排在前面的0不打印出来。全排列用递归很容易实现,数字的每一位都可能是0~9中的一个数,然后设置下一位。递归结束的条件就是我们已经设置了数字的最后一位。

void Print1ToMaxOfNDigits(int n) { if(n<=0) return; char *number = new char[n+1]; number[n] = '\0'; for(int i=0; i<10; ++i) { number[0] = i+'0'; Print1ToOfNDigitsRecursively(number, n, 0); } delete[] number; } void Print1ToOfNDigitsRecursively(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'; Print1ToOfNDigitsRecursively(number, length, index+1); } }






0 0
原创粉丝点击