题目

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

思路

陷阱: n过大时是大数问题,不能简单用int或者long数据输出,需要采用字符串或者数组表达大数。

解决方法: 通过字符数组char[]来进行输出数字。

方法一:

1)在字符串表达的数字上模拟加法;

2)把字符串表达的数字打印出来。

方法二:

1)采用递归将每一位都从0到9排列出来;

2)把字符串表达的数字打印出来。

·测试算例

功能测试(输入1,2,3……)

特殊输入测试(输入0,-1)

完整Java代码

自己复习时写的方法(比第一次写的方法更清晰、简洁点):

	public void print1ToMaxOfNDights1s(int n) {
if(n<=0)
return;
char[] digit = new char[n];
for(int i=0;i<n;i++)
digit[i]='0';
for(int i=n-1;i>=0;i--) {
while(digit[i]!='9') {
int m=0;
digit[m]++;
while(m<n-1 && digit[m]>'9') {
digit[m]='0';
digit[m+1]++;
m++;
}
printdigits(digit);
}
}
} private void printdigits(char[] digit) {
int m = digit.length-1;
while(digit[m]=='0')
m--;
for(int i=m;i>=0;i--)
System.out.print(digit[i]);
System.out.println();
}

(第一次写的代码,含测试)

/**
*
* @Description 面试题17:打印1到最大的n位数
*
* @author yongh
* @date 2018年9月17日 下午9:07:53
*/ // 题目:输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则
// 打印出1、2、3一直到最大的3位数即999。 public class Print1ToMaxOfNDigits { //=========方法一============
/**
* 采用模拟加一的方法
*/
public void print1ToMaxOfNDigits(int n) {
if (n <= 0)
return;
char[] number = new char[n];
// 不能用foreach方法对nuber[]赋值
// for (char c : number) {
// c = '0';
// }
for (int k = 0; k < number.length; k++)
number[k] = '0';
while (!increment(number)) {
printCharNumber(number);
}
} /**
* 对字符串进行加一操作,number达到最大值后返回true
* 最低位加一;所有位如果超过10,则进位
*/
private boolean increment(char[] number) {
int nTakeOver = 0; // 代表进位
for (int i = number.length - 1; i >= 0; i--) {
int nSum = (number[i] - '0') + nTakeOver; // 当前位置数字
// number[i]-'0'是把char转化为int,nTakeOver代表进位
if (i == number.length - 1)
nSum++;
if (nSum >= 10) {
if (i == 0)
return true; // 超出范围了
nTakeOver = 1;
nSum -= 10;
number[i] = (char) (nSum + '0');
} else {
number[i] = (char) (nSum + '0');
break; // 高位不变,可以直接跳出循环了
}
}
return false;
} /**
* 打印字符数组形成的数字
* 书中方法:利用布尔变量isBeginning0来从第一个非零字符打印
*/
private void printCharNumber(char[] number) {
boolean isBeginning0 = true;
for (int i = 0; i < number.length; i++) {
if (isBeginning0 && (number[i] - '0') != 0) {
isBeginning0 = false;
}
if (!isBeginning0) {
// System.out.print(number[i] - '0');
System.out.print(number[i]);
}
}
System.out.println(); } /**
* 打印字符数组形成的数字
* 自己的方法:找出第一个非零字符位置,往后进行打印
*/
private void printCharNumber2(char[] number) {
int beginner = number.length; // 不写成number.length-1,以防写出0
for (int i = 0; i <= number.length - 1; i++) {
if ((number[i] - '0') != 0) {
beginner = i;
break;
}
}
for (int i = beginner; i <= number.length - 1; i++) {
System.out.print(number[i]);
}
if (beginner != number.length) // 数字为0时,换行符不输出
System.out.println();
} //=========方法二============
/**
* 采用递归的方法
*/
public void print1ToMaxOfNDigits2(int n) {
if (n <= 0)
return;
char[] number = new char[n];
for (int k = 0; k < number.length; k++)
number[k] = '0';
for (int i = 0; i <= 9; i++) {
makeNumber(n, number, i, 0);
}
} /**
* 生成数字
*/
private void makeNumber(int n, char[] number, int nNumber, int index) {
if (index == number.length - 1) {
number[index] = (char) (nNumber + '0');
printCharNumber2(number); // 打印数字代码与第一个方法一样
return;
} else {
number[index] = (char) (nNumber + '0');
for (int i = 0; i <= 9; i++) {
makeNumber(n, number, i, index + 1);
}
}
} // ========测试代码=============
void test(int nDigits) {
System.out.println("===test begin===");
System.out.println("method1:");
print1ToMaxOfNDigits(nDigits);
System.out.println("method2:");
print1ToMaxOfNDigits2(nDigits);
System.out.println("===test over===");
} public static void main(String[] args) {
Print1ToMaxOfNDigits demo = new Print1ToMaxOfNDigits();
demo.test(-1);
demo.test(0);
demo.test(1);
demo.test(2);
}
}

