剑指offer上面看到的题目,来练习一下~~~mark~~~~
这道题说的是打印1到最大的N位数,如N=3,则输出1到999之间的所有数字。
so, 需要特别注意:大数。
直观算法:
(1)需要建立数组存放当前数字,数组的每一位即为数字当前位,数组的长度当然也是N了。
(2)对这个数组进行模拟加法器的操作。主要考虑点在进位的处理上。
当然,这道题这样子做略显麻烦,哈哈,看下面全排列的做法吧。
算法一:理解为全排列。求1到最大的N位数,其实是每个位上面0-9为选项的全排列。
#include <iostream>
using namespace std;
void Print(char *s)//输出,忽略数字前面的0.
{
bool bIsZero = true;
for (int i = 0;i<strlen(s);i++)
{
if(s[i] != '0')
bIsZero = false;
if(!bIsZero)
printf("%c", s[i]);
}
if(!bIsZero)
printf("\t");
}
void Print1ToMaxOfNDigitsRecursively(char* s, int n, int index)//递归调用,
{
if(index == n -1)
{
Print(s);
return;
}
for(int i = 0;i<10;i++)
{
s[index+1] = '0'+i;
Print1ToMaxOfNDigitsRecursively(s, n, index+1);
}
}
bool Print1ToMaxOfNDigits(int n)
{
if(n <= 0)
return false;
char* str = new char[n+1];
str[n] = '\0';
fill(str, str+n, '0');
for(int i = 0;i<10;i++)
{
str[0] = i + '0';
Print1ToMaxOfNDigitsRecursively(str, n, 0);
}
return true;
}
int main(void)
{
Print1ToMaxOfNDigits(2);
return 0;
}
算法二:递归方法。
#include<iostream>
using namespace std;
void Print(char *s)//输出,忽略数字前面的0.
{
bool bIsZero = true;
for (int i = 0;i<strlen(s);i++)
{
if(s[i] != '0')
bIsZero = false;
if(!bIsZero)
printf("%c", s[i]);
}
if(!bIsZero)
printf("\t");
}
bool Increment(char* s)//字符串的加法器
{
int bOverFlow = 0;
int num = s[strlen(s)-1] - '0';
num++;
bOverFlow = num/10;
if(bOverFlow > 0)
{
int i = strlen(s)-2;
while(i>=0&&bOverFlow)
{
int tmp = s[i]-'0'+bOverFlow;
bOverFlow = tmp / 10;
s[i] = tmp%10+'0';
i--;
}
num = num%10;
}
s[strlen(s)-1] = num + '0';
return bOverFlow>0;
}
void Print1ToMaxOfNDigits(int n)
{
if(n <=0)
return;
char* str = new char[n+1];
fill(str, str+n, '0');
str[n] = '\0';
while(!Increment(str))//模拟字符串的加法器
{
Print(str);//输出
}
}
int main(void)
{
Print1ToMaxOfNDigits(2);
return 0;
}