打印1到最大的n位数

来源:互联网 发布:seo的工资 编辑:程序博客网 时间:2024/05/29 07:28

题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的999。

这道题目看着很简单,最简单的思想就是先求出最大的n位数,然后用一个循环从1开始逐个打印,代码很简单:

void Print1ToMaxOfNDigits_1(int n){   int number=1;   int i=0;   while(i++<n)   {     number*=10;   }   for(i=i;i<number;i++)   {      printf("%d\t",i);   }}

初看之下似乎没什么问题,但如果仔细分析这个问题,当输入的n很大的时候,我们求最大的n位数是不是用整形(int)或者长整形(long long)都会溢出?在这里我们没有考虑大数问题。

思路:我们可以用字符串或者数组来表达大数。用字符串表示数字的时候,最直观的方法就是字符串里面每个字符都是’0’到’9’之间的某个字符,用来表示数字中的一位。因为数字最大是n位,因此我们需要一个长度为n+1的字符串(字符串中最后一个是结束符号’\0’),当实际数字不够n位时,在字符串的前半部分补0。首先我们把字符串中的每一个数字都初始化为’0’,然后每一次为字符串表示的数字加1,再打印出来。

即分为两步:1.在字符串表达的数字上模拟加法 2把字符串表达的数字打印出来

void Print1ToMaxOfNDigits(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=false;    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++;//数字+1        }        if(nSum>=10)//值>=10要进位*******************        {            if(i==0)//如果已经到了第一位,进位就溢出            {                isOverflow=true;            }            else{//如果没有到第一位,就向前进位                nSum-=10;//该位变为0,进一位                nTakeOver=1;//进位+1                number[i]='0'+nSum;            }        }        else{//值<10,结束,准备打印该值***************           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')//只有碰到第一个非0字符之后才开始打印      {          isBeginning0==false;      }      if(!isBeginning0)      {          printf("%c",number[i]);      }   }   printf("\t");}

上述思路虽然很直观,但是由于模拟了整数的加法,代码看起来有些冗长。下面我们换一种思路来考虑这个问题。如果我们在数字前面补0的话,就会发现n位所有十进制数其实就是n个从0到9的全排列。全排列用递归很容易,数字的每一位都可能是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';     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+i]=i+'0';      Print1ToMaxOfNDigitsRecursively(number,length,index+1);   }}void PrintNumber(char* number){   int nLength=strlen(number);   bool isBeginning0=true;   for(int i=0;i<nLength;++i)   {      if(isBeginning0 && number[i]!='0')      {          isBeginning0=false;      }      if(!isBeginning0)      {          printf("%c",number[i]);      }   }}
原创粉丝点击