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」、またはその他の 2 つの異なる値である可能性があります。)

これは再帰の良い候補のように思えますが、それは現時点では単なる感覚です。これまでの私の努力はすべて最適とは言えませんでした。* 別の言語を使用する以外に、良いアプローチについて何か考えはありますか?

* 例: 0 から (2^input)-1 までループします。数値を [入力] 桁のバイナリ値として解釈します。2 進数を使用して部分配列を生成します。ブレア。

編集:一般化された反復ソリューションを提示する

public enum アイテム {

   ITEM1、ITEM2、...; // 必要なだけ

   private static final int ITEM_COUNT = values().length;

   public static Item[][] allCombinationsOfSize(intのコンボサイズ) {

      int arraySize = (int) Math.pow(ITEM_COUNT,omboSize);
      アイテム配列[][] = 新しいアイテム[配列サイズ][];

      for ( int n = 0 ; n < 配列サイズ ; ++n ) {
         array[n] = nthSubarray(n, コンボサイズ);
      }

      配列を返します。
   }

   private static Item[] nthSubarray(int n, int コンボサイズ) {

      アイテムのコンボ[] = 新しいアイテム[コンボサイズ];

      for ( int i = コンボサイズ - 1 ; i >= 0 ; --i ) {
         コンボ[i] = Item.values()[n % ITEM_COUNT];
         n /= ITEM_COUNT;
      }

      リターンコンボ;
   }
}

allCombinationsOfSize が探している方法だと思います。私はまだ、もっとエレガントなものを見逃しているのではないかとこっそり疑っています。それにもかかわらず、上記により、JUnitテストでこれを書くことができます...

for ( 信号信号[] : Signal.allCombinationsOfSize(pinCount) ) {
   assertEquals(
      cls.getSimpleName() + "結果",
      expectedResultFor(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

決定はコードに基づいています - 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 に答える
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 に答える