分析java
誠然,最早想到的方法就是10層循環(OMG!),這顯然是一個很可怕的方法(雖然這並無錯)。算法
那麼咱們該怎麼辦呢?數組
接下來就該想到將這62個字符對應一個固定的下標,咱們按必定的方法生成一個下標數組,而後取出對應的字符組成字符串,就是咱們要的結果啊!app
那麼這個下標數組該如何生成呢?優化
咱們能夠維護一個包含10個下標值的數組(由於元素不能重複,因此初始值能夠設定爲(0,1,2,3,4,5,6,7,8,9),而不是(0,0,0,0,0,0,0,0,0)),spa
而後檢查其中是否有重複的下標?若是有,則不符合要求,進行下一步;若是沒有,則符合要求,輸出其對應的字符串;code
將數組中最後一個數加1,而後從後向前遍歷數組,每一個數(原始字符串的長度)除以62,將結果加到前一個數上,其自己對62取餘;字符串
檢查這個數組是否已經遍歷完全部的組合(數組中全部的數都是61),沒有,則返回(i)步開始執行,不然程序結束get
代碼io
public class Main { private static final String originalStr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; public static void main(String[] args) { int[] charArr = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 61}; while(notTheEnd(charArr)) { if(isOK(charArr)) { System.out.println(getString(charArr)); } addOne(charArr); } } /** * 查看charArr是否已經查找到最後一個值,即全部的值都是61 * @param charArr * @return */ private static boolean notTheEnd(int[] charArr) { for(int i = 0; i < charArr.length; i++) { if(charArr[i] < 61) return true; } return false; } /** * 將charArr的最後一個值加1,超過61,要對62取餘,並向前一個數進位 * @param charArr */ private static void addOne(int[] charArr) { int len = originalStr.length(); charArr[charArr.length - 1]++; int carry = 0; for(int i = charArr.length - 1; i >= 0; i--) { charArr[i] += carry; carry = charArr[i] / len; charArr[i] %= len; } } /** * 查看charArr中是否有重複值 * @param charArr * @return */ private static boolean isOK(int[] charArr) { for(int i = 0; i < charArr.length; i++) { for(int j = i + 1; j < charArr.length; j++) { if(charArr[i] == charArr[j]) return false; } } return true; } /** * 將charArr中數字所對應的字符,組成字符串返回 * @param charArr * @return */ private static String getString(int[] charArr) { StringBuffer sb = new StringBuffer(); for(int i = 0; i < charArr.length; i++) { sb.append(originalStr.charAt(charArr[i])); } return sb.toString(); } }
總結
整體思想仍是進制的問題。算法仍是有些幼稚,還有不少地方能夠優化,如:
如何判斷數組中是否有重複值;
若是有重複值出現,如何快速跳動到下一個不包含重複值的數組;