没有递归的排列算法?爪哇岛
2022-09-01 01:27:13
我想得到一个数字的所有组合,没有任何重复。比如 0.1.2、0.2.1、1.2.0、1.0.2、2.0.1、2.1.0。我试图找到一个简单的方案,但无法找到。我为它画了一个图形/树,这尖叫着使用递归。但是如果可能的话,我想在没有递归的情况下执行此操作。
任何人都可以帮我这样做吗?
我想得到一个数字的所有组合,没有任何重复。比如 0.1.2、0.2.1、1.2.0、1.0.2、2.0.1、2.1.0。我试图找到一个简单的方案,但无法找到。我为它画了一个图形/树,这尖叫着使用递归。但是如果可能的话,我想在没有递归的情况下执行此操作。
任何人都可以帮我这样做吗?
你应该使用这样一个事实,当你想要N个数字的所有排列时,有N个!可能性。因此,每个数字 x 从 1..N!对此类排列进行编码。下面是一个以迭代方式打印出刺痛的所有排列的示例。
private static void printPermutationsIterative(String string){
int [] factorials = new int[string.length()+1];
factorials[0] = 1;
for (int i = 1; i<=string.length();i++) {
factorials[i] = factorials[i-1] * i;
}
for (int i = 0; i < factorials[string.length()]; i++) {
String onePermutation="";
String temp = string;
int positionCode = i;
for (int position = string.length(); position > 0 ;position--){
int selected = positionCode / factorials[position-1];
onePermutation += temp.charAt(selected);
positionCode = positionCode % factorials[position-1];
temp = temp.substring(0,selected) + temp.substring(selected+1);
}
System.out.println(onePermutation);
}
}
这是我一年前写的一个通用排列枚举器。它还可以产生“子排列”:
public class PermUtil <T> {
private T[] arr;
private int[] permSwappings;
public PermUtil(T[] arr) {
this(arr,arr.length);
}
public PermUtil(T[] arr, int permSize) {
this.arr = arr.clone();
this.permSwappings = new int[permSize];
for(int i = 0;i < permSwappings.length;i++)
permSwappings[i] = i;
}
public T[] next() {
if (arr == null)
return null;
T[] res = Arrays.copyOf(arr, permSwappings.length);
//Prepare next
int i = permSwappings.length-1;
while (i >= 0 && permSwappings[i] == arr.length - 1) {
swap(i, permSwappings[i]); //Undo the swap represented by permSwappings[i]
permSwappings[i] = i;
i--;
}
if (i < 0)
arr = null;
else {
int prev = permSwappings[i];
swap(i, prev);
int next = prev + 1;
permSwappings[i] = next;
swap(i, next);
}
return res;
}
private void swap(int i, int j) {
T tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
我的算法背后的想法是,任何排列都可以表示为交换命令的唯一序列。例如,对于<A,B,C>,交换序列012将所有项目保留在原位,而122首先将索引0与索引1交换,然后将1与2交换,然后将2与2交换(即将其保留在原位)。这导致排列BCA。
这种表示与排列表示(即一对一关系)同构,并且在遍历排列空间时很容易“增量”。对于 4 个项目,它从 0123 (ABCD) 开始,以 3333(DABC) 结束。