排列生成算法实现java
2011-07-24 00:37
567 查看
排列生成算法是常用的算法之一,详细的介绍请查考《组合数学》教材。
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。
具体参照《组合数学》
由此可以对于数序算法的核心主要包括两个
一是如何把一个整数映射到一个元素序数
二是对序数的解码
对于算法的实现,如下:
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
相关文章推荐
- 最小生成树算法——Kruskal算法Java实现
- java实现图的最小生成树(MST)的普利姆(Prim)算法
- Prim最小生成树算法详解以及java实现源代码
- java生成MD5校验码及算法实现
- JAVA实现全排列算法(去重复)
- Kruskal生成树算法的java代码简单实现
- 生成排列的算法实现
- [算法学习]Java实现字符串全排列
- 备考蓝桥杯(37)超级无敌经典的全排列算法 java实现
- java生成MD5校验码及算法实现
- 微博URL短网址生成算法原理及(java版、php版实现实例)
- 算法java实现--回溯法--圆排列问题--排列树
- Java 语言实现的随机数生成算法
- 排列组合算法总结(含Java实现)
- java排列组合算法代码实现
- 高效率的排列组合算法(java实现)
- 基于rsync同步算法的文件同步系统JAVA实现(二)——校验码的生成
- 【LeetCode-面试算法经典-Java实现】【046-Permutations(求排列)】
- 一个php实现的生成排列的算法
- 【LeetCode-面试算法经典-Java实现】【022-Generate Parentheses(生成括号)】