问题:
给定字符串 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(); } }
暂时到这里了,以后有机会再补充!
以上算法全部经过验证通过,如有问题,请留言!