• ベストアンサー

x重入れ子の実装方法について

■やりたいこと: arrayA, arrayB, arrayCの配列から毎回それぞれ1つずつ取り出し、すべてのパタンをプリントする。 ■入れ子の階層が既知の場合: for文を入れ子にしていけばいいのですが(下記サンプルのように) ■入れ子の階層が未知な場合: どのように実装すればよいか、わかりません。 どなたかアドバイスいただけますか? ----------------------------- String[] arrayA = {"a1", "a2", "a3"}; String[] arrayB = {"b1", "b2"}; String[] arrayC = {"c1", "c2", "c3", "c4"}; int count = 1; for (int a = 0; a < arrayA.length; a++) { for (int b = 0; b < arrayB.length; b++) { for (int c = 0; c < arrayC.length; c++) { System.out.println(count + " : " + arrayA[a] + "-" + arrayB[b] + "-" + arrayC[c]); count += 1; } } } ------------------------ 上記ソースの出力: 1 : a1-b1-c1 2 : a1-b1-c2 3 : a1-b1-c3 以下省略

  • Java
  • 回答数2
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

アドバイスというか、ソースを書いてしまいました。効率は無視しています。 再帰を考えるとわかりやすく書けるかも知れませんよ。 import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Combination{ public static void main(String[] args) { String[] arrayA = {"a1", "a2", "a3"}; String[] arrayB = {"b1", "b2"}; String[] arrayC = {"c1", "c2", "c3", "c4"}; List<List<String>> arrays = new ArrayList<List<String>>(); arrays.add(Arrays.asList(arrayA)); arrays.add(Arrays.asList(arrayB)); arrays.add(Arrays.asList(arrayC)); List<List<String>> result = new ArrayList<List<String>>(); combination(arrays, new ArrayList<String>(), result); for(int i = 0; i < result.size(); i++){ List<String> ls = result.get(i); System.out.print((i + 1) + ":"); for(int k = 0; k < ls.size(); k++){ System.out.print(ls.get(k) + (k < ls.size() - 1 ? "-" : "")); } System.out.println(); } } public static <T> void combination(List<List<T>> sources, List<T> choosed, List<List<T>> result){ if(sources.size() == 0){ result.add(choosed); }else{ for(int i = 0; i < sources.get(0).size(); i++){ List<T> newChoosed = new ArrayList<T>(choosed); newChoosed.add(sources.get(0).get(i)); combination(sources.subList(1, sources.size()), newChoosed, result); } } } }

hasekyou
質問者

お礼

ありがとうございました。大変勉強になりました。

その他の回答 (1)

  • HarukaV49
  • ベストアンサー率53% (48/89)
回答No.2

入れ個数を可変するようにはなっていませんが、 任意個数の文字列配列の順列を書き下すという 仕様は満たしていると思います。  public static void main(String[] args) {   String[] arrayA = {"a1", "a2", "a3"};   String[] arrayB = {"b1", "b2"};   String[] arrayC = {"c1", "c2", "c3", "c4"};      for(int i=0; i<getPermutationCount(arrayA, arrayB, arrayC); i++) {    System.out.printf( "%d %s\n", i, getPermutation(i, arrayA, arrayB, arrayC) );   }  }  /**   * index番目の順列を返します。   * @param index 順列順位   * @param args 順列を求めたい任意個数の任意長文字列配列   * @return 順列文字列   */  private static String getPermutation( int index, String[]... args ) {   String s = "";   for(int i=0, n=args.length; i<n; i++) {    s += (i==0 ? "" : "-") + choose( index, i, args );   }   return s;  }  /**   * index番目の順列の文字列配列digit番の要素を抽出します   * @param index 順列順位   * @param digit 文字列配列の順位   * @param args 順列を求めたい任意個数の文字列配列   * @return 1個の順列文字列   */  private static String choose( int index, int digit, String[]... args ) {   String s = args[digit][ index / getPermutationCount(digit+1, args ) % args[digit].length ];   return s;  }  /**   * digit番目までの順列個数   * @param digit 文字列配列の順位   * @param args 任意個数の文字列配列   * @return 順列個数   */  private static int getPermutationCount( int digit, String[]... args ) {   int count = 1;   for(int i=digit, n=args.length; i<n; i++) {    count *= args[i].length;   }   return count;  }  /**   * 順列総数を求めます   * @param args 任意個数の文字列配列   * @return 順列数   */  private static int getPermutationCount( String[]... args ) {   return getPermutationCount( 0, args );  }