===test begin===
method1:
method2:
===test over===
===test begin===
method1:
method2:
===test over===
===test begin===
method1:
1
2
3
4
5
6
7
8
9
method2:
1
2
3
4
5
6
7
8
9
===test over===
===test begin===
method1:
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
method2:
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
===test over===

Print1ToMaxOfNDigits

收获

1.任何时候都不能轻视题目,像这道题看起来简单,但其实涉及到大数问题,以后遇到数字相关的题目时要注意大数问题;

2.int类型和char类型转化,通过±‘0’来实现,int与char类型间的相互转换:https://www.cnblogs.com/yongh/p/9688259.html。

3.打印字符串表示的数组,从第一个非零数字打印。

Java 剑指offer(16) 打印1到最大的n位数的更多相关文章

  1. 【Java】 剑指offer(16) 打印1到最大的n位数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入数字n,按顺序打印出从1最大的n位十进制数.比如输入3,则打印 ...

  2. 剑指OFFER之打印1到最大的N位数(九度OJ1515)

    题目描述: 给定一个数字N,打印从1到最大的N位数. 输入: 每个输入文件仅包含一组测试样例.对于每个测试案例,输入一个数字N(1<=N<=5). 输出: 对应每个测试案例,依次打印从1到 ...

  3. 【剑指offer】打印1到最大的n位数

    题目描写叙述: 输入数字n,按顺序打印出从1到最大的n位十进制数.比方输入3,则打印出1.2.3一直到最大的3位数即999. 分析描写叙述: 首先想到的是先计算出最大的n位数是多少,然后用一个循环从1 ...

  4. 剑指 Offer 17. 打印从1到最大的n位数

    剑指 Offer 17. 打印从1到最大的n位数 Offer 17 题目解析: 暴力解法 package com.walegarrett.offer; /** * @Author WaleGarret ...

  5. 力扣 - 剑指 Offer 17. 打印从1到最大的n位数

    题目 剑指 Offer 17. 打印从1到最大的n位数 思路1 如果有n位,那么最大值就是\(10^n-1\),即如果n是2,那么最大就到输出到99 考虑到大数情况,所以使用字符数组 还要把字符数组转 ...

  6. 【剑指offer】打印1到最大的n数字

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/25562105 剑指offer第12题.九度OJ測试通过. 题目描写叙述: 给定一个数字N, ...

  7. 剑指Offer 顺时针打印矩阵

    题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2, ...

  8. 剑指OFFER——顺时针打印矩阵

    输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8 ...

  9. python剑指offer 顺时针打印指针

    题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数 ...

  10. 用js刷剑指offer(顺时针打印数组)

    题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数 ...

随机推荐

  1. hci0 command 0xfc20 tx timeout(Realtek 8761B Chipset, Bluetooth 5.0)

    当前使用的Linux内核版本: 4.4.189 插上USB Bluetooth 5.0 Adapter后,dmesg显示如下log: [ 240.348480] usb 3-1.2: new full ...

  2. rust程序设计(5)结构体相关练习题| 附带解答

    题目 基础结构体练习: 创建一个名为Person的结构体,包含name(字符串类型)和age(整数类型)两个字段. 写一个函数,接收一个Person实例作为参数,并打印出这个人的名字和年龄. 结构体方 ...

  3. 图文剖析 big.js 四则运算源码

    big.js,一个小型.快速的用于任意精度的十进制算术的JavaScript 库. big.js 用于解决平常项目中进行算术运算时精度丢失引起的结果不准确的问题.和 big.js 类似的两个库 big ...

  4. 【Javaweb】Servlet三|实现Servlet程序的几种方法及Servlet继承体系说明

    GET和POST请求的分发处理 代码如下 注意页面要和index位置一样否则浏览器找不到 注意大小写 HttpServletRequest httpServletRequest = (HttpServ ...

  5. VS Code安装教程

    一.下载 1.官网 下载地址:https://code.visualstudio.com/Download 2.下载 根据自己电脑型号下载,此处以Windows为例. 二.安装 1.下载完成后,直接点 ...

  6. [ABC246E] Bishop

    Problem Statement We have an $N \times N$ chessboard. Let $(i, j)$ denote the square at the $i$-th r ...

  7. 关于C#反射概念,附带案例!

    反射 C#中的反射是一种使程序在运行时能够动态地获取类型信息并调用其成员的技术.通过反射,程序可以在运行时进行类型的动态加载.创建对象.调用方法和属性,以及访问和修改字段等.反射可以使程序更加灵活,但 ...

  8. Spring Framework系统架构

  9. 图扑物联 | WEB组态可视化软件

    01什么是组态? 组态的概念来自于20世纪70年代中期出现的第一代集散控制系统(Distributed Control System),可理解为"配置"."设置" ...

  10. 使用dtd定义元素