Fork me on GitHub

算法(打印1到最大的n位数)

题目

数组数字你,按顺序打印出从1到最大n位十进制数。比如输入3,则打印出1、2、3…999

这个题目大家看着其实很简单,而且很快就能写出如下的代码:

1
2
3
4
5
6
7
8
9
10
void printNumber(int n){
int number = 1;
int i = 0;
while(i++<n){
number *= 10;
}
for (int i = 0; i<number;i++){
printf("%d",i);
}
}

这样写看着也能实现,但是有个问题就是如果n很大,超过了整型类型的最大数值范围呢??
所以我们最好用字符串来解此算法。

思路

我们定义一个n+1的字符串,最后一位为’\0’结束标志位,每位的范围为’0’-‘9’,然后对字符串进行+1计算。如果被加位为’9’则进1位,如此循环。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
bool increment(char *number){
int nLength = (int)strlen(number);
bool flag = false;
for (int i = nLength-1; i>=0; i--) {
int nSum = number[i]-'0';//取得原来的字符,转换成数字
nSum += 1;//进行加1
if (nSum>=10) {//如果大于10,则就是'9'
if (i==0) {//循环结束标志.当i等于0的时候,说明已经循环到了最大为,并且最大位需要加1了,(比如n=3,最大位'999'),此时就是结束的时候
flag = true;
}
number[i]='0';
}else{//小于10的话直接输出
number[i] = nSum+'0';
break;
}
}
return flag;
}
void printNumber(char *number){//由于数字可能前边有‘0’比如'0088',这时我们要把前边的'0'去掉
int flag = false;
for (int i = 0;i<strlen(number); i++) {
if (number[i]-'0'!=0) {
flag = true;
}
if (flag) {
printf("%c",number[i]);
}
}
printf("\n");
}
void print1ToMaxOfNumber(int n){
char *number = calloc(n+1, sizeof(char));
number[n] = '\0';
memset(number,'0',n);
while (!increment(number)) {
printNumber(number);
}
}
//******* 测试数据 *********
//printf("%d\n",number2Of1(-10));
//print1ToMaxOfNumber(3);

感想

连着看了2个星期的数据结构和算法了。一边在看书,一边在写算法。不得不说这个过程挺耗脑子的。每一个算法题自己一开始想到的可能不是最优方法,然后根据书上最优方法进行修改,如此循环。
本来计划是一个季度,3个月的时间会重点研究数据结构和算法,2个多星期体验开来,到自己刷完定的目标的算法题是有点慢,但是万事开头难吧,希望自己能够坚持下来达到自己的目标。

0%