排列生成算法是常用的算法之一,详细的介绍请查考《组合数学》教材。
1.序数法
序数思想来源于数字的表示形式
对于任何给定小于10的m次方的正整数N,我们可以表示为如下形式:
N= a0×10^0+...+a(m-1)×10^(m-1)
也就是说N可以唯一的表示为(a0,..., a(m-1))
同理对于任何属于0~(n!-1)的正整数m 我们可以唯一的表示为
m=a(n-1)*(n-1)!+...+a1*1!
这样给定整数m我们可以唯一的表示为(a(n-1),...,a1)
对于以上的计算,显而易见了。
对于任何一个排列p1,p2,p3,...,pn
ai可以看作是排列p中i+1所在的位置比较i+1小的数的个数。
例如:4213,4右边的比4小的数为3,则a3=3,同理可得
p=(4212)可以表示为(301)
反过来我们可以通过301得到4213。
具体参照《组合数学》
由此可以对于数序算法的核心主要包括两个
一是如何把一个整数映射到一个元素序数
二是对序数的解码
对于算法的实现,如下:
package recursive; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class Perm { public ArrayList ordinalPerm(String input) { int lenght = input.length(); int num = caculatePerm(lenght); ArrayList al = new ArrayList(); for (int i = 0; i < num; i++) { String code = num2ordinal(i, lenght - 1); al.add(decode(code, input)); } return al; } // decode private String decode(String code, String input) { int[] tag = new int[code.length() + 1]; char[] content = new char[code.length() + 1]; for (int i = 0; i < code.length(); i++) { int pos = Integer.parseInt(code.charAt(i) + ""); char temp = input.charAt(input.length() - 1 - i); int ept = 0; int index = 0; // locate the position of new character // count the empty slot for (int j = tag.length - 1; j >= 0; j--) { if (ept == pos && tag[j] != 1) { index = j; break; } else { if (tag[j] != 1) ept++; } } content[index] = temp; tag[index] = 1; } for (int i = 0; i < tag.length; i++) { if (tag[i] == 0) content[i] = input.charAt(0); } String result = ""; for (int i = 0; i < content.length; i++) { result += content[i]; } return result; } private String num2ordinal(int k, int lenght) { String s = ""; for (int i = 0; i < lenght; i++) { s = k % (i + 2) + s; k = k / (i + 2); } return s; } // the num of permutation private int caculatePerm(int n) { if (n <= 1) { return 1; } else { int perm = 1; for (int i = n; i >= 1; i--) { perm *= i; } return perm; } } }
input:1234 output:如下 0 000 1234 1 001 2134 2 010 1324 3 011 2314 4 020 3124 5 021 3214 6 100 1243 7 101 2143 8 110 1342 9 111 2341 10 120 3142 11 121 3241 12 200 1423 13 201 2413 14 210 1432 15 211 2431 16 220 3412 17 221 3421 18 300 4123 19 301 4213 20 310 4132 21 311 4231 22 320 4312 23 321 4321