说明:本文仅供学习交流,转载请标明出处,欢迎转载!
今天看到剑指offer上的第12题,题目例如以下:
输入数字n。按顺序打印出从1到最大的n位十位数。
比方输入3,则打印出1,2,3,...,999。
当我看到这个题目的时候。第一感觉就是用递归,为什么呢?首先得从我们的一个实际数字出发,比方123。我们对数字加1,实际上分为例如以下两个步骤:
步骤1:最低位加1;
步骤2:若发生进位,则向更高位传播该进位的影响(这也是递归的所在)。
在完毕这个算法题之前。我想插一句“细节决定成败!”,我们写一个程序,事实上大体的思路都能想到。而往往忽略对细节的考虑,如本题须要考虑的问题例如以下:
1.怎样表示一个n位数?(用字符数组)
2.每次加1都在最低位进行;
3.加1后若发生进位。则将该进位传播给高位数字(这里既可用循环,也可用递归);
4.若最高位发生进位,则溢出,该溢出可作为打印最后一个数的标志;
5.打印数字时,仅仅能从最高位不为0的数字起開始打印。(这符合数字的正常表示)
递归实现例如以下:
#include<iostream>
#include<cstring>
using namespace std;
bool Increment(char *str,int length)//字符串加1,假设为发生溢出,则返回true,否则返回返回false
{
if(str==NULL && length<1)//假设发生溢出。则返回false
{
return false;
}
int sum=str[length-1]-'0'+1;
if(sum<10)//假设不发生进位
{
str[length-1]+=1;
return true;
}
else
{
if(length-1==0)//假设溢出,则返回false
{
return false;
}
str[length-1]='0';//发生进位,把剩下的任务交给前length-1个字符
return Increment(str,length-1);//递归表达式
}
}
void print(char *str)//打印字符,打印时去掉前面的几个0
{
bool isBegin=false;//标识能否够開始输出
int i;
for(i=0;i<strlen(str);i++)
{
if(!isBegin && str[i]!='0')//假设找到第一个非0字符,则标识能够開始输出了
{
isBegin=true;
}
if(isBegin)
{
cout<<str[i];
}
}
cout<<endl;
}
void ToMaxN(int n)//打印从1到最大的N位数
{
if(n>=1)
{
char *str=new char[n+1];
memset(str,'0',n);
str[n]='