Java从多个数组生成所有可能的排列
我有一个 ArrayList
,其中包含未定义数量的 int[]
。
输入示例(请注意,文本“= Condition 0/1/2”不是 ArrayList 的一部分)。
= Condition 0
[2, 6], [3, 7]
= Condition 1
[1, 3], [2, 4], [2, 3]
= Condition 2
[1, 2]
(A 部分) 我希望创建所有 int[] 对的所有可能排列 (ArrayList
,第 9 行),前提是每个条件只有一对,例如,第一个来自 C0,第二个来自
[2,6], [1,3], [1,2]
[2,6], [2,4], [1,2]
[2,6], [2,3], [1,2]
[3,7], [1,3], [1,2]
and so on...
(B 部分) 一旦我有了所有可能的排列 (2^numOfConditions),我将组合ArrayList
public static Set<Integer> findOptimalPairs(ArrayList<ArrayList<int[]>> conditions) {
// A
ArrayList<ArrayList<int[]>> listOfConditions = new ArrayList<>();
for (int i = 0; i < conditions.get(0).size(); i++) {
for (int j = 0; j < conditions.get(1).size(); j++) {
for (int k = 0; k < conditions.get(2).size(); k++) {
ArrayList<int[]> option = new ArrayList<>();
option.add(conditions.get(0).get(i));
option.add(conditions.get(1).get(j));
option.add(conditions.get(2).get(k));
listOfConditions.add(option);
}
}
}
//A
//B
Set<Integer> best = new HashSet<>();
for (ArrayList<int[]> pairs : listOfConditions) {
Set<Integer> curr = new HashSet<>();
for (int[] pair : pairs) {
for (int num : pair) curr.add(num);
}
best = (best.size() > 0 && best.size() <= curr.size()) ? best : curr;
}
return best;
//B
}
PART B 工作得很好,但是我如何修改 A,以便它能够处理与 3 不同的条件大小?我现在对值 (0,1,2) 进行了硬编码,因为我不知道如何针对更大的集合修改它。
我已经花了这么多时间在这个问题上,我觉得答案并不是特别困难。
Java 11,如果这很重要的话。谢谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
基本上,您创建一个一维数组,该数组将在每个索引处保存该集合的 int[] 数组的数量。
然后,您创建一个相同大小的附加一维数组,并使用存储的大小进行“计数”,以了解何时重置每个计数器。如果您曾经用其他基数进行过计数,您应该确切地知道我的意思,除非我们将左侧视为最低有效数字。
例如,对于您的数据集:
有三行,因此您将创建一个大小为 3 的数组并存储每组中的项目数。
这里我硬编码只是为了展示这个过程。在实际代码中,它将根据传入的数据是动态的:
现在我们开始一个相同大小的新数组,所有值都为零(无论如何这是默认值):
从左侧开始,我们递增中的值该索引直到我们达到“设置大小”。每当我们点击“设置大小”时,我们都会将该索引重置为零,并将该列向右递增(对每列重置和向右递增遵循相同的规则)。
这些将是生成的序列:
这些数字表示您应该从该组合中的每个集合中选择 int[] 数组的索引。因此,我们只需将这些索引从输入数据集转换为相应的 int[] 数组即可。
这种方法是迭代的,不需要递归。
该代码可能如下所示:
生成的输出:
Basically you create a 1D array that will hold at each index the number of int[] arrays for that set.
Then you create an additional 1D array of the same size and you "count" using the stored sizes to know when to reset each counter. If you've ever counted in other bases you should know exactly what I mean, except we are treating the left side as the least significant digit.
For instance, with your data set of:
There are three rows, so you'd make an array of size three and store the number of items in each set.
Here I'm hard-coding just to show the process. In the actual code it will be dynamic based on the data passed in:
Now we start off a new array of the same size, with all values at zero (which is the default anyways):
Starting from the left, we increment the value in that index until we reach "set size". Whenever we hit "set size" we reset that index back to zero and increment the column to the right (following the same rule for each column of resetting and incrementing to the right).
These would be the sequences generated:
The numbers represent what index from the int[] array you should pick from each set in that combination. So then we just translate those indices to the corresponding int[] array from the input data set.
This approach is ITERATIVE, requiring no recursion.
Here's what that code might look like:
Output generated:
像这样的东西应该可以工作
在你的代码中你有循环内循环。在这里,我们使用递归调用来执行 for 循环。我试图与您当前拥有的代码进行比较。因此,当我在评论中提到 i、j、k 时,我指的是您当前如何使用它们。
Something like this should work
In your code you have loops inside loops. Here, we use recursive calls to do the for loops. I have tried to make comparisons to the code you currently have. So when I refer to i,j,k in the comments, I am referring to how you are currently using them.