4

我有一個非常奇怪的問題,它有一些限制使得它很難解決。我有一個列表清單,我想做這些清單中所有項目的組合。每個項目都有一個名稱和一個值。這裏有一個例子:如何在飛行中執行組合動作

主要列表:

  • 表01:
    • 項目01:名稱:name01,值:value01
    • 項目02:名稱:name02,值:value02
  • 表02:
    • 項目01:名:姓名03,2值:value03
  • 表03:
    • 項目01:名:姓名04,2值:value04
    • 項目02:名稱:name05,值:value05

最終的結果應該像這樣的:

一些名單:

  • 項目01:name01:value01,姓名03,2:value03,姓名04,2:value04
  • 項目02:name02:value02,姓名03,2:value03,姓名04,2:value04
  • 項目03:姓名03,2:value03,姓名03,2:value03,姓名04,2:value04
  • 項目04:name01:value01,姓名03,2:value03,姓名04,2:value05
  • 項目05:name02:value02,姓名03,2:value03,姓名04,2:value05
  • 項目06:姓名03,2:value03,姓名03,2:value03,姓名04,2: value05

新列表非常包含像散列圖那樣的項目。

的約束如下:

  1. 我不能收集到新的列表和它們混合,因爲這些列表可能會很快變得非常大。
  2. 我正在使用某種類似觀察者的API,所以我需要儘快讓觀察者瞭解結果,以便我不會使用太多內存。

換句話說,這個組合生成器可能會用X數量的列表進行填充,每個列表可能包含N個項目,我必須在不使用太多內存的情況下生成它們的組合。

我不希望一次處理多於5個列表,但我希望使算法儘可能靈活地對代碼進行更改。

我正在解決java中的問題,但該算法也應該在其他語言同樣工作,因爲它可能會被翻譯。

你有什麼想法和建議嗎?

在此先感謝。

P.S.我認爲遞歸不會很好。我正在嘗試使用while循環和一些嵌套循環的想法,但想象這應該如何工作變得非常困難。

+0

你的例子不是很清楚,並且包含 - 我認爲是 - 一個錯誤。我可以推薦3個2,1和3元素列表((a,b)(c)(d,e,f))。這將導致6個解決方案(笛卡爾產品或交叉產品)。如果你喜歡,請閱讀:=(name01,value01)。但是你的例子有一些列表項目03:n3v3 n3v3 - 兩次。這不是意圖,是嗎? – 2011-02-17 01:27:06

回答

2

所以這是笛卡爾的產品,你後?

假設3個列表,包含2個,1個和3個元素。你會在2 * 1 * 3個=組合6.結束(摘要:A * B * ... * I)

現在你採取6個號碼從0到5

void getCombiFor (int i, List <List <Integer>> li) 
{ 
    if (li.length > 0) 
    { 
     int idx = i % li.get (0).size();   
     System.out.print (li.get (0).get(idx));     
     getCombiFor (i - idx, li.remove (0)); 
    } 
    System.out.println(); 
} 
// pseudocodeline: 
List li = List (List ('a', 'b'), List ('c'), List ('d', 'e', 'f')) 
for (int i = 0; i < 6; ++i) 
{ 
    getCombiFor (i, li); 
} 

示例:

Lists = ((a,b), (c), (d,e,f)) 
acd 
bcd 
acf 
bcf 
ace 
bce 
0

如何創建索引數組,每個給定列表一個?可以通過依次對每個列表執行get()來讀取當前組合。每個指數將在零 - 然後前進到你實際上做下組合

index[0]++; 
if (index[0] >= list[0].size()) { 
    index[0] = 0; 
    index[1]++; 
    if (index[1] >= list[1].size()) { 
     ... 
    } 
} 

+0

每個索引**將在0開始**,obvs。 – 2011-02-17 00:52:52

0

爲什麼不(打開嵌套if的成迭代作爲練習留給讀者。)你實際上做了一個hashmap?

Map<String,Map<String,String>> mainMap = new HashMap<String,Map<String,String>>(); 

for(List l : lists) { 
    for(Data d : l) { 
     String item = d.item; 
     String name = d.name; 
     String value = d.value; 

     Map<String,String> itemMap = mainMap.get(item); 
     if(item == null) { 
      itemMap = new HashMap<String,String>(); 
      mainMap.put(item,itemMap); 
     } 
     itemMap.put(name,value); 
    } 
} 

以後,你想得到給定名稱的所有值,不管是什麼項目?

List<String> getValuesForName(String name) { 
    List<String> list = new LinkedList<String>(); 
    for(Map<String,String map : mainMap) { 
     String value = map.get(name); 
     if(value != null) list.add(value); 
    } 
    return list; 
} 
1

您不需要使用任何內存來解決此問題。有可能獲得列表的第N個元素,而不創建整個組合。這是解釋here