[英]Given a list of lists of strings, find most frequent pair of strings, second most frequent pair, ....., then most frequent triplet of strings, etc
我有一個包含 k 個字符串列表的列表(這些 k 個列表中的每一個都沒有任何重復的字符串)。 我們知道所有可能字符串的並集(假設我們有 n 個唯一字符串)。
我們需要找到的是:出現頻率最高的字符串對是什么(即,在 k 個列表中,哪兩個字符串一起出現最多?第二最頻繁的字符串對,第三最頻繁的字符串對,等等。另外,我想知道最頻繁的字符串三元組,第二頻繁的字符串三元組,等等。
我能想到的唯一算法是非常復雜的,基本上是為了解決最常見的對,我將從 n 個字符串 (O(n^2)) 和每個字符串中枚舉所有可能的對他們檢查有多少個列表 (O(k)) 然后我會對結果進行排序以獲得我需要的結果,所以我的整體復雜度是 O(n^2.x),忽略最后一個排序。
關於更好的算法時間方面的任何想法? (這有望適用於三連音和四連音等)? python 中的代碼最好,但詳細的偽代碼(和數據結構,如果相關)或詳細的總體思路也可以!
例如:如果
myList=[['AB', 'AC', 'ACC'], ['AB','ACC'],['ACC'],['AC','ACC'],['ACC','BB','AC']],
那么對問題的預期輸出將是:'AC','ACC' 是最頻繁的對,'AB','ACC' 是第二頻繁的對。
您可以使用combinations
、 Counter
和frozenset
:
from itertools import combinations
from collections import Counter
combos = (combinations(i, r=2) for i in myList)
Counter(frozenset(i) for c in combos for i in c).most_common(2)
輸出:
[(frozenset({'AC', 'ACC'}), 3), (frozenset({'AB', 'ACC'}), 2)]
這是所有組合長度的通用解決方案:
import itertools
def most_freq(myList, n):
d={} #create a dictionary that will keep pair:frequency
for i in myList:
if len(i)>=n:
for k in itertools.combinations(i, n): #generates all combinations of length n in i
if k in d: #increases the frequency for this pair by 1
d[k]+=1
else:
d[k]=1
return {k: v for k, v in sorted(d.items(), key=lambda item: item[1], reverse=True)} #this just sorts the dictionary based on the value, in descending order
例子:
myList=[['AB', 'AC', 'ACC'], ['AB','ACC'],['ACC'],['AC','ACC'],['ACC','BB','AC']]
>>> most_freq(myList,2)
{('AB', 'ACC'): 2, ('AC', 'ACC'): 2, ('AB', 'AC'): 1, ('ACC', 'BB'): 1, ('ACC', 'AC'): 1, ('BB', 'AC'): 1}
>>> most_freq(myList,3)
{('AB', 'AC', 'ACC'): 1, ('ACC', 'BB', 'AC'): 1}
在我的硬盤上找到一個片段,檢查它是否對你有幫助:
from collections import Counter
from itertools import combinations
mylist = [['AB', 'AC', 'ACC'], ['AB','ACC'],['ACC'],['AC','ACC'],['ACC','BB','AC']]
d = Counter()
for s in mylist:
if len(mylist) < 2:
continue
s.sort()
for c in combinations(s,2):
d[c] += 1
print(list(d.most_common()[0][0]))
將返回列表['AC','ACC']
我有一個相當簡單的方法,不使用任何庫。
首先,對於主列表中的每個列表,我們可以計算每對字符串的哈希值。 (更多關於字符串散列在這里: https : //cp-algorithms.com/string/string-hashing.html )。 維護一個字典,保存每個散列發生的計數。 最后,我們只需要對字典進行排序以獲取所有對,按出現次數排序。
示例: [['AB', 'AC', 'ACC', 'TR'], ['AB','ACC']]
對於列表 1,即['AB', 'AC', 'ACC', 'TR']
,
計算“AB AC”、“AC ACC”、“ACC TR”對的哈希值,並相應地將它們添加到字典中。 對主列表中的所有列表重復相同的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.