【剑指offer】面试题12、打印 1 到最大的 n 位数

题目:输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入数字 3,则打印出 123 ··· 999(因为最大的 3 为数即为 999)。

这个题目看似简单。最容易想到的办法就是先求出 n 位十进制数的最大值,然后利用for循环逐个打印出即可;

代码如下:

 1 // Print1ToMaxOfNDigits.c
 2 #include "stdio.h"
 3 #include "stdlib.h"
 4 
 5 void Print1ToMaxOfNDigits(int n)
 6 {
 7     int num = 1;
 8     int i = 0;
 9     while(i++ < n)
10         num *= 10;
11 
12     for(i = 1; i < num; ++i)
13         printf("%d ", i);
14     printf("
");
15 }
16 
17 int main(int argc, char *argv[])
18 {
19     int i;
20     while(printf("Please input a num: "), scanf("%d", &i))
21     {
22         Print1ToMaxOfNDigits(i);
23     }
24     return 0;
25 }
View Code

如果仔细分析这个问题,我们可能就注意到这里并没有规定 n 的范围。因此当输入的 n 很大的时候,我们求最大的 n 位数无论是用 int 整型还是 long 长整形都会溢出。这里实际所描述的是大数问题。

解法:在字符串上模拟数字加法

1、由于数字最大是 n 位的,因此我们需要一个长度为 n+1 的字符串(最后一个为结束符‘ ’)

2、当实际数字不够 n 位的时候,在字符串的前半部分补 0 即可。打印时,需要绕过前面为 0 的位。

3、首先为我们所申请的 n+1 位字符初始化,皆为'0'。

4、然后我们只需要做两件事:

 一是在字符串所表达的数字上模拟加法;

 二是把字符串表达的数字打印出来。

基于上面的分析,我们可以写出如下代码:

 1 void Print1ToMaxOfNDigits(int n)
 2 {
 3     if(n <= 0)
 4         return;
 5 
 6     char *result = new char[n+1];
 7     memset(result, '0', n);
 8     result[n] = '