如何使用变量子数组填充Java数组?

时间:2012-11-20 00:03:58

标签: java multidimensional-array populate

我想编写一个运行类似这样的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)
   );
}

......这是相当简单的。

3 个答案:

答案 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;
}