2017-09-01 43 views
-3

就我而言,我有兩個不同長度的列表。第一個需要至少一個成功的第二個條目,包括重複項必須匹配條目。例如:Python 3.6如何有效地比較2個無序的字符串列表,保留重複項並解決不相等的列表大小?

['I', 'have', 'a', 'list', 'with', 'a', 'duplicate']['I', 'have', 'a', 'list', 'with', 'no', 'duplicate']將返回False

['I', 'have', 'a', 'list', 'with', 'a', 'duplicate']['I', 'have', 'a', 'list', 'with', 'a', 'possible', 'duplicate']將返回True

我有套試過,但不保留副本。我也嘗試使用for in循環來通過它,但是它們已經證明在運行時需要完成的比較數量太慢。

必須有一個更有效的方法來做到這一點。誰能幫我?

---------------------------------------------- - - - - - - - 編輯 - - - - - - - - - - - - - - - - - - -------------------------

這是最初被問及的目的是找到解決在HackerRank Ransom Note挑戰的最有效的方式。

+0

爲什麼選擇投票? – Spiznak

+0

相關:https://en.m.wikipedia.org/wiki/Edit_distance – SwiftsNamesake

+0

@SwiftsNames相似,但不完全匹配。我沒有看到需要多少操作來匹配,我正在尋找是否在第二個列表中可用的每個必要元素的合適數量。編輯距離建議達到同一性,而問題只需要包含列表。不過謝謝你給我提供重讀這個機會的機會。 – Spiznak

回答

-2

我想我可能已經找到了答案,從拼湊我一直在尋找的其他東西(大約20個不同的答案,類似的問題丟失關鍵部分,需要放在一起)。

Countercollections似乎是這樣做的方式,使用-比較和檢查結果中的空字典。一個人爲設想的情況就是採訪問題「你如何判斷一本雜誌(列表)是否包含你希望在贖金記錄(列表)中包含的每一個字?」

最有效的答案,我能想到的,和拼湊,如上面提到的是:

from collections import Counter 

def ransom_note(magazine, ransom): 
    return (Counter(ransom) - Counter(magazine)) == {} 

如果任何人有什麼更有效,請讓我知道。

感謝,

Spiznak

+0

這不是一個空集,它是一個空的* dict *。 –

+0

這不會保留訂單 – SwiftsNamesake

+0

此外,如果第二個列表中有其他單詞,則差異不會是空集 – SwiftsNamesake

-1

如果我理解正確你的問題,所有你需要做的是循環於第一個列表,檢查在第二列表中的相應條目是否匹配,並確保到跳過第二個列表中不匹配的任何單詞。如果你設法用這種方式耗盡第一個列表,你知道這些列表符合你的標準。

如果您以前的解決方案太慢,我想這是因爲您使用的是較慢的算法。很難說,因爲您沒有以任何方式描述樣本空間(如果數量巨大,您可能需要使用低級語言,或使用專門的庫,如numpy)。


這是不是最漂亮的實施能夠想象,但我會離開這裏,現在,直到我有時間去把它擦亮。道歉的草率命名和不良的風格。

first = ['I', 'have', 'a', 'list', 'with', 'a', 'duplicate'], ['I', 'have', 'a', 'list', 'with', 'no', 'duplicate'] 
second = ['I', 'have', 'a', 'list', 'with', 'a', 'duplicate'], ['I', 'have', 'a', 'list', 'with', 'a', 'possible', 'duplicate'] 

# TODO: Come up with Haskell solution 
# TODO: Parallelise 
# TODO: Suggest numpy solution 
def match(a, b): 
    c = iter(b) 

    # Loop over the first list 
    for word in a: 
    try: 
     # Checking whether there's a matching entry in the other list, 
     # making sure to skip past non-matches 
     while word != next(c): 
     pass 
    except StopIteration: 
     # We've run out of entries in the second list, 
     # before exhausting the first one. 
     return False 
    else: 
    # We've matched all entries in the first list 
    return True 
    return False 

assert not match(first[0], first[1]) 
assert match(second[0], second[1]) 
+0

樣本應該是'100 Spiznak

+0

@Spiznak,我其實不認爲它是O(n^2),因爲你不會每次都重新啓動內部循環。它最多隻會檢查任何條目*一次*。 – SwiftsNamesake

+0

@Spiznak由於一個要求是列表1中的每個單詞也在列表2中,所以如果函數耗盡了列表2中的所有單詞而未找到匹配項,則該函數將簡單地返回false。除非我誤解了你的問題,否則我不認爲我需要單獨檢查。 – SwiftsNamesake

相關問題