2015-11-06 55 views
1

比方說我有x集合對象,並且每個集合都有一定數量的對象。我想創建一個數組,它將存儲所有這些對象的唯一「和」組合。例如,如果我在集合A中有5個對象,集合B中有10個對象,集合C中有8個對象,那麼我知道有5 * 10 * 8 = 400個獨特的方式從每個對象中選擇一個對象組。但我想實際上將這些組合存儲在一個數組中。查找所有「和」組合多個集合

所以數組是多維的,是這樣的:

{ 
    { a, a, a } 
    { a, a, b } 
    { a, a, c } 
    ... 
    { a, b, a } 
    { a, b, b } 
    and so on... 
} 

我需要的解決方案,以儘可能高效,因爲我處理的地方有潛在的數以千萬計的組合情況。我不確定如何開始解決這個問題。

對不起,如果它不清楚,但我真的不知道該怎麼稱呼我想達到的目標,所以我只是盡我所能地描述它。感謝您提供任何幫助。

編輯:這是有關該問題的一些詳細信息:

這個問題的目的是,我要計算每個結果數組「得分」值。然後,我想找到排名前n分數並將它們返回給用戶。所以實際上,我相信我不需要在內存中擁有整個數組。我可以遍歷數組,計算得分,並將其添加到返回的數組,如果它的分數足夠高。這樣,我只需要不斷在內存中的頂層n對象。

我希望這使事情更清楚。

+0

一些評論:notationally,我不認爲'set'可以有多個相同的元素。或者,至少要知道,某些語言(例如Python)會在您使用'set()'時重複數據刪除。其次 - 擁有數以百萬計的連擊數,你是否需要立即整個陣列?或者你可以迭代每一個。否則,你可能會遇到內存大小問題,不是嗎? – dwanderson

+0

嘿,對不起,如果不明確。每個集合A,B,C中的對象都是唯一的。如果你指的是符號'{a,a,a}',我想說的是'{從一個對象a,從一個對象a到另一個對象a,從集合c對象a'等等...... – Charles

+0

啊,陷入困境,然後忽略第一點。第二個仍然站立。 – dwanderson

回答

1

快速蟒蛇,恐怕無法得到更有效的,因爲你需要在某個時候進行迭代...

getItems(A, B, C): 
    for a in A: 
     for b in B: 
      for c in C: 
       items = (a, b, c) ## or [a, b, c], as desired 
       yield items 

或者,如果你熟悉發電機表達式:

gen = ((a, b, c) for a in A for b in B for c in C) 

然後使用:

for combo in getItems(A, B, C): ## or for combo in gen: 
    ## do stuff here 

編輯:

def getItems(*allSets): 
    if len(allSets) == 0: 
     yield [] 
     return 
    thisSet, theRest = allSets[0], allSets[1:] 
    for value in thisSet: 
     for values in getItems(*theRest): 
      yield [value] + values 
+0

嘿,謝謝你的回覆!我對此很熟悉。但是,有沒有辦法遞歸地做到這一點?我不一定知道有多少套。 – Charles

+0

最後一點還不夠用;不能連接列表'[value]'和生成器'getItems(theRest)',但我正在處理它 – dwanderson

+0

現在應該工作。 – dwanderson

0

你知道設計時的組數嗎?如果是這樣,我會做嵌套for循環。如果你不知道集的數量,那麼你可能會做某種形式的遞歸來處理循環。

這樣說,我認爲你所做的是,根據定義,是不高效的。是否有理由需要將所有可能的組合存儲在內存中,而不是根據需要隨時生成它們?

+0

對於遞歸,你需要一組設置對象(在java中數組的數組,等等)。你的遞歸將循環遍歷該主數組,傳遞要循環的集合的索引,以及當前選中的元素。 – WingedPanther73

+0

請參閱編輯,我希望它使問題更清楚。 – Charles

+0

@Charles稍微澄清一點。在你的情況下,我絕對不會將所有內容都存儲在RAM中。只有最高的n個分數以及他們的分數,所以你可以取代更好的分數。我可能會使用一個鏈表或平衡樹,所以你可以保持秩序的分數,並降低最低分,一旦你找到n個物品。 – WingedPanther73