简体   繁体   中英

Find a prefix based on trie search | | python

Problem: Given a list of business_names (strings) and a searchTerm (string). Return a list of business_names that contains searchTerm as prefix in the 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"]

I have tried solving in this below way.

But I want to implement trie approach to solve this problem. some one please help here? https://www.geeksforgeeks.org/trie-insert-and-search/

Any linear solution to solve

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]

I don't know what means trie approach and if this is what you need but I would write it simpler - without join , range , len

To make sure I use also 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))

EDIT:

I took code from link and create this code.

But I had to change two things.

  • it works only with letters az so I have to remove ' and convert to lower()

  • it search only full words but after removing and pCrawl.isEndOfWord in return pCrawl.= None and pCrawl.isEndOfWord it seems it find words which stats with searchTerm

But I have one doubt: maybe it can search better then O(n^2) but first it has to build Trie and it also need some time. So it can be useful when you always search in the same text and you have to build Trie only once. But you have to build separated Trie for every business name - and it doesn't have to be faster.

.

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 )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM