我在网上找到了这个代码,它可以很好地通过给定的数组进行置换并返回给定数字的所有可能组合。有谁知道如何更改此代码以包含2D数组?
public static ArrayList<ArrayList<Integer>> permute(int[] numbers) {
ArrayList<ArrayList<Integer>> permutations = new ArrayList<ArrayList<Integer>>();
permutations.add(new ArrayList<Integer>());
for ( int i = 0; i < numbers.length; i++ ) {
ArrayList<ArrayList<Integer>> current = new ArrayList<ArrayList<Integer>>();
for ( ArrayList<Integer> p : permutations ) {
for ( int j = 0, n = p.size() + 1; j < n; j++ ) {
ArrayList<Integer> temp = new ArrayList<Integer>(p);
temp.add(j, numbers[i]);
current.add(temp);
}
}
permutations = new ArrayList<ArrayList<Integer>>(current);
}
return permutations;
}
这就是我的尝试:
public static int[][] permute(int[] numbers){
int[][] permutations = new int[24][4];
permutations[0] = new int[4];
for ( int i = 0; i < numbers.length; i++ ) {
int[][] current = new int[24][4];
for ( int[] permutation : permutations ) {
for ( int j = 0; j < permutation.length; j++ ) {
permutation[j] = numbers[i];
int[] temp = new int[4];
current[i] = temp;
}
}
permutations = current;
}
return permutations;
}
然而,这会返回全零。我选择24和4,因为这是我需要的2D阵列的大小。 感谢
答案 0 :(得分:0)
这并不是那么容易。原始代码利用// Save NSMutableDictionary to NSUserDefaults
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: dataDictionary];
[[NSUserDefaults standardUserDefaults] setObject: data forKey: key];
[[NSUserDefaults standardUserDefaults] synchronize];
// Retrieve dictionary from NSUserDefaults
NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey: key];
NSMutableDictionary* dataDictionary = [[NSKeyedUnarchiver unarchiveObjectWithData: data] mutableCopy];
的更动态行为,因此需要一些手动编码。您的代码中有许多正确的想法。我试着写下我看到的问题的解释,但它变得太长了,所以我决定修改你的代码。
原始ArrayList
是最难处理数组的部分,因为它将元素推向位置temp.add(j, numbers[i]);
右侧的一个位置。在我的版本中,我在中间循环中创建一个临时数组,并在最里面的循环中一次洗一个元素。
j
我使用临时数组的技巧意味着我没有得到与原始代码中相同顺序的排列。如果这是一项要求,您可以从索引1开始将public static int[][] permute(int[] numbers) {
// Follow the original here and create an array of just 1 array of length 0
int[][] permutations = new int[1][0];
for (int i = 0; i < numbers.length; i++) {
// insert numbers[i] into each possible position in each array already in permutations.
// create array with enough room: when before we had permutations.length arrays, we will now need:
int[][] current = new int[(permutations[0].length + 1) * permutations.length][];
int count = 0; // number of new permutations in current
for (int[] permutation : permutations) {
// insert numbers[i] into each of the permutation.length + 1 possible positions of permutation.
// to avoid too much shuffling, create a temp array
// and use it for all new permutations made from permutation.
int[] temp = Arrays.copyOf(permutation, permutation.length + 1);
for (int j = permutation.length; j > 0; j--) {
temp[j] = numbers[i];
// remember to make a copy of the temp array
current[count] = temp.clone();
count++;
// move element to make room for numbers[i] at next position to the left
temp[j] = temp[j - 1];
}
temp[0] = numbers[i];
current[count] = temp.clone();
count++;
}
assert count == current.length : "" + count + " != " + current.length;
permutations = current;
}
return permutations;
}
复制到permutation
并在循环中以相反的方式进行混洗。 temp
可以进行初始复制。
答案 1 :(得分:0)
这里的问题是你真的需要正确实现ArrayList.add(int,value)
命令的数组版本。也就是说你做一个System.arraycopy()并将j之后的所有值推下来,然后将值插入j。您当前设置了该值。但是,这会覆盖排列[j]的值,它实际上应该已经被置换为排列[j + 1]。
所以你在哪里:
permutation[j] = numbers[i];
应该是:
System.arraycopy(permutation,j, permutations, j+1, permutations.length -j);
permutation[j] = numbers[i];
由于ArrayList.add(int,value)就是这样做的。您基本上错误地将其实现为.set()。
虽然我个人会废弃代码,然后选择动态制作这些值。还有一些价值观,而你正在谈论关于记忆的禁令。找到排列的第n个索引并不难。即使没有分配任何内存也是如此。 (虽然你需要一个数组的副本,如果你要在不引起奇怪的情况下摆弄这些东西)。
public static int[] permute(int[] values, long index) {
int[] returnvalues = Arrays.copyOf(values,values.length);
if (permutation(returnvalues, index)) return returnvalues;
else return null;
}
public static boolean permutation(int[] values, long index) {
return permutation(values, values.length, index);
}
private static boolean permutation(int[] values, int n, long index) {
if ((index == 0) || (n == 0)) return (index == 0);
int v = n-(int)(index % n);
int temp = values[n];
values[n] = values[v];
values[v] = temp;
return permutation(values,n-1,index/n);
}