簡體   English   中英

將具有共同元素的所有子陣列合並為一個子陣列

[英]Merging all sub-arrays with mutual elements into one sub-array

我需要找到共享任何相互元素的所有子數組,並將它們合並為一個子數組。 (在Python中實現,但是任何算法思想都將有所幫助)

多維數組結構:

categories = {'car':['automobile','auto'],
             'bike':['vehicle','motorcycle','motorbike','automobile'],
             'software':['computer','macbook','apple','microsoft','mozilla'],
             'firefox':['internet','mozilla','browser']
             'bicycle':['vehicle']}

我想將“汽車”,“自行車”和“自行車”合並到一個列表中( 保留第一個列表的密鑰, 新列表的密鑰可以是任何相關密鑰),並且將“軟件”和“ firefox”合並為一個列表,如下所示:好。

性能至關重要。

我能來與迄今最好的辦法是保持平坦元件 => list_key(例如“ 汽車 ” =>“ 汽車 ”)的一維數組,然后運行下面的遞歸函數的多維陣列中的每個列表(偽代碼) :

function merge_similar(list_key):
    For each element in categories[list_key]:
        If flatten_array.has_key(element):
            list_to_merge = flatten_array[element]
            merge_similar(list_to_merge) /* merge other lists which share an element with our newly found similar list */
            categories[list_key] = merge(categories [list_key], categories[list_to_merge])
            delete categories[list_to_merge]

知道如何改善其性能嗎?

謝謝!

請注意, 沒有 “第一個關鍵” -類型的字典不守秩序,所以如果你需要一些為了保持住,你就需要一些不同的,額外的數據結構開始。

除了與訂單相關的問題外,我將從類似的內容開始:

def merged(dictoflists):
  result = dict()
  reversed = dict()
  for k, l in dictoflists.iteritems():
    intersecting = set(reversed.get(w) for w in l) - set([None])
    if intersecting:
      pickone = intersecting.pop()
      into = result[pickone]
    else:
      pickone = k
      into = result[k] = set()
    for ok in intersecting:
      into.update(result.pop(ok))
    into.update(l)
    for w in into:
      reversed[w] = pickone
  return dict((k, sorted(l)) for k, l in result.iteritems())

如果順序對您很重要,則使用set將會有問題,並且您將需要更復雜(且速度更慢)的數據結構-但是,在這種情況下,您應該首先完整詳細地說明您需要精確的順序約束尊重可能發生的各種可能情況。

我無法想象遞歸解決方案會很快。
使用list.extend()是否太慢?
您可以執行以下操作:

categories['car'].extend(categories['bike']);
categories['car'].extend(categories['bicycle']);

或更籠統地說,如果您傳遞要合並的鍵列表:

first_key=None;
for key in keys_whose_lists_I_want_to_merge:
    if first_key is None:
        first_key=key;
    else:
        categories[first_key].extend(categories[key]);

如果要合並大量列表,則可以優化該循環,使其在第一次之后不執行“無”檢查。 請參閱“ Python性能提示”頁面上的標題為“在運行時重新映射函數”的提示

>>> categories = {'car':['automobile','auto'],
             'bike':['vehicle','motorcycle','motorbike','automobile'],
             'software':['computer','macbook','apple','microsoft','mozilla'],
             'firefox':['internet','mozilla','browser'],
             'bicycle':['vehicle']}
>>> # Use sets for values
>>> for k,v in categories.items(): categories[k] = set(v)

>>> # Acumulate
>>> for k1, v1 in categories.items():
    if v1:
        for k2,v2 in categories.items():
            if v2 and k1 != k2 and v1 & v2:
                v1 |= v2
                categories[k2] = None
        categories[k1] = v1


>>> # Print
>>> for k1, v1 in categories.items():
    if v1: print('%s: %r' %(k1,v1))


bicycle: {'motorbike', 'vehicle', 'auto', 'automobile', 'motorcycle'}
firefox: {'apple', 'mozilla', 'macbook', 'computer', 'internet', 'microsoft', 'browser'}
>>> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM