python给定的查询字符串查找一组具有相同开头的字符串

2024-04-27 04:54:20 发布

您现在位置:Python中文网/ 问答频道 /正文

编辑:我很感激所有的答案,但谁能告诉我为什么我的解决方案不起作用?我想在不使用.startswith()的情况下尝试这样做谢谢

我正在尝试完成此练习:

Implement an autocomplete system. That is, given a query string and a set of all possible query strings, return all strings in the set that have s as a prefix. For example, given the query string de and the set of strings [dog, deer, deal], return [deer, deal]. Hint: Try preprocessing the dictionary into a more efficient data structure to speed up queries.

但我得到一张空名单。我可能做错了什么?我以为这会给我[鹿,交易]

def autocomplete(string,set):
    string_letters = []
    letter_counter = 0
    list_to_return = []

    for letter in string:
        string_letters.append(letter)

    for words in set:
        for letter in words:
            if letter_counter == len(string):
                list_to_return.append(words)
            if letter == string_letters[letter_counter]:
                letter_counter += 1
            else:
                break
    return list_to_return

print(autocomplete("de", ["dog","deer","deal"]))

输出:

[]

编辑:我很感激所有的答案,但谁能告诉我为什么我的解决方案不起作用?我想在不使用.startswith()的情况下尝试这样做谢谢


Tags: thetoinstringreturncounterqueryautocomplete
3条回答

以下是我将如何完成您正在尝试做的事情:

import re
strings = ['dog', 'deer', 'deal']
search = 'de'
pattern = re.compile('^' + search)
[x for x in strings if pattern.match(x)]

结果:['deer', 'deal']

但是在大多数情况下,对于这样的用例,您可能希望忽略搜索字符串和搜索字段的大小写

import re
strings = ['dog', 'Deer', 'deal']
search = 'De'
pattern = re.compile('^' + search, re.IGNORECASE)
[x for x in strings if pattern.match(x)]

结果:['Deer', 'deal']

要回答代码不工作的原因,请在代码中添加一些详细信息:

def autocomplete(string,set):
    string_letters = []
    letter_counter = 0
    list_to_return = []

    for letter in string:
        string_letters.append(letter)

    for word in set:
        print(word)

        for letter in word:
            print(letter, letter_counter, len(string))
            if letter_counter == len(string):
                list_to_return.append(word)
            if letter == string_letters[letter_counter]:
                letter_counter += 1
            else:
                print('hit break')
                break
    return list_to_return

print(autocomplete("de", ["dog","deer","deal"]))

输出:

dog
('d', 0, 2)
('o', 1, 2)
hit break
deer
('d', 1, 2)
hit break
deal
('d', 1, 2)
hit break
[]

正如您在输出中看到的那样,dog'd匹配但o不匹配’,这使得字母_计数器为1,然后在deer'd!='所以它坏了。。。这种情况一次又一次地持续下去。有趣的是,设置“ddeer”实际上与此行为匹配。要解决这个问题,您需要重置for循环中的字母_计数器,并具有额外的断点以防止过度修改索引

def autocomplete(string,set):
    string_letters = []
    list_to_return = []

    for letter in string:
        string_letters.append(letter)

    for word in set:
        # Reset letter_counter as it is only relevant to this word.
        letter_counter = 0
        print(word)

        for letter in word:
            print(letter, letter_counter, len(string))
            if letter == string_letters[letter_counter]:
                letter_counter += 1
            else:
                # We did not match break early
                break
            if letter_counter == len(string):
                # We matched for all letters append and break.
                list_to_return.append(word)
                break
    return list_to_return

print(autocomplete("de", ["dog","deer","deal"]))

您只需使用startswithstring函数并避免所有这些计数器,如下所示:

def autocomplete(string, set):
    list_to_return = []

    for word in set:
        if word.startswith(string):
            list_to_return.append(word)
    return list_to_return

print(autocomplete("de", ["dog","deer","deal"]))

我注意到提示,但它并不是一项要求,因此:

def autocomplete(string,set):
    return [s for s in set if s.startswith(string)]

print(autocomplete("de", ["dog","deer","deal"]))

如果str以n开头,则str.startswith(n)将返回一个布尔值True,否则False

相关问题 更多 >