2016-05-31 12 views
0

各列から1つの項目(ここではスープ、麺、トッピングのいずれかを選択)を取って、すべての組み合わせを返すアルゴリズムがあります。Javaすべての可能な組み合わせを列から検索

これを行うためのより効率的かつ動的な方法はありますか? findAllCombinationsメソッドが機能するためには、そこにいくつの列があるかを知り、それらをハードコードする必要があります。

有効な組合せ: [クレソンスープ、うどん、魚キューブ]、[スパイシースープ、ラーメン、ハム]、...

ArrayList<ArrayList<String>> listOfLists = Lists.newArrayList(); 
listOfLists.add(Lists.newArrayList("Original Soup", "Spicy Soup", "Watercress Soup", "Thai Spicy Soup", "Malaysia Spicy Soup")); 
listOfLists.add(Lists.newArrayList("Udon", "Ramen", "Egg Noodle", "Flat Rice Noodle", "Vermicelli", "Instant Noodle")); 
listOfLists.add(Lists.newArrayList("Fish Cube", "Fish Ball", "Ham", "Squid", "Seaweed")); 

ArrayList<ArrayList<String>> combo = findAllCombinations(listOfLists); 


private ArrayList<ArrayList<String>> findAllCombinations(ArrayList<ArrayList<String>> arrays){ 
    ArrayList<ArrayList<String>> combinations = new ArrayList<>(); 
    for(String item1: arrays.get(0)){ 
     for(String item2: arrays.get(1)){ 
      for(String item3: arrays.get(2)){ 
       ArrayList<String> temp = new ArrayList<String>() { 
        { 
         add(item1); 
         add(item2); 
         add(item3); 
        } 
       }; 
       combinations.add(temp); 
      } 
     } 
    } 
    return combinations; 
} 
+0

2番目の配列の最初のメンバーと3番目の配列の最初の2メンバーをスキップするのはなぜですか? – LostAndConfused

+3

@LostAndConfusedあなたは少し失われて混乱しているようです。 – shmosel

+0

@LostAndConfused彼はいません、彼は第1、第2、第3の配列 – TheBakker

答えて

2

あなたはセットのリストの代わりになるためにあなたの構造を微調整した場合リストのリストには、グアバのSets.cartesianProduct()を使用することができます。

List<Set<String>> listOfSets = Lists.newArrayList(); 
listOfSets.add(Sets.newHashSet("Original Soup", "Spicy Soup", "Watercress Soup", "Thai Spicy Soup", "Malaysia Spicy Soup")); 
listOfSets.add(Sets.newHashSet("Udon", "Ramen", "Egg Noodle", "Flat Rice Noodle", "Vermicelli", "Instant Noodle")); 
listOfSets.add(Sets.newHashSet("Fish Cube", "Fish Ball", "Ham", "Squid", "Seaweed")); 

Set<List<String>> combo = Sets.cartesianProduct(listOfSets); 

順序が重要な場合、あなたはLinkedHashSetを使用することができます。

編集:バージョン19の時点で、グアバはLists.cartesianProduct()です。これはまさにあなたが望むことを行うはずです。

+0

LinkedHashSetを使って何を意味するのか分かりません。 – PandaTank

+0

'LinkedHashSet listOfSets =新しいLinkedHashSet();'は動作しません。 – PandaTank

+0

@PandaTank私は 'listOfSets.add(new LinkedHashSet <>(Arrays.asList(" Fish Cube "、" Fish Ball "、" Ham "、" Squid "、" Seaweed "))));' – shmosel

2

あなたがGuavaを使用せず、自分でロールする必要がある/したい場合は、ここをクリックしてください(以下のコード)。

考えられるのは、リストサイズの積として組み合わせの数を計算し、次に0からnumber_of_combinations -1まで反復し、その範囲の各整数を異なる組み合わせに変換することです。

import java.util.ArrayList; 
import java.util.Arrays; 

public class Tester { 

private static ArrayList<ArrayList<String>> findAllCombinations(ArrayList<ArrayList<String>> arrays){ 
    final ArrayList<ArrayList<String>> combinations = new ArrayList<>(); 
    int combinationCount = 1; 
    for (final ArrayList<String> als : arrays) { 
     combinationCount *= als.size(); 
    } 

    for (int i = 0; i < combinationCount; i++) { 
     int combinationIndex = i; 
     final ArrayList<String> oneCombination = new ArrayList<String>(); 
     for (final ArrayList<String> als : arrays) { 
      int index = combinationIndex % als.size(); 
      oneCombination.add(als.get(index)); 
      combinationIndex = (combinationIndex - index)/als.size(); 
     } 
     combinations.add(oneCombination); 
    } 
    return combinations; 
} 

public static void main(String[] args) { 

final ArrayList<ArrayList<String>> listOfLists = new ArrayList<ArrayList<String>>(); 
listOfLists.add(new ArrayList<String>(Arrays.asList(new String[] {"Original Soup", "Spicy Soup", "Watercress Soup", "Thai Spicy Soup", "Malaysia Spicy Soup"}))); 
listOfLists.add(new ArrayList<String>(Arrays.asList(new String[] {"Udon", "Ramen", "Egg Noodle", "Flat Rice Noodle", "Vermicelli", "Instant Noodle"}))); 
listOfLists.add(new ArrayList<String>(Arrays.asList(new String[] {"Fish Cube", "Fish Ball", "Ham", "Squid", "Seaweed"}))); 

ArrayList<ArrayList<String>> combo = findAllCombinations(listOfLists); 
System.out.println(combo); 
System.out.println("Generated " + combo.size() + " combinations"); 
} 

} 
+1

OPのようですグアバを使って – shmosel

+0

はい、わかっています。しかし、ポストのタイトルに基づいて、検索でこの質問を見つけたすべての人がグアバを使用しているとは限りません。私はStackOverflow "ファウル"の場合、私の答えを削除または修正することができます。 –

+0

あなたの答えに問題はありません(それはOPのソリューションより複雑です)。私はちょうどあなたの最初の文にコメントしていた。サイドノート:1)Arrays.asList()はvarargsを受け取り、2)その結果を新しいArrayListに渡すと少し過剰ですが、OPのメソッドシグネチャを保持したい場合は*技術的に*必要です。 – shmosel

関連する問題