题目描述
输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,打印出1,2,3一直到最大的3位数即999.
解析
- n的取值范围可以很大,考虑大数问题。
- 最常见的方法是用字符串或者数字表达大数。
- 把问题转换成数字排列问题。
在字符串上模拟数字加法
思考:
如何用字符串存储数字;
如何在字符串表达的数字上模拟加法
把字符串表达是数字打印出来
实现
#include <iostream>
#include <stdlib.h>
//字符串表达的数字模拟加法
bool Increment(char* number){
bool isOverflow = false;
int carry = 0; //表示进位
int n = strlen(number);
for (int i = n-1; i >= 0; i--){
int sum = number[i] - '0' + carry;
if (i == n - 1){
sum++;
}
if (sum >= 10){
if (i == 0)
isOverflow = true;
else{
number[i] = sum - 10 + '0';
carry = 1;
}
}else{
number[i] = sum + '0';
break; //没有产生进位,只需要修改有进位的部分
}
}
return isOverflow;
}
//把字符串表达的数字打印出来
void PrintNumber(char* number){
int n = strlen(number);
int i = 0;
while (number[i] == '0'){
i++;
}
while (i < n){
printf("%c", number[i]);
i++;
}
printf("\t");
}
//字符串模拟数字加法
void Print1ToNOfNDigits(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;
}
int main()
{
Print1ToNOfNDigits(-1);
Print1ToNOfNDigits(0);
Print1ToNOfNDigits(3);
system("pause");
return 0;
}
数字排列的方法
把数字的每一位都从0到9排列一遍,就得到了所有的十进制数,然后在打印的时候,数字排在前面的0不打印出来。
数字的每一位都可能是0~9中的一个数,然后设置下一位,递归结束的条件是我们已经设置数字的最后一位。
实现
#include <iostream>
void printNumber(char* number){
int n = strlen(number);
int i = 0;
while (number[i] == '0'){
i++;
}
while (i < n){
printf("%c", number[i]);
i++;
}
printf("\t");
}
void Print1ToNOfDigitsRecursively(char* number, int length, int index){
if (index == length - 1){
printNumber(number);
return;
}
for (int i = 0; i < 10; i++){
number[index + 1] = i + '0'; //设置index+1位的值
Print1ToNOfDigitsRecursively(number, length, index + 1);
}
}
void Print1ToNOfNDigits(int n){
if (n <= 0)
return;
char* number = new char[n + 1];
memset(number, '0', n);
number[n] = '\0';
for (int i = 0; i < 10; i++){
number[0] = i + '0'; //n位数的最高位设置值
Print1ToNOfDigitsRecursively(number, n, 0);
}
delete[] number;
}
int main()
{
Print1ToNOfNDigits(-1);
Print1ToNOfNDigits(0);
Print1ToNOfNDigits(3);
system("pause");
return 0;
}