打印1到最大的n位数
题目:输入数字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
题目:输入数字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]);
}
}
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)