本文參考自《劍指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)
本身複習時寫的方法(比第一次寫的方法更清晰、簡潔點):
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===
1.任什麼時候候都不能輕視題目,像這道題看起來簡單,但其實涉及到大數問題,之後遇到數字相關的題目時要注意大數問題;
2.int類型和char類型轉化,經過±‘0’來實現,見int與char類型間的相互轉換。
3.打印字符串表示的數組,從第一個非零數字打印。