1. 程式人生 > >華為機試---解密(全排列)

華為機試---解密(全排列)

亮亮深吸一口氣,小心地將盒子開啟,裡面是一張地圖,地圖上除了一些奇怪的字母以外沒有任何路線資訊,這可讓亮亮犯了愁,這些字母代表了什麼意思呢? 亮亮絞盡腦汁也想不出什麼思路,突然,亮亮眼前一亮,“我可以把這些字母所有的排列方式全部寫出來,一定可以找到答案!” 於是,亮亮興奮的開始尋找字母裡的祕密。

輸入描述:
每組資料輸入只有一行,是一個由不同的大寫字母組成的字串,已知字串的長度在1到9之間,我們假設對於大寫字母有'A' < 'B' < ... < 'Y' < 'Z'。


輸出描述:
輸出這個字串的所有排列方式,每行一個排列,要求字母序比較小的排列在前面。

輸入例子:
WHL

輸出例子:
HLW

HWL

LHW

LWH

WHL

WLH
import java.util.Arrays;
import java.util.Scanner; 
public class Main {
 public static void main(String[] args){   
  Scanner scan = new Scanner(System.in);
  while(scan.hasNext()){ 
   String key = scan.nextLine();
   String[] result = QuanPaiLie(key);
   Arrays.sort(result);
   for(int i = 0 ; i < result.length ; i++){
    System.out.println(result[i]);
   }
  }
  scan.close();
    }
 /**
  * 求字串的全排列
  * 演算法思想:遞迴
  * 比如  abcde  先求出abcd的全排列,然後將e分別插入全排列的5個位置
  * a 全排列  a
  * ab 全排列  ab ba
  * abd 全排列即是  cab acb abc cba bca bac
  */
 private static String[] QuanPaiLie(String key) {
  //如果字串是空字串“”,或者是空物件
  if(key == null || key.isEmpty()){
   return null;
  }
  int length = key.length();
  //計算全排列後的字串個數
  int num = length;
  int sum = 1;  
  while(num != 0){
   sum *= num;
   num--;
  }
  String[] result = new String[sum];//儲存生成的全排列字串
  if(length == 1){
   result[0] = key;
  }else if(length == 2){
   result[0] = key;
   result[1] = "" + key.charAt(1) + key.charAt(0);
  }else{
  //length>2使用遞迴
   char end = key.charAt(length - 1);//儲存結尾的字元
   String frontStr = key.substring(0, length - 1);//擷取除過結尾字元以外的字串
   String[] frontStrResult = QuanPaiLie(frontStr) ;//遞迴
   //將結尾字元插入到生成字串的各個位置
   int frontResultNum = frontStrResult.length;//生成的字串個數
   int insertPlace = frontStrResult[0].length() + 1;//可以插入的位置 = 生成字串的長度 + 1
   int resultIndex = 0;
   for(int i = 0 ; i < frontResultNum ; i++){
    String tempResult = frontStrResult[i];
    for(int index = 0 ; index < insertPlace ; index++){
     result[resultIndex++] = tempResult.substring(0 , index) + end + tempResult.substring(index);
    }
   }
  }
  return result;
 }
}