二维数组列表的排列
Posted
技术标签:
【中文标题】二维数组列表的排列【英文标题】:Permutation of a 2 dimensional arraylist 【发布时间】:2013-10-29 08:38:08 【问题描述】:我正在尝试创建一个二维数组列表,其中填充了每个可能的组合,比如递归地说 1、2、3、4。 没有翻倍。
例如。 1,0,0 2,0,0 3,0,0 4,0,0 1,2,0 1,3,0 1,4,0 1,2,3 等等……
到目前为止我有
//this gives me all my numbers
for(int i =0;i<arraySize;i++)
index[i] = i;
// and is the part that make the combinations
for(int i = 0;i<arraySize;i++)
for(int x = 0;x<k;x++)
combinations.get(i).set(x, index[i]);
编辑: 我也不想打印结果我想将结果存储在二维数组中
【问题讨论】:
你有一个ArrayList
并尝试获取其元素之间的所有排列?
您想要一个“让我们说 1,2,3,4 的可能组合”的列表,但在您的示例中,您输入了: 1,0,0 。由于 0 不在原始列表中,因此它也不应该在输出中吗? :)
@Sephy 我有一个数组“index”,无论我的对象数组的长度是多少,它都是 1,我有一个组合,它是一个二维数组列表,我想用所有的“索引”的可能组合。
@user2777005 我试图表明我不想要 111 112 113 我需要 1 2 3 零将为空
这似乎更像是一个计数器而不是一个排列——也就是说,您允许“1”或“12”等“不完整”的词。是否允许使用诸如“21”之类的词,或者您是否强制要求数字必须按升序排列?
【参考方案1】:
另一个非递归选项。我对(部分)排列使用“单词”,对数字使用“符号”:
/**
* Expands the set of existing words by adding non-repeated symbols to their right
* @param symbols to choose from
* @param existing words (may include the empty word)
* @param expanded result
*/
public static void expand(ArrayList<Integer> symbols,
ArrayList<ArrayList<Integer>> existing,
ArrayList<ArrayList<Integer>> expanded)
for (ArrayList<Integer> prev : existing)
Integer last = prev.isEmpty() ? null : prev.get(prev.size()-1);
for (Integer s : symbols)
if (last == null || s > last)
ArrayList<Integer> toAdd = new ArrayList<>(prev);
toAdd.add(s);
expanded.add(toAdd);
public static void main(String[] args)
ArrayList<Integer> symbols = new ArrayList<>(
Arrays.asList(new Integer[]1, 2, 3, 4));
ArrayList<ArrayList<Integer>> prev = new ArrayList<>();
ArrayList<ArrayList<Integer>> next = new ArrayList<>();
ArrayList<ArrayList<Integer>> aux;
ArrayList<ArrayList<Integer>> output = new ArrayList<>();
// add empty
prev.add(new ArrayList<Integer>());
// expand empty, then expand that expansion, and so on and so forth
for (int i=0; i<symbols.size(); i++)
expand(symbols, prev, next);
output.addAll(next);
aux = prev; prev = next; next = aux;
next.clear();
// print result (note: only for debugging purposes)
for (ArrayList<Integer> o : output)
for (int i : o) System.out.print(i); System.out.println();
并且输出与原始问题匹配(不是似乎要求实际排列,至少根据提供的示例):
1
2
3
4
12
13
14
23
24
34
123
124
134
234
1234
【讨论】:
请注意,扩展规则可以调整以产生一个实际的计数器(“所有单词,甚至不完整的,都有允许的数字”)。我目前正在执行升序,因为所有提供的示例都是升序...... 这是我想要达到的结果。我想要二维数组或数组列表中的所有这些组合,这样我就可以将这些值单独用作指向对象数组中值索引的指针output
ArrayList 正是您所要求的 output.get(rowIndex).get(colIndex)
产生对应于特定行/列索引对的整数。请注意,并非所有行(= 可能的组合)都具有相同的长度。【参考方案2】:
您要查找的内容称为Backtracking。这种解决问题的技术很大程度上基于递归。基本上,你设置你的第一个数字,然后只考虑其他数字作为一个子问题,当找到第一个数字集的每个排列时,这个第一个数字会增加,等等。
您也可以直接使用 4 个 for 循环来解决问题,但解决方案不会扩展到 4 个数字以外的任何东西。
您的解决方案将类似于以下内容。它将输出 4 个数字的每个排列。
public class PermutationDemo
public static void main(String[] args)
int[] array = new int[4];
for (int i=0; i<array.length; i++)
reset(array, i);
solve(array, 0);
private static void solve(int[] array, int i)
if (i == array.length)
print(array);
return;
for (int k=0; k<4; k++)
solve(array, i+1);
makeMove(array, i);
reset(array, i);
private static void makeMove(int[] array, int i)
array[i] += 1;
private static void reset(int[] array, int i)
array[i] = 1;
private static void print(int[] array)
for (int i=0; i<array.length; i++)
System.out.print(array[i] + " ");
System.out.println("");
结果是:
PS [10:21] Desktop > java PermutationDemo
1 1 1
1 1 2
1 1 3
1 1 4
1 2 1
1 2 2
1 2 3
1 2 4
1 3 1
1 3 2
1 3 3
1 3 4
1 4 1
1 4 2
1 4 3
1 4 4
2 1 1
2 1 2
2 1 3
2 1 4
2 2 1
2 2 2
2 2 3
2 2 4
2 3 1
2 3 2
2 3 3
2 3 4
2 4 1
2 4 2
2 4 3
2 4 4
3 1 1
3 1 2
3 1 3
3 1 4
3 2 1
3 2 2
3 2 3
3 2 4
3 3 1
3 3 2
3 3 3
3 3 4
3 4 1
3 4 2
3 4 3
3 4 4
4 1 1
4 1 2
4 1 3
4 1 4
4 2 1
4 2 2
4 2 3
4 2 4
4 3 1
4 3 2
4 3 3
4 3 4
4 4 1
4 4 2
4 4 3
4 4 4
【讨论】:
这几乎是我想要做的,但在二维数组中,因为我需要将组合与对象数组的索引进行比较,以找到最佳的项目组合。【参考方案3】:作为关于 java 中集合操作的一般提示,我建议您查看 Google Guava 中的实用程序类,它为您完成了大部分繁重工作,并确保您没有遇到性能问题理解。
然后,下一步是寻找适合您需要的方法。例如,Collections2.permutations 可能就是您要查找的内容。
最后,如果您想自己实现这个作为算法练习,您可以查看 guava 或 Groove Collection API 的源代码以获取想法。
【讨论】:
以上是关于二维数组列表的排列的主要内容,如果未能解决你的问题,请参考以下文章