0

我想编写一个 Java 方法来操作如下:

输入 1,输出 { {0},{1} }
输入 2,输出 { {0, 0}, {0, 1}, {1, 0}, {1, 1} }
输入 3,输出 { {0, 0, 0}, {0, 0, 1}, {0, 1, 0}, ... {1, 1, 1} }
...

(为了简洁,我在示例中使用 0 和 1;最低级别的子元素可能是 HIGH 和 LOW、'A' 和 'Z',或任何其他两个不同的值。)

这感觉像是一个很好的递归候选者,但这只是一种感觉。到目前为止,我所有的努力似乎都不是最理想的。* 除了使用不同的语言之外,还有什么好的方法吗?

* 例如:循环 0 到 (2^input)-1;将数字解释为 [输入] 位二进制值;使用二进制数字生成子数组。呸。

编辑:提出广义迭代解决方案

公共枚举项{

   第 1 项,第 2 项,...;// 需要多少

   私有静态最终 int ITEM_COUNT = values().length;

   公共静态项目[][] allCombinationsOfSize(int comboSize) {

      int arraySize = (int) Math.pow(ITEM_COUNT, comboSize);
      项目数组[][] = 新项目[arraySize][];

      for (int n = 0 ; n < arraySize ; ++n ) {
         数组[n] = nthSubarray(n, comboSize);
      }

      返回数组;
   }

   私有静态项目 [] nthSubarray(int n, int comboSize) {

      项目组合[] = 新项目[comboSize];

      for (int i = comboSize - 1 ; i >= 0 ; --i ) {
         组合[i] = Item.values()[n % ITEM_COUNT];
         n /= ITEM_COUNT;
      }

      返回组合;
   }
}

我相信 allCombinationsOfSize 是我正在寻找的方法。我仍然有一个偷偷摸摸的怀疑,我错过了一些更优雅的东西。尽管如此,以上内容允许我在我的 JUnit 测试中编写它......

对于(信号信号[]:Signal.allCombinationsOfSize(pinCount)){
   断言等于(
      cls.getSimpleName() + "结果",
      预期结果(cls,信号),
      actualResultFor(cls, 信号)
   );
}

...这很简单。

4

3 回答 3

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 }
}
于 2012-11-20T00:56:20.667 回答
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;
        }
    }

和一个小提琴

于 2012-11-20T00:19:39.103 回答
0

该决定基于代码 - 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;
}
于 2012-11-20T00:32:18.617 回答