[英]Combination algorithm Java
I'm trying to write a function: private static ArrayList<boolean[]> Combo(int i, int j)
where it'd be a sort of "concrete" implementation of iCj
in math:我正在尝试编写 function:
private static ArrayList<boolean[]> Combo(int i, int j)
,它是数学中iCj
的一种“具体”实现:
Combo(4,2)
would return an arraylist of {true, true, false, false}, {true, false, true, false}, {false, true, true, false}, {false, true, false, true}, {false, false, true, true}
(in no particular order). Combo(4,2)
将返回一个 arraylist {true, true, false, false}, {true, false, true, false}, {false, true, true, false}, {false, true, false, true}, {false, false, true, true}
(不分先后)。
Currently, I've got a recursive algorithm like this:目前,我有一个这样的递归算法:
private static ArrayList<boolean[]> Combo(int i, int j) {
ArrayList<boolean[]> k = new ArrayList<boolean[]>();
if (i == 1 && j == 0) {
k.add(new boolean[]{false});
} else if (i == 1 && j ==1) {
k.add(new boolean[]{true});
} else if (j>i) {
;
} else {
ArrayList<boolean[]> a1 = Combo((byte) i/2,1);
ArrayList<boolean[]> a2 = Combo((byte) i/2,2);
ArrayList<boolean[]> a3 = Combo((byte) i/2,3);
ArrayList<boolean[]> a4 = Combo((byte) i/2,4);
ArrayList<boolean[]> a5 = Combo((byte) i/2,5);
ArrayList<boolean[]> a6 = Combo((byte) i/2,6);
ArrayList<boolean[]> a7 = Combo((byte) i/2,7);
ArrayList<boolean[]> a8 = Combo((byte) i/2,8);
ArrayList<boolean[]> a9 = Combo((byte) i/2,9);
k.addAll(merge(a1,a9,j));
k.addAll(merge(a2,a8,j));
k.addAll(merge(a3,a7,j));
k.addAll(merge(a4,a6,j));
k.addAll(merge(a5,a5,j));
}
return k;
}
private static ArrayList<boolean[]> merge(ArrayList<boolean[]> a1, ArrayList<boolean[]> a2, int tot) {
ArrayList<boolean[]> k = new ArrayList<boolean[]>();
for (boolean[] b : a1) {
for (boolean[] b1: a2) {
boolean[] c = new boolean[tot];
for (int i = 0 ; i< b.length; i++) {
c[i] = b[i];
}
for (int i = b.length; i<b.length+b1.length; i++) {
c[i] = b1[i-b.length];
}
k.add(b);
}
}
return k;
}
But I'm getting Exception in thread "main" java.lang.StackOverflowError
on line 129.但是我在第 129 行
Exception in thread "main" java.lang.StackOverflowError
。
Can anyone please help me optimize this?谁能帮我优化一下?
Jave method names should always start with a lower case letter. Jave 方法名称应始终以小写字母开头。
You should also use a java.util.List
as a method return value.您还应该使用
java.util.List
作为方法返回值。
I don't like writing recursive code, so I wrote an iterative solution.我不喜欢写递归代码,所以我写了一个迭代解决方案。 I used a bit trick I learned a while back to generate all combinations.
我使用了我不久前学到的一些技巧来生成所有组合。 The bit patterns of all the integers from zero to 2^N give all the combinations of N length.
从零到 2^N 的所有整数的位模式给出了 N 长度的所有组合。
In this code, I test for the number of true values you're seeking.在这段代码中,我测试了您正在寻找的真实值的数量。
Here are my test results for 4,2 and 6,2.这是我对 4,2 和 6,2 的测试结果。 I formatted the results to fit in the answer.
我对结果进行了格式化以适合答案。
[[true, true, false, false], [true, false, true, false],
[false, true, true, false], [true, false, false, true],
[false, true, false, true], [false, false, true, true]]
[[true, true, false, false, false, false],
[true, false, true, false, false, false],
[false, true, true, false, false, false],
[true, false, false, true, false, false],
[false, true, false, true, false, false],
[false, false, true, true, false, false],
[true, false, false, false, true, false],
[false, true, false, false, true, false],
[false, false, true, false, true, false],
[false, false, false, true, true, false],
[true, false, false, false, false, true],
[false, true, false, false, false, true],
[false, false, true, false, false, true],
[false, false, false, true, false, true],
[false, false, false, false, true, true]]
Here's the complete runnable code.这是完整的可运行代码。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CombinationAlgorithm {
public static void main(String[] args) {
CombinationAlgorithm ca = new CombinationAlgorithm();
List<boolean[]> comboList = ca.combo(4, 2);
ca.printList(comboList);
comboList = ca.combo(6, 2);
ca.printList(comboList);
}
public List<boolean[]> combo(int elementCount, int trueCount) {
List<boolean[]> comboList = new ArrayList<>();
if (elementCount < trueCount) {
// Return empty list
return comboList;
}
int limit = (int) Math.pow(2.0, elementCount);
for (int index = 0; index < limit; index++) {
if (Integer.bitCount(index) == trueCount) {
boolean[] values = new boolean[elementCount];
for (int bit = 0; bit < elementCount; bit++) {
if (getBit(index, bit) == 0) {
values[bit] = false;
} else {
values[bit] = true;
}
}
comboList.add(values);
}
}
return comboList;
}
private int getBit(int value, int bit) {
return (value >> bit) & 1;
}
private void printList(List<boolean[]> comboList) {
System.out.print("[");
for (int index = 0; index < comboList.size(); index++) {
boolean[] values = comboList.get(index);
System.out.print(Arrays.toString(values));
if (index < (comboList.size() - 1)) {
System.out.print(", ");
}
}
System.out.println("]");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.