打印1到最大的n位数(大数问题)

来源:互联网 发布:java导出excel poi 编辑:程序博客网 时间:2024/05/15 02:47
/******************************************************题目:输入数字n,按顺序打印出从1最大的n位十进制。比如输入3,则打印出1,2,3,4一直到3位数最大值999。******************************************************//*分析:这个题目需要考虑大数问题。也就是如果我们输入的n值比较大,比如n=100,那么将会超出所有整形所能表示的范围(不论是int还是long)。解决办法:在字符串解决大数问题*/#include<stdio.h>#include<string.h>void printNumber(char* number);/*//实现方法1bool increment(char* number);void print1ToMaxOfNDigital(int n){if(n<=0)return;char* number = new char[n+1];memset(number,'0',n);number[n] = '\0'; while(!increment(number))//increment函数用来使字符串表示的数字自增{printNumber(number);//用来输出字符来代替数字}delete[] number;}//实现字符自增,模拟数字自增bool increment(char* number){bool isOverFlow = false;//如果超过范围,溢出int nTakeOver = 0;//超过10,进位int nLength = strlen(number);//字符串长度,也就是位数nfor(int i=nLength-1; i>=0; --i){int nSum = number[i]-'0'+nTakeOver;if(i == nLength-1)nSum++;if(nSum>=10)//如果某一位上的数大于10{if(i == 0)//如果在字符串的最低位,也就是数字上的最高位isOverFlow = true;//超出范围else{nTakeOver = 1;//进位nSum -= 10;number[i] = '0'+nSum;//将超过10的这一位减去10}}else{number[i] = '0' + nSum;//设置位上的数值break;}}return isOverFlow;}*///实现方法2,以上方法虽然能够实现基本功能,但编程思路落实不易//下面采用将问题转换为数字全排列的解法void print1ToMaxOfNDigitsRecursively(char* number, int length, int index);void print1ToMaxOfNDigital(int n){if(n<=0)return;char* number = new char[n+1];number[n] = '\0';for(int i=0; i<10; ++i){number[0] = '0'+i;//数字表示最高位print1ToMaxOfNDigitsRecursively(number,n,0);}delete[] number;}void print1ToMaxOfNDigitsRecursively(char* number, int length, int index){if(index == length-1){printNumber(number);return;}for(int i=0; i<10; i++){number[index + 1] = '0' + i;print1ToMaxOfNDigitsRecursively(number,length,index+1);}}//打印数字,防止高位为0是也打印出来void printNumber(char* number){bool isBeginning0 = true;int nLength = strlen(number);for(int i=0; i<nLength; ++i){if(isBeginning0 && number[i]!='0')//从字符串最低位开始寻找第一个不是‘0’的位置isBeginning0 = false;if(!isBeginning0)//如果不以‘0’开头,则打印printf("%c",number[i]);}printf("\t");}int main(){print1ToMaxOfNDigital(3);}
总结:
1.用字符串解决大数问题值得研究
2.需要注意的问题是字符串或者数组的最高位对于数字上的最低位。
3.如果面试题是关于n位的整数并且没有限定n的取值范围,或者是输入任意大小的整数,
那么这个题目很有可鞥需要考虑大数问题的字符串是一个简单、有效的表示大数的方法。
相关题目:
1)前面的代码中,我们都是用一个char型字符表示十进制数字的一位。
8个bit的char型字符最多能表示256个字符,而十进制数字只有0-9的10个数字。
因此用char型字符串来表示十进制的数字并没有充分利用内存,有一些浪费。
有没有更高效的方式来表示大数。
2)定义一个函数,在该函数中可以实现任意两个整数的加法。由于没有限定输入
两个数的大小范围,我们也要把它当做大数问题来处理。在前面的代码的第一个
思路中,实现了在字符串表示的数字上加1的功能,我们可以参考这个思路实现
两个数字相加功能,另外还有一个需要注意的问题:如果输入的数字中有负数,

我们应该怎么处理?


建议方案

void printf1ToMaxOfNDigits_1(int n){if(n<=0)return;char* number = new char[n+1];number[n] = '\0';for(int i=0; i<10; ++i){number[0] = '0' + i;printf1ToMaxOfNDigits_1(number, n, 0);}delete[] number;//不要忘记释放内存}void printf1ToMaxOfNDigits_1(int* number, int len, int index){if(index == len-1){printfNumer(number);return;}else{for(int i=0; i<10; ++i){number[index+1] = '0' + i;printf1ToMaxOfNDigits_1(number, len, index+1);}}}void printfNumer(char* number){bool isBegingWith0 = true;int len = strlen(number);for(int i=0; i<len; ++i){if(isBegingWith0 && number[i] != '0')isBegingWith0 = false;if(!isisBegingWith0){printf("%c", number[i]);}}printf("\t");}


==参考剑指offer

0 0
原创粉丝点击