#python #python-3.x
#python #python-3.x
Вопрос:
Проблема: Дан список business_names (строк) и поисковый запрос (строка). Возвращает список business_names, который содержит условие поиска в качестве префикса в business_names.
Example 1.
Input:
business_names[] = { "burger king", "McDonald's", "super duper burger's", "subway", "pizza hut"}
searchTerm = "bur"
Ouput:
["burger king", "super duper burger's"]
Я попытался решить это следующим образом.
Но я хочу реализовать три подхода для решения этой проблемы. кто-нибудь, пожалуйста, помогите здесь? https://www.geeksforgeeks.org/trie-insert-and-search/
Любое линейное решение для решения
def prefix(business_names, searchTerm):
split = [i.split() for i in business_names]
ans = []
for name in split:
for i in range(len(name)):
query = ' '.join(name[i:])
if query.startswith(searchTerm):
ans.append(name)
break
return [' '.join(i) for i in ans]
Комментарии:
1. Есть некоторые проблемы в вашем примере ввода и коде:
business_name[]
? и никогда не используйтеsplit
в качестве имени переменной — поскольку это встроенное имя. Используйте что-то другое, что вам нравитсяparts
больше.2. Не могли бы вы , пожалуйста , также объяснить , что вы имеете в виду под
trie
? Структура данных?3. почему вы используете так много
for
циклов ? вы моглиsplit()
бы сделать это во втором цикле вместо создания спискаsplit
. И тогда вы могли бы использовать originla name непосредственно в append(), и позже вам не нужно было бы использовать" ".join()
4. Не совсем понятно, почему
bur
это считается префиксом вsuper duper burger's
. Если вы хотите использовать три с этим определением префикса, вам понадобится три отдельных слова, а затем структура, которая сопоставляет слова с названиями компаний.5. @furas не могли бы вы мне здесь помочь?
Ответ №1:
Я не знаю, что это значит trie approach
, и если это то, что вам нужно, но я бы написал проще — без join
, range
, len
Чтобы убедиться, что я также использую lower()
business_names = ["burger king", "McDonald's", "super duper burger's", "subway", "pizza hut"]
searchTerm = "bur"
def prefix(business_names, searchTerm):
searchTerm = searchTerm.lower()
results = []
for name in business_names:
for word in name.split(' '):
word = word.lower()
if word.startswith(searchTerm):
results.append(name)
break
return results
print(prefix(business_names, searchTerm))
Редактировать:
Я взял код из ссылки и создал этот код.
Но мне пришлось изменить две вещи.
- он работает только с буквами
a-z
, поэтому я должен удалить'
и преобразовать вlower()
- он ищет только полные слова, но после удаления
and pCrawl.isEndOfWord
,return pCrawl != None and pCrawl.isEndOfWord
кажется, он находит слова, которые соответствуют статистикеsearchTerm
Но у меня есть одно сомнение: может быть, тогда он сможет искать лучше O(n^2)
, но сначала его нужно построить Trie
, и ему также нужно некоторое время. Таким образом, это может быть полезно, когда вы всегда выполняете поиск в одном и том же тексте и вам приходится создавать Trie
только один раз. Но вы должны создавать отдельные Trie
файлы для каждого названия компании — и это не обязательно должно быть быстрее.
.
class TrieNode:
# Trie node class
def __init__(self):
self.children = [None]*26
# isEndOfWord is True if node represent the end of the word
self.isEndOfWord = False
class Trie:
# Trie data structure class
def __init__(self):
self.root = self.getNode()
def getNode(self):
# Returns new trie node (initialized to NULLs)
return TrieNode()
def _charToIndex(self,ch):
# private helper function
# Converts key current character into index
# use only 'a' through 'z' and lower case
return ord(ch)-ord('a')
def insert(self, key):
# If not present, inserts key into trie
# If the key is prefix of trie node,
# just marks leaf node
pCrawl = self.root
length = len(key)
for level in range(length):
index = self._charToIndex(key[level])
# if current character is not present
if not pCrawl.children[index]:
pCrawl.children[index] = self.getNode()
pCrawl = pCrawl.children[index]
# mark last node as leaf
pCrawl.isEndOfWord = True
def search(self, key):
# Search key in the trie
# Returns true if key presents
# in trie, else false
pCrawl = self.root
length = len(key)
for level in range(length):
index = self._charToIndex(key[level])
if not pCrawl.children[index]:
return False
pCrawl = pCrawl.children[index]
return pCrawl != None #and pCrawl.isEndOfWord # <-- check `isEndOfWord` to search full words
# driver function
def prefix(business_names, searchTerm):
searchTerm = searchTerm.lower()
results = []
for name in business_names:
# Input keys (use only 'a' through 'z' and lower case)
# remove `'` and convert to list with lower case words
keys = name.lower().replace("'", "").split(" ")
#print('keys:', keys)
# Trie object
t = Trie()
# Construct trie
for key in keys:
#print('key:', key)
t.insert(key)
# Search in trie
if t.search(searchTerm) is True:
results.append(name)
return results
if __name__ == '__main__':
business_names = ["burger king", "McDonald's", "super duper burger's", "subway", "pizza hut"]
searchTerm = "bur"
results = prefix(business_names, searchTerm)
print( results )
Комментарии:
1. Спасибо @furas за оптимизацию моего кода, мне все еще нужен подход trie к этой проблеме. Поскольку приведенный выше код равен O(n ^ 2).
2. тогда вам нужно объяснить, что это
trie approach
такое, потому что, похоже, никто не знает, что это значит. Вы могли бы добавить описание в вопросе или ссылку на какое-то объяснение — возможно, в Википедии.3. Я имею в виду этот подход. geeksforgeeks.org/trie-insert-and-search @фурас
4. похоже, по этой ссылке у вас уже есть некоторая реализация на Python.
5. да, но я борюсь с тем, как на самом деле реализовать это в данном случае.