問題:
給定字符串 abcdefg ,請給出其:
①全排列; (★)
基本概念
排列
一般地,從n個不同元素中取出m(m≤n)個元素,按照一定的順序排成一列,叫做從n個元素中取出m個元素的一個排列(Sequence,Arrangement, Permutation)。
全排列
當m=n時所有的排列情況叫全排列。
全排列數f(n)=n!(定義0!=1)
算法
基本算法
(A)字典序法
(B)遞增進位制數法
(C)遞減進位制數法
(D)鄰位對換法
生成樹
遞歸
實現一般多爲遞歸,暫且給出遞歸的方法吧,以後有方法會補充的。
組合排列算法實現1
一種很迅速就想起來的,比較水的方法,就是窮舉了,如下:
package com.java.interview.algorithm; public class Full_Permutation { private static int count = 0; public static void main(String[] args) { String string = "abcdefg"; // String string = "abc"; int length = string.length(); int re_count = 0; int permutation = permutation(string, length, re_count); // System.out.println("遞歸了 " + permutation + " 次!"); } public static int permutation(String string, int length, int re_count) { if (length == re_count) { return count; } StringBuilder str_copy = new StringBuilder(string); String str_copy2 = str_copy.substring(1) + str_copy.charAt(0); count++; for (int i = 0; i < length; i++) { System.out.println(str_copy.substring(0, i + 1)); } return permutation(str_copy2, length, count); // String str_copy2 = str_copy.substring(1) + str_copy.charAt(0); // return permutation(str_copy2, length, count); } }
組合排列及全排列算法實現2
package com.java.interview.algorithm; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Full_Permutation_Final { private static int total; private static int total_all; public static void main(String[] args) { // String string = "abcdefg";//總共有 13699 中組合! // String string = "abcd";//64 // string 不能有重複的字母 String string = "abc";// int length = string.length(); permutation(string, length); permutation_All(string, length); } public static void permutation_All(String string, int length) { total_all = 0; String[] strings = new String[length]; for (int i = 0; i < strings.length; i++) { strings[i] = string.charAt(i) + ""; } sort_num(Arrays.asList(strings), new ArrayList<String>(), length); System.out.println("全排列總共有 " + total_all + " 中組合!"); } public static void permutation(String string, int length) { total = 0; String[] strings = new String[length]; for (int i = 0; i < strings.length; i++) { strings[i] = string.charAt(i) + ""; } for (int j = 0; j < length; j++) { sort_num(Arrays.asList(strings), new ArrayList<String>(), j + 1); } System.out.println("總共有 " + total + " 中組合排列!"); } /** * 遞歸算法:將數據分爲兩部分,遞歸將數據從左側移右側實現全排列 * * @param datas * @param target */ private static void sort_num(List<String> datas, List<String> target, int num) { if (target.size() == num) { for (Object obj : target) System.out.print(obj); System.out.println(); total++; total_all++; // 遞歸條件下每一層的return只能返回到上一層,而不能跳出整個遞歸函數 // 即通過return恢復datas與target return; } for (int i = 0; i < datas.size(); i++) { List<String> newDatas = new ArrayList<String>(datas); List<String> newTarget = new ArrayList<String>(target); newTarget.add(newDatas.get(i)); newDatas.remove(i); sort_num(newDatas, newTarget, num); } } }
全排列算法實現3(參考)
public class FullSort { // 將NUM設置爲待排列數組的長度即實現全排列 private static int NUM = 2; /** * 遞歸算法:將數據分爲兩部分,遞歸將數據從左側移右側實現全排列 * * @param datas * @param target */ private static void sort(List datas, List target) { if (target.size() == NUM) { for (Object obj : target) System.out.print(obj); System.out.println(); return; } for (int i = 0; i < datas.size(); i++) { List newDatas = new ArrayList(datas); List newTarget = new ArrayList(target); newTarget.add(newDatas.get(i)); newDatas.remove(i); sort(newDatas, newTarget); } } public static void main(String[] args) { String[] datas = new String[] { "a", "b", "c", "d" }; sort(Arrays.asList(datas), new ArrayList()); } }
另外一種百科上的遞歸算法:(遞歸-恢復-遞歸-恢復)
package com.java.interview.algorithm; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * <p> * Title:全排列算法 * </p> * * <p> * Copyright: http://blog.csdn.net/sunyujia/ * </p> * * @author 孫鈺佳 * @main [email protected] * @date 2009-04-25 23:57:23 PM */ public class Full_Permutation_Final2 { public static char[] text = { 'a', 'b', 'c', 'd', 'e' }; public static void main(String[] args) { permutation(text, 0, text.length); System.exit(0); } /** * 全排列輸出 * * @parama[]要輸出的字符數組 * @paramm輸出字符數組的起始位置 * @paramn輸出字符數組的長度 */ public static void permutation(char a[], int m, int n) { int i; char t; if (m < n - 1) { permutation(a, m + 1, n); for (i = m + 1; i < n; i++) { t = a[m]; a[m] = a[i]; a[i] = t; permutation(a, m + 1, n); t = a[m]; a[m] = a[i]; a[i] = t; } } else { printResult(a); } } /** * 輸出指定字符數組 * * @param將要輸出的字符數組 */ public static void printResult(char[] text) { for (int i = 0; i < text.length; i++) { System.out.print(text[i]); } System.out.println(); } }
暫時到這裏了,以後有機會再補充!
以上算法全部經過驗證通過,如有問題,請留言!