Python 如果用户输入,如何在O(logN)时间内搜索字谜?

Python 如果用户输入,如何在O(logN)时间内搜索字谜?,python,binary-search,anagram,Python,Binary Search,Anagram,嗨,我已经想了好几天如何实现这个 我正在尝试实现一个程序,将字典读入一个列表,并在O(N)时间内对其进行排序。之后,我必须在O(log N)时间内根据用户的输入搜索列表中的字谜。我可以按字母对每个单词进行排序,并在O(N)时间内按字母顺序对列表进行排序 因为我试图在O(logN)时间内进行搜索,所以我尝试使用二进制搜索,对每个单词中的每个字母进行排序,并将其用作识别字谜的键。 例如,“act”是字谜组“act”、“cat”、“tac”的键 arr=['act','cat','tac','bad'

嗨,我已经想了好几天如何实现这个

我正在尝试实现一个程序,将字典读入一个列表,并在O(N)时间内对其进行排序。之后,我必须在O(log N)时间内根据用户的输入搜索列表中的字谜。我可以按字母对每个单词进行排序,并在O(N)时间内按字母顺序对列表进行排序

因为我试图在O(logN)时间内进行搜索,所以我尝试使用二进制搜索,对每个单词中的每个字母进行排序,并将其用作识别字谜的键。 例如,“act”是字谜组“act”、“cat”、“tac”的键

arr=['act','cat','tac','bad','fad'] 
分类后

[['act', 'act'], ['cat', 'act'], ['tac', 'act'], ['bad', 'abd'],  ['fad', 'adf']] 
但二进制搜索只找到一个目标,因此它只会在“act”下为字谜组返回“tac”。我的二进制搜索代码:

def binarySearch(arr, lower, upper, target):
anagramList=[]
if upper >= lower:
    mid = lower + ((upper - lower) // 2)
    if areAnagrams(arr[mid][1],target):
        anagramList.append(arr[mid])
    elif arr[mid] > target:
        return binarySearch(arr, lower, mid - 1, target)
    else:
        return binarySearch(arr, mid + 1, upper, target)
return anagramList
我试着这样把他们分组

[['act','act','cat','tac'],['bad','abd'],['fad','daf]]
但是它需要O(N^2)的复杂性,它比O(N)大?有人能建议我应该怎么做吗?谢谢

编辑:
例如,如果查询字符串是alppe,则输出将由单词appel和apple组成。

您可以使用字典,其中关键字是已排序字母的单词

from collections import defaultdict
anagrams = defaultdict(list)

arr=['act','cat','tac','bad','fad']

for word in arr:
    anagrams[''.join(sorted(word))].append(word)

def get_anagram(user_input):
    return anagrams[''.join(sorted(user_input))]
例如:

>>> get_anagram('tca')
['act', 'cat', 'tac']

你可以使用以字母排序的单词为关键字的字典

from collections import defaultdict
anagrams = defaultdict(list)

arr=['act','cat','tac','bad','fad']

for word in arr:
    anagrams[''.join(sorted(word))].append(word)

def get_anagram(user_input):
    return anagrams[''.join(sorted(user_input))]
例如:

>>> get_anagram('tca')
['act', 'cat', 'tac']

您需要使用模块中的计数器。计数器类是不可散列的,因此我们将使其成为可散列的dict

from collections import Counter, defaultdict


class hashablecounter(Counter):
    def __hash__(self):
        return hash(tuple(sorted(self.items())))


d = defaultdict(list)
arr=['act','cat','tac','bad','fad']

for a in arr:
    d[hashablecounter(a)].append(a)

s = 'cat'
print('Anagrams for ', s, ' are ', d[hashablecounter(s)])

您需要使用模块中的计数器。计数器类是不可散列的,因此我们将使其成为可散列的dict

from collections import Counter, defaultdict


class hashablecounter(Counter):
    def __hash__(self):
        return hash(tuple(sorted(self.items())))


d = defaultdict(list)
arr=['act','cat','tac','bad','fad']

for a in arr:
    d[hashablecounter(a)].append(a)

s = 'cat'
print('Anagrams for ', s, ' are ', d[hashablecounter(s)])


你可能想用一个列表,对吗?如果没有,你可以查字典。不允许部分匹配,对吗?你总是需要完整的单词?您能提供更多的输入和预期的输出吗?这样我们就可以确切地知道您要做什么。@Megalng Well字典需要O(N)插入,所以最坏的情况是O(N^2)如此no@Håken Lid好的,我编辑过it@SookLimHakenLid O(N^2)的答案是什么?插入为O(N),查找为O(1)。但也许我误解了大O符号。你可能想用一个列表,对吗?如果没有,你可以查字典。不允许部分匹配,对吗?你总是需要完整的单词?您能提供更多的输入和预期的输出吗?这样我们就可以确切地知道您要做什么。@Megalng Well字典需要O(N)插入,所以最坏的情况是O(N^2)如此no@Håken Lid好的,我编辑过it@SookLimHakenLid O(N^2)的答案是什么?插入为O(N),查找为O(1)。但也许我误解了big-O表示法。那么读取和排序文件的时间复杂度就不是O(N)?@SookLim Python wiki声明insert是O(1)(最坏情况是O(N)),getitem是相同的:N是容器的大小。如果输入数组的大小和达到最坏情况O(n*n),那么您是正确的,但这不太可能。如果
n
是输入的长度
arr
,则构建查找哈希映射是
O(n)
。如果单个单词在某个上限内(根据问题中的示例,这不应该是一个不合理的假设),那么我们可以断言排序键也有一个上限常量时间。@Megalng抱歉,我是说最坏情况下的时间复杂度为O(N)@MegaIng:为什么要将insert和getitem操作相乘?那么读取和排序文件的时间复杂度就不是O(N)?@SookLim Python wiki声明insert是O(1)(最坏情况是O(N)),getitem是相同的:N是容器的大小。如果输入数组的大小和达到最坏情况O(n*n),那么您是正确的,但这不太可能。如果
n
是输入的长度
arr
,则构建查找哈希映射是
O(n)
。如果单个单词在某个上限范围内(根据问题中的示例,这不应该是一个不合理的假设),那么我们可以断言排序键也有一个上限常量时间。@Megalng抱歉,我指的是最坏情况下的时间复杂度,如O(N)@MegaIng:为什么要对insert和getitem操作进行乘法运算?