def insert(self, string): """Insert the given string into this prefix tree. Time: O(kn) n = # of strings (width of tree), k = len(string) Space: Θ(1) """ cur_node = self.root for char in string: try: ## Try to update cur_node with existing child for char cur_node = cur_node.get_child(char) except ValueError: ## Child for char doesn't exist, so add new child then update ## cur_child new_node = PrefixTreeNode(char) cur_node.add_child(char, new_node) cur_node = new_node try: ## Check if terminate character exists cur_node.get_child('$') except ValueError: ## Terminate character ($) wasn't found, so this must be a new ## string cur_node.add_child('$', PrefixTreeNode('$')) # Terminal node self.size += 1 # Increment because a new string has been inserted
def __init__(self, strings=None): """Initialize this prefix tree and insert the given strings, if any.""" # Create a new root node with the start character self.root = PrefixTreeNode(PrefixTree.START_CHARACTER) # Count the number of strings inserted into the tree self.size = 0 # Insert each string, if any were given if strings is not None: for string in strings: self.insert(string)
def _traverse(self, node: PrefixTreeNode, prefix: str, visit: Callable) -> None: """Traverse this prefix tree with recursive depth-first traversal. Start at the given node with the given prefix representing its path in this prefix tree and visit each node with the given visit function.""" # Once the node is filled with characters and contains a terminal node, it'll append if node.is_terminal(): visit(prefix) for char in node.children.keys(): next_node = node.get_child(char) self._traverse(next_node, prefix + char, visit)
def test_init_and_properties(self): character = 'A' node = PrefixTreeNode(character) # Verify node character assert isinstance(node.character, str) assert node.character is character # Verify children nodes structure assert isinstance(node.children, PrefixTreeNode.CHILDREN_TYPE) assert len(node.children) == 0 assert node.children == PrefixTreeNode.CHILDREN_TYPE() # Verify terminal boolean assert isinstance(node.terminal, bool) assert node.terminal is False
def test_init_and_properties(self): character = 'a' node = PrefixTreeNode(character) # Verify node character assert isinstance(node.character, str) print(node.character) assert node.character == 'a' # Verify children nodes structure assert isinstance(node.children, PrefixTreeNode.CHILDREN_TYPE) assert len(node.children) == 26 assert node.children == [None] * 26 assert node.num_children() == 0 # Verify terminal boolean assert node.terminal is False assert node.is_terminal() is False
def insert(self, string): """Insert the given string into this prefix tree. Runtime Complexity: O((nm) + (np)), where n is the size of the trie, m is the length of string being searched as we look for a duplicate, and p is the length of the string being nserted. This runtime depends on calling the contains() method. In the average case it will then also insert the new string, an operation which the runtime depends on thethe size of the trie (i.e. the number of strings already being stored) because will increase the time we spend looking amongst the children of the root node. Also, this second step depends on the length of the new string being added. """ # make sure the string not already in the tree if self.contains(string) is False: # find the node to start adding new letters from current_node, index = self._find_node(string) # for each index position in the string greater than index for i in range(index, len(string)): # returned, add a new child node of the node returned next_char = string[i] new_node = PrefixTreeNode(next_char) current_node.add_child(next_char, new_node) # then move the current node to its child current_node = new_node # mark the last node to be added as terminal current_node.terminal = True # increment size of the tree self.size += 1
def insert(self, string): """ Insert the given string into this prefix tree. """ # Start with root node = self.root depth = 0 # Iterate through letters in string for letter in string: # Check if node has child matching letter if node.has_child(letter): # move on to the next node node = node.get_child(letter) depth += 1 node.depth = depth else: # create a child node child = PrefixTreeNode(letter) depth += 1 # add it as a child to the node node.add_child(letter, child) # move on to the next node node = node.get_child(letter) node.depth = depth # if node.terminal == True: # print(self.root.children) if node.terminal == False: self.size += 1 # On the last node make terminal true node.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" # TODO current = self.root #"h e l l o" for i in range(len(string)): #if current does not have children: #insert new node with current #char in string #create a new node #add it as a child of current node #if there is a child the child is the letter of the string #current = that child #when I'm at the end of the string I want to make the last character terminal print(string[i]) if not current.has_child(string[i]): new_node = PrefixTreeNode(string[i]) current.add_child(string[i],new_node) print("Current", current) current = current.get_child(string[i]) print("Change to next") print("End", current) if current.terminal == False: self.size += 1 current.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" # check if tree has current string if not self.contains(string): # print(f"inserting: {string}") node = self.root for char in string: # check if the current char is already exists, if so skip the char if char.isalpha(): char = char.upper() else: continue # check if node has child for char if not node.has_child(char): # create a child node to be added child_node = PrefixTreeNode(char) # add the child node as a child to the current node node.add_child(char, child_node) # print(f"node: {node}: new child node: {child_node}") # child already exists, so we just continue traversing down else: child_node = node.get_child(char) # print(f'child node is there: {child_node}') # update the current node always node = child_node # set the last char in the string as a terminal node node.terminal = True # print(f"inserted: {string}") # increment the size by 1 once we inserted the whole string self.size += 1 else: print(f'String: {string} is already in the tree!')
def insert(self, string): """Insert the given string into this prefix tree.""" if self.contains(string) == False: current = self.root last_letter = len(string) - 1 self.size += 1 for char in string: if current.has_child(char) == True: current = current.get_child(char) else: if char == string[last_letter]: current.add_child(char, PrefixTreeNode(char)) current = current.get_child(char) current.terminal = True else: current.add_child(char, PrefixTreeNode(char)) current = current.get_child(char)
def insert(self, string): """Insert the given string into this prefix tree.""" # if self.contains(string): # return node = self.root for ch in string: if not node.has_child(ch): node.add_child(ch, PrefixTreeNode(ch)) node = node.children[ch] if not node.is_terminal(): self.size += 1 node.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" node = self.root for char in string: if node.has_child(char): node = node.get_child(char) else: node.add_child(char, PrefixTreeNode(char)) node = node.get_child(char) if not node.is_terminal(): self.size += 1 node.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" current = self.root #"h e l l o" for i in range(len(string)): if not current.has_child(string[i]): new_node = PrefixTreeNode(string[i]) current.add_child(string[i], new_node) current = current.get_child(string[i]) if current.terminal == False: self.size += 1 current.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" working_node = self.root for character in string: if working_node.has_child(character): working_node = working_node.get_child(character) else: new_node = PrefixTreeNode(character) working_node.add_child(character, new_node) working_node = new_node if not working_node.is_terminal(): working_node.terminal = True self.size += 1 # don't add to length if duplicate
def insert(self, string: str) -> None: """Insert the given string into this prefix tree.""" node = self.root for char in string: if node.has_child( char): # checks to see if the char exists already node = node.get_child(char) # next node else: node.add_child(char, PrefixTreeNode(char)) # new node node = node.get_child(char) # next node if not node.is_terminal(): self.size += 1 node.terminal = True # last node is terminal
def insert(self, string): """Insert the given string into this prefix tree.""" current_node = self.root for letter in string: if current_node.has_child(letter): current_node = current_node.get_child(letter) # continue # Move on to next letter else: current_node.add_child(letter, PrefixTreeNode(letter)) current_node = current_node.get_child(letter) # Check to make sure string has not already been added if current_node.terminal is False: self.size += 1 current_node.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" current = self.root up_string = string.upper() for letter in up_string: index = ord(letter) - 65 if current.children[index] is not None: current = current.children[index] continue current.add_child(letter, PrefixTreeNode(letter)) current = current.children[index] if not current.terminal: current.terminal = True self.size += 1
def insert(self, string): """Insert the given string into this prefix tree.""" node = self.root added = False for c in string: if not node.has_child(c): node.add_child(c, PrefixTreeNode(c)) node = node.get_child(c) added = True else: node = node.get_child(c) node.terminal = True if added: self.size += 1
def insert(self, string): """Insert the given string into this prefix tree.""" node = self.root for char in string: if node.has_child(char): # Search for child, and character is found node = node.get_child(char) # Node is there, move to the next node else: # Create a new node new_node = PrefixTreeNode(char) node.add_child(char, new_node) # Append new node node = new_node # point "head" to new new node and continue # if node is not terminal, increase word count, then set terminal to equal True if not node.is_terminal(): self.size += 1 node.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" # TODO if not self.contains(string): self.size += 1 node = self.root for i in range(len(string)): if not node.has_child(string[i]): new_node = PrefixTreeNode(string[i]) node.add_child(string[i], new_node) node = node.get_child(string[i]) if i == len(string) - 1: node.terminal = True
def insert(self, string): """Insert the given string into this prefix tree. Running-Time: O(n) where n is the length of string. Space-Complexity: 3*O(1) we instantiate a variable to traverse through prefixtree. """ cur_node = self.root unique = False for s in string: if s not in cur_node.children: unique = True cur_node.children[s] = PrefixTreeNode(s) cur_node = cur_node.children[s] cur_node.terminal = True if unique: self.size += 1
def insert(self, string): """Insert the given string into this prefix tree.""" last_added = self.root node_created = False for character in string: if last_added.has_child(character): last_added = last_added.get_child(character) else: new_node = PrefixTreeNode(character) last_added.add_child(character, new_node) last_added = new_node node_created = True last_added.terminal = True if node_created: self.size += 1
def insert(self, string): """Insert the given string into this prefix tree.""" current_node = self.root for char in string: # we add a node if not found in current node's children if not current_node.has_child(char): new_node = PrefixTreeNode(char) current_node.add_child(new_node) current_node = current_node.get_child(char) # only want to increment size if terminal is not False if not current_node.is_terminal(): self.size += 1 current_node.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" current_node = self.root # needs a list indice for indice in range(len(string)): # check if char exists in the list of the current node's children if string[indice] not in current_node.children: char = string[indice] # string[indice] is char # if not, create the node with the char current_node.children[indice] = PrefixTreeNode(char) current_node = current_node.children(char) current_node.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" # check if string is in tree if not self.contains(string): node = self.root for char in string: if not node.has_child(char): # add char if not in tree node.add_child(char, PrefixTreeNode(char)) self.size += 1 # get child node if/when in tree node = node.get_child(char) self.string_count += 1 node.terminal = True # last char in loop
def insert(self, string): """Insert the given string into this prefix tree.""" current_node = self.root # Current node for i in string: if current_node.has_child(i): # Found current_node = current_node.get_child(i) else: # CREATE new node new_node = PrefixTreeNode(i) current_node.add_child(i, new_node) current_node = new_node # Set terminal if not current_node.is_terminal(): self.size += 1 current_node.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" current = self.root new_string = False for character in string: if not current.has_child(character): node = PrefixTreeNode(character) current.add_child(character, node) new_string = True current = current.get_child(character) if new_string: # In case they try to add the same string self.size += 1 current.terminal = True
def insert(self, string): """Insert the given string into this prefix tree.""" node = self.root for character in range(len(string)): if node.has_child(character): node = node.get_child(character) else: newNode = PrefixTreeNode(character) node.add_child(character, newNode) node = newNode if not node.is_terminal(): node.terminal = True self.size += 1
def insert(self, string): """Insert the given string into this prefix tree.""" # Runs in roughly O(log n) time node, depth = self._find_node(string) if node is not None and node.terminal is True: return if depth == len(string): node.terminal = True self.size += 1 return terminus, _ = self._find_node(string[:depth]) for index in range(depth, len(string)): leaf = PrefixTreeNode(string[index]) terminus.add_child(string[index], leaf) terminus = leaf terminus.terminal = True self.size += 1
def insert(self, string): """Insert the given string into this prefix tree.""" node = self.root for char in string: # Search for the child if node.has_child(char): # found it so just traverse to next node node = node.get_child(char) else: # create new node and add it new_node = PrefixTreeNode(char) node.add_child(char, new_node) # traverse to next node node = new_node # set node to terminal and increment word count if the node is not already terminal if not node.is_terminal(): self.size += 1 node.terminal = True