【Java】 劍指offer(16) 打印1到最大的n位數

本文參考自《劍指offer》一書,代碼採用Java語言。html

更多:《劍指Offer》Java實現合集  java

題目

  輸入數字n,按順序打印出從1最大的n位十進制數。好比輸入3,則打印出一、二、3一直到最大的3位數即999。git

思路

  陷阱:n過大時是大數問題,不能簡單用int或者long數據輸出,須要採用字符串或者數組表達大數。面試

  解決方法:經過字符數組char[]來進行輸出數字。數組

 方法一:ide

  1)在字符串表達的數字上模擬加法;post

  2)把字符串表達的數字打印出來。測試

 方法二:url

  1)採用遞歸將每一位都從0到9排列出來;spa

  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,則
// 打印出一、二、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類型間的相互轉換

  3.打印字符串表示的數組,從第一個非零數字打印。

  

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索