【问题标题】:Efficiently finding anagrams in two lists在两个列表中有效地查找字谜
【发布时间】:2021-05-09 12:11:53
【问题描述】:

我有两个名为“查询”和“数据”的列表,它们都包含字符串。我需要计算'data'中有'query'中每个字符串的字谜。

例如以下两个列表:

query = ['no', 'result', 'oh', 'abc', 'temper']

data = ['no', 'on', 'bca', 'oh', 'cba', 'repmet', 'serult', 'pemter', 'tluser', 'tlures', 'pterem', 'temprep']

输出将是一个字典,其中包含每个单词的字谜计数:

{'no': 2, 'result': 3, 'oh': 1, 'abc': 2, 'temper': 4}

我有一个使用嵌套循环的初始蛮力解决方案,但我想知道我应该如何优化它,因为当列表变大时它会很慢。

dict1 = {}
data.sort()
data.sort(key=len, reverse=False)    

for idx in range(len(query)):

    dict1[query[idx]] = 0
    x = sorted(query[idx])

    for idx2 in range(len(data)):
      if len(data[idx2]) > len(query[idx]):
        break

      if data[idx2] == query[idx]:
        dict1[query[idx]] += 1

      elif x == sorted(data[idx2]):
        dict1[query[idx]] += 1

【问题讨论】:

    标签: python arrays string optimization


    【解决方案1】:

    您可以使用Counter 对象:

    from collections import Counter
    query = ['no', 'result', 'oh', 'abc', 'temper']
    data = ['no', 'on', 'bca', 'oh', 'cba', 'repmet', 'serult', 'pemter', 'tluser', 'tlures', 'pterem', 'temrep']
    
    counts = Counter(''.join(sorted(word)) for word in data)
    anagram_counts = {k:counts[''.join(sorted(k))] for k in query}
    print(anagram_counts) #prints {'no': 2, 'result': 3, 'oh': 1, 'abc': 2, 'temper': 4}
    

    这具有线性复杂性,而您的嵌套循环方法具有二次复杂性。即使不使用 Counter 对象,您也可以获得线性复杂度:一次通过 data 创建计数字典,然后通过 query,使用第一个循环中构造的字典创建目标字典。

    【讨论】:

    • 不错的解决方案,当您告诉它的线性时,如何考虑排序的日志线性时间复杂度?你能解释一下吗?谢谢@john coleman
    • @python_user 好点。它在len(query)+len(data) 中是线性的。 OP 提到列表的长度是主要问题。如果所有字符串都具有相当的长度,那么为了这个目的,排序可以被认为是O(1)。但你确实提出了一个很好的观点。如果其中一个字符串是《战争与和平》的完整文本,就会出现问题。
    猜你喜欢
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 2021-08-27
    • 2015-12-25
    • 1970-01-01
    • 2017-12-23
    • 2016-03-17
    • 2022-01-21
    相关资源
    最近更新 更多