我想编写一个运行类似这样的Java方法:
input 1, output { {0}, {1} } input 2, output { {0, 0}, {0, 1}, {1, 0}, {1, 1} } input 3, output { {0, 0, 0}, {0, 0, 1}, {0, 1, 0}, ... {1, 1, 1} } ...
(我在示例中使用0和1表示简洁;最低级别的子元素可能是HIGH和LOW,'A'和'Z',或任何其他两个不同的值。)
这对于递归感觉是一个很好的候选者,但这只是一种感觉。到目前为止,我所有的努力似乎都不是最理想的。*除了使用不同的语言之外,还有任何关于良好方法的想法吗?
*例如:循环0到(2 ^输入)-1;将数字解释为[input] - 数字二进制值;使用二进制数字生成子数组。 Bleah
编辑:提出广义迭代解决方案
public enum Item { ITEM1, ITEM2, ...; // As many as needed private static final int ITEM_COUNT = values().length; public static Item[][] allCombinationsOfSize(int comboSize) { int arraySize = (int) Math.pow(ITEM_COUNT, comboSize); Item array[][] = new Item[arraySize][]; for ( int n = 0 ; n < arraySize ; ++n ) { array[n] = nthSubarray(n, comboSize); } return array; } private static Item[] nthSubarray(int n, int comboSize) { Item combo[] = new Item[comboSize]; for ( int i = comboSize - 1 ; i >= 0 ; --i ) { combo[i] = Item.values()[n % ITEM_COUNT]; n /= ITEM_COUNT; } return combo; } }
我相信allCombinationsOfSize是我正在寻找的方法。我仍然怀疑自己错过了一些更优雅的东西。不过,上面允许我在我的JUnit测试中写这个......
for ( Signal signals[] : Signal.allCombinationsOfSize(pinCount) ) { assertEquals( cls.getSimpleName() + " result", expectedResultFor(cls, signals), actualResultFor(cls, signals) ); }
......这是相当简单的。
答案 0 :(得分:1)
这是一个递归解决方案:
class Test {
private static Object[][] createArray(int n, Object[] values)
{
Object[][] result = null;
int m = values.length;
if (n == 1)
{
result = new Object[m][1];
for (int i = 0; i < m; ++i)
result[i][0] = values[i];
}
else
{
Object[][] array = createArray(n - 1, values);
int l = array.length;
result = new Object[m * l][n];
for (int i1 = 0; i1 < m; ++i1)
{
for (int i2 = 0; i2 < l; ++i2)
{
int i = i1 * l + i2;
for (int j = 0; j < n; ++j)
result[i][j] = j == 0 ? values[i1] : array[i2][j - 1];
}
}
}
return result;
}
private static void printArray(Object[][] array)
{
System.out.println("{");
for (int i = 0; i < array.length; ++i)
{
System.out.print(" {");
for (int j = 0; j < array[0].length; ++j)
System.out.printf(" %s", array[i][j].toString());
System.out.println(" }");
}
System.out.println("}");
}
public static void main(String[] args) {
Object[] values = {'a', 'b', 'c'};
for (int n = 1; n <= 3; ++n)
{
System.out.printf("n = %d:\n", n);
Object[][] array = createArray(n, values);
printArray(array);
System.out.println();
}
}
}
输出:
n = 1:
{
{ a }
{ b }
{ c }
}
n = 2:
{
{ a a }
{ a b }
{ a c }
{ b a }
{ b b }
{ b c }
{ c a }
{ c b }
{ c c }
}
n = 3:
{
{ a a a }
{ a a b }
{ a a c }
{ a b a }
{ a b b }
{ a b c }
{ a c a }
{ a c b }
{ a c c }
{ b a a }
{ b a b }
{ b a c }
{ b b a }
{ b b b }
{ b b c }
{ b c a }
{ b c b }
{ b c c }
{ c a a }
{ c a b }
{ c a c }
{ c b a }
{ c b b }
{ c b c }
{ c c a }
{ c c b }
{ c c c }
}
答案 1 :(得分:0)
递归方法应该有效。这应该给你一个粗略的想法。
public class Main {
public static void main(String[] args) throws Exception {
final int input = 6;
final byte[] array = new byte[input];
final List<byte[]> arrays = recurse (array, input - 1);
for (final byte[] a : arrays) {
print(a);
}
}
private static void print(final byte[] array) {
final StringBuilder buf = new StringBuilder ("{");
for(final byte b : array) {
if (buf.length() > 1) {
buf.append (", ");
}
buf.append (b);
}
buf.append ("}");
System.out.println(buf);
}
private static List<byte[]> recurse(byte[] array, int input) {
if (input > 0) {
final List<byte[]> subArr1 = recurse (array, input - 1);
array[array.length - input - 1] = 1;
final List<byte[]> subArr2 = recurse (array, input - 1);
return sumList (subArr1, subArr2);
}
else {
final byte[] arr1 = Arrays.copyOf(array, array.length);
final byte[] arr2 = Arrays.copyOf(array, array.length);
arr2[array.length - 1] = 1;
return Arrays.asList(arr1, arr2);
}
}
private static List<byte[]> sumList(List<byte[]> subArr1,
List<byte[]> subArr2) {
final List<byte[]> result = new ArrayList<byte[]> (subArr1.size() + subArr2.size());
result.addAll(subArr1);
result.addAll(subArr2);
return result;
}
}
并为它fiddle。
答案 2 :(得分:0)
决定基于代码 - List of all binary combinations for a number in Java
public static void main(String args[]) throws Exception {
int value = 4;
populate(value);
}
public static List<List<Integer>> populate(int value) {
List<List<Integer>> ret = new ArrayList<List<Integer>>();
for (int i = 0; i < Math.pow(2, value); i++) {
List<Integer> intermediate = new ArrayList<Integer>();
StringBuilder binary = new StringBuilder(Integer.toBinaryString(i));
for (int j = binary.length(); j < value; j++) {
binary.insert(0, '0');
}
System.out.println(binary);
for (int k=0; k<binary.length(); k++)
{
intermediate.add(Integer.valueOf("" + binary.charAt(k)));
}
ret.add(intermediate);
}
System.out.println(ret);
return ret;
}