関連するQ&A

  • Javaのオーバーロードを使った問題

    class Book{ String title, size; int price; Book(String title, String size, int price){ this.title = title; this.size = size; this.price = price; } public String info(){ return title + " " + size; } public String info(String title){ return title + " " + size + " " + price +"円"; } public int info(String title, String size){ return price; } } ________________________________________________________ class Book_test{ public static void main(String[] args){ String[] title = {"図鑑","参考書","雑誌","地図"}; String[] size = {"B4", "A5", "A4", "A3"}; int[] price={4500, 1800, 600, 1400}; Book[] b = new Book[4]; for(int i=0; i<b.length; i++){ b[i] = ****; } for(int i=0; i<b.length; i++){ System.out.println(***); } for(int i=0; i<b.length; i++){ System.out.println(***); } for(int i=0; i<b.length; i++){ System.out.println(***); } } } 実行結果は、以下の通り 図鑑 B4 参考書 A5 雑誌 A4 地図 A3 図鑑 B4 4500円 参考書 A5 1800円 雑誌 A4 600円 地図 A3 1400円 4500 1800 600 1400 このように表示するために、javaのソースコードを書かなくてはならないのですが、***の部分に何を入れれば良いのか分かりません。 特に、for文の部分です。 classが苦手なので分かりやすく教えていただけると幸いです。

    • ベストアンサー
    • Java
  • 【初心者です】最大値の箇所

    import java.io.*; public class ex41b { public static void main(String[] args) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int[] a = new int[100]; int count = 0; while(count < a.length) { System.out.print(count + "> "); int v = (new Integer(in.readLine())).intValue(); if(v == 0) break; a[count] = v; ++count; } int max = a[0]; for(int i = 1; i<a.length; i++) { if(a[i]>max) max = a[i]; } System.out.println("max: " + max); System.out.println("pos: " + ****); } } このソースで、最大値と最大値が何番目かを出力したいのですが、 最後の****に何を当てはめればいいのかが分かりません。 いくつかやってみたのですが、よく分かりませんでした。 よろしくお願いします。

    • ベストアンサー
    • Java
  • コマンドライン引数を用いて。

    コマンドライン引数を用いて足し算をさせるプログラムです。 class goukei{ public static void main(String args[]){ int i, count; int sum = 0; int a[]; count = args.length; for(i=0; i<args.length; i++){ int arg_i = Integer.parseInt(args[i]); sum = sum + arg_i; } System.out.println("引数の数は" + count); System.out.println("合計は" + sum); } } と考えたのですが、もっとこうしたほうがいいという部分があれば教えてください。 一応これでできているとは思うのですがイマイチ自信がありません・・・。

    • ベストアンサー
    • Java
  • Java言語のプログラムをC言語にする場合

    次の2つのJava言語のプログラムをC言語にしたいのですが、C言語でプログラムを書いたことがありません。C言語にする場合はどう書けばいいのでしょうか? import java.io.*; public class Sort { public static void main(String[] args) { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); try{ System.out.println("整数値を入力してください"); String line = reader.readLine(); int a = Integer.parseInt(line); String line2 = reader.readLine(); int b = Integer.parseInt(line2); String line3 = reader.readLine(); int c = Integer.parseInt(line3); String line4 = reader.readLine(); int d = Integer.parseInt(line4); int[] data = {a, b, c, d}; for (int i = 0; i< data.length - 1 ; i++) { for (int j = i + 1; j< data.length; j++) { if(data[i] > data[j]) { int e = data[i]; data[i] = data[j]; data[j] = e; } } } System.out.println("昇順に並べ替えると、"); for (int i = 0; i< data.length; i++) { System.out.print(data[i] + " "); } System.out.println("です。"); } catch (IOException e){ System.out.println(e); } catch (NumberFormatException e) { System.out.println("数式の形式が正しくありません。"); } } } import java.io.*; public class Yakusu { public static void main(String[] args) { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); try{ System.out.println("2つの整数値を入力してください"); System.out.print("整数A : "); String line = reader.readLine(); int a = Integer.parseInt(line); System.out.print("整数B : "); String line2 = reader.readLine(); int b = Integer.parseInt(line2); if(a%b == 0){ System.out.println("BはAの約数です"); } else { System.out.println("BはAの約数ではありません"); } } catch (IOException e){ System.out.println(e); } catch (NumberFormatException e) { System.out.println("数式の形式が正しくありません。"); } } }

  • arraycopy コンパイルエラー

    javaの勉強をしているのですが arraycopy()を使ったプログラムでエラーが出てしまいます。 class Ex97{ public static void main(String args[]){ int []a = new int[10]; int []b = new int[5]; for(int i=0; i<10; i++){ a[i] = (int)(Math.random()*10); } System.arraycopy(a, 2, b, 0, 5); for(int i=0; 0<a.length-1; i++){ System.out.println(a[i]); } System.out.println(""); for(int i=0; 0<b.length; i++){ System.out.println(b[i]); } } } /*メッセージ Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10 at Ex32.main(Ex32.java:13) */ このプログラムはaの3番目の要素から5つ分の内容をbへコピーする というものです。 ご回答よろしくお願いします。

    • ベストアンサー
    • Java
  • perlでの配列について

    配列の配列について教えてください。 以下のようなテキストから値を取得し、A,B,Cの値をそれぞれ別の配列に格納し、A,B,Cの平均値を出す処理を行っているとします。 ----- A=100 B=200 C=300 A=110 B=210 : ----- 現状、以下のような状態です。 @arrayA=(); @arrayB=(); @arrayC=(); : (テキストを読み込み) : ・読み込んだ行がA=XXXならarrayAにpush push(@arrayA,"100"); ・読み込んだっ行がB=XXXならarrayBにpush push(@arrayB,"100"); : (各配列の要素の平均値を出す) このやり方だと、グループが増えるとそのまま行数が増えて冗長なので、グループごとの配列を1つの配列にまとめたいのです。 Webで初期値を入れた形で説明しているのはよくみるのですが、今回のように空の配列に値をいれていくにはどうすればよいのでしょうか?(そもそも宣言の仕方もわかりません)。 また、配列の配列?とした場合、以下のような処理はできるのでしょうか? (1)配列の1つ目の要素(の配列)にpushする(現状でのarrayAにpushに該当) push(@arrayAll[0],"test");

  • javaの問題

    import java.util.Scanner; class test6{ static void printArray(int[] a) { for(int i=0;i<a.length;i++) System.out.print(String.format("%1$6s", (a[i]+" "))); System.out.println(); } static void printArray(int[][] a) { for(int[] i:a) { for(int j:i) System.out.print(String.format("%1$6s",(j+"\t"))); System.out.println(); } } public static void main(String[] args) { int[] a = {12,536,-8,7}; int[][] c = {{32,-1,32,45,67}, {535,99999,2}, {2,5,-123,9}}; printArray(a); printArray(c); } } このプログラムを表示するとこのようになるのですが、 12 536 -8 7 32 -1 32 45 67 535 99999 2 2 5 -123 9 これに一工夫加えて見やすくしたいです。 このような形にするのはどのようにすればよいのでしょうか + + | 32 -1 45 67 | | 535 99999 2 | | 2 5 -123 9 | + +

  • 入れ子の構造体について

    例えば、入れ子の構造体を1つ使いたい場合、 struct bbb{ int b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; と書くと、「dt.a.b = 10」とやれば、値等を設定できると思いますが、 入れ子の構造体を2つ使いたい場合も、同じように書けるのでしょうか? struct ccc{ int c; }; struct bbb{ struct ccc b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; dt.a.b.c = 10; と書けるのでしょうか?こんがらがってしまって、どう書いていいのか・・。 2つでも出来るのであれば、コードの書き方を教えて頂けませんか?

  • 配列のソートと削除

    String型のstrToRemoveで与えられた文字列を配列から探し、あればそれ以降の配列の数字をすべて左にシフトします。 なので配列の大きさは1小さくなります。その結果の配列をreturnで返します。 例) ({"A","B","C","D","B"}, "B")配列1にBがあるのでそれ以降の文字列をすべて左にシフト→ {"A","C","D","B"} ({"A","B","C","D","B"}, "A") 配列0にAがあるのでそれ以降の文字列を左にシフト→ {"B","C","D","B"} プログラムは以下のように組みました。 public class ArrayFun { public String[] oneRemoved(String[] array, String strToRemove) { int count = 0; for (int i = 0; i < array.length; i++) {      if (strToRemove.equals(array[i]) && count == 0) {        for (int j = i; j < array.length - 1; j++) {          array[j] = array[j + 1];        }          count++;      } }      array = new String[array.length - 1];      array[array.length - 1] = null;      return array; } } ちなみにcountは、一度シフトすればもう同じ文字列がそれ以降の配列にあってもシフトはしないので、countでシフトしたかどうかを判断しようと思い付けました。 これでテストメソッドも作るのですが、 import static org.junit.Assert.*; import org.junit.Test; public class ArrayFunTest { @Test public void testoneRemoved() { ArrayFun af = new ArrayFun(); String[] a1 = {"A","B","C","D","B" };//元の配列 String[] a2 = {"A","BB","CCC","DDD","B"};//元の配列 String[] a3 = {"B","C","D","B"};//シフト後の配列 String[] a4 = {"A","BB","CCC","DDD","B"};//シフト後の配列 assertEquals(a3, af.oneRemoved(a1, "A")); assertEquals(a4, af.oneRemoved(a2, "NotHere")); } } 以上のように組むと、assertEqualsの真ん中に黒線が入って自動的に@SuppressWarnings("deprecation")が加えられてしまいます。 実行結果は、({"A","B","C","D","B"}, "A") の例だと、配列0にB が入るはずがnullになっている、とエラーがでます。 どのようにしたら正常に動かせるでしょうか?宜しくお願いします。

    • ベストアンサー
    • Java
  • 配列のインデックス番号を返したいが

    インデックス番号を返したい x[0]=1 x[1]=2 x[2]=3 x[3]=3 x[4]=5 の場合で探す(返す)値を3とした場合⇒2,3と値が返るようにしたい import java.util.*; class Test7_23 { static int[] arraySrchIdx(int[] a,int x){ int idx = 0; for(int i=0;i<a.length;i++){ //A if(a[i]==x){ a[i] = i; idx++; } else{ a[i] = 0; } } for(int i=0;i<a.length;i++) //B System.out.println(a[i]); int[] b = new int[idx]; for(int i=0;i<a.length;i++){ if(a[i] != 0) for(int j=0;j<idx;j++) b[j]=a[i]; } for(int i=0;i<idx;i++) System.out.println("b["+i+"]="+b[i]); return b; } public static void main(String[]args){ Scanner std = new Scanner(System.in); System.out.print("配列の要素数は:"); int n = std.nextInt(); int[] x = new int[n]; for(int i=0;i<n;i++){ System.out.print("x["+i+"]="); x[i] = std.nextInt(); } System.out.print("探す値:"); int a = std.nextInt(); int[] b = arraySrchIdx(x,a); for(int i=0;i<b.length;i++){ System.out.println(b[i]); } } }

専門家に質問してみよう