【问题标题】:Find a prefix based on trie search | | python根据 trie search 查找前缀 | | Python
【发布时间】:2020-12-28 23:19:27
【问题描述】:

问题: 给定一个 business_names(字符串)列表和一个 searchTerm(字符串)。 返回一个business_names 列表,其中包含searchTerm 作为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"]

我已经尝试通过以下方式解决。

但我想实现 trie 方法来解决这个问题。有人请在这里帮忙吗? 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]

【问题讨论】:

  • 您的示例输入和代码中存在一些问题:business_name[]?并且永远不要使用split 作为变量名——因为它是一个内置名称。使用 parts 之类的其他内容会更好。
  • 你能解释一下trie是什么意思吗?数据结构?
  • 你为什么要使用这么多for-loops?您可以在第二个循环中使用split() 而不是创建列表split。然后你可以直接在 append() 中使用 originla 名称,以后你就不需要使用 " ".join()
  • 目前还不清楚为什么bur 被视为super duper burger's 中的前缀。如果您想使用具有这种前缀定义的 trie,您将需要一个单个单词的 trie,然后是一个将单词映射到企业名称的结构。
  • @furas 你能帮我吗?

标签: python python-3.x


【解决方案1】:

我不知道trie approach 是什么意思,如果这是你需要的,但我会写得更简单——没有joinrangelen

为了确保我也使用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()

  • 它只搜索完整的单词,但在删除 return pCrawl != None and pCrawl.isEndOfWord 中的 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 )

【讨论】:

  • 感谢 @furas 优化我的代码,我仍然需要尝试解决这个问题。因为上面的代码是O(n^2)。
  • 那么你必须解释什么是trie approach,因为似乎没有人知道这意味着什么。您可以添加有问题的描述或链接到一些解释 - 也许在维基百科上。
  • 我的意思是这种方法。 geeksforgeeks.org/trie-insert-and-search@furas
  • 在此链接中您似乎已经在 Python 中进行了一些实现。
  • 是的,但在这种情况下,我正在为如何在此处实际实施而苦苦挣扎。
猜你喜欢
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
  • 2019-07-04
  • 1970-01-01
  • 2020-01-01
  • 2020-08-10
  • 1970-01-01
  • 2017-06-30
相关资源
最近更新 更多