簡體   English   中英

給定一個字符串列表列表,找到最頻繁的一對字符串,第二個最頻繁的對,.....,然后是最頻繁的字符串三元組,等等

[英]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' 是第二頻繁的對。

您可以使用combinationsCounterfrozenset

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.

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