def bad_insert(self, string): # Scenarios: 1. no child for that character 2. full match 3. partial match # 1. Add suffix as new child (example: adding 'Skylar' to an 'S' node with no 'k' children) # 2. Add node in after match # 3. Break the child node into two parts wherever the split occurs # Example: Adding 'Sasha' to 'S' -> 'am' # Break 'am' into 'a' -> 'm', with 'm' keeping all of previous 'am' 's childrien # New paths are 'S' -> 'A' -> 'Sha' and S -> 'A' -> 'M' """Insert the given string into this prefix tree.""" current_node = self.root current_string = string[:] while current_string[0] in current_node.children: print(current_node) current_node = current_node.children[current_string[0]] print("current_node is now", current_node) print("comparing", current_node, string) no_match_index = 1 for i in range( 1, min(len(current_string), len(current_node.full_path))): if current_string[i] == current_node.full_path[i]: no_match_index += 1 else: break if no_match_index < len(current_node.full_path): print("partial match, fail at index", no_match_index) # use index of where new string and old string diverge to get new paths new_split_string = current_string[0:no_match_index] remainder = current_string[no_match_index:] old_remainder = current_node.full_path[no_match_index:] #current node's new path is current_node.full_path = new_split_string current_node.terminal = False # old child getting new assignment if necessary print("current_node", current_node) print("current_node children", current_node.children) split_child = PrefixTreeNode(old_remainder) # if old children exists then old child split due to new string if current_node.full_path[0] in current_node.children: print("##@#@$%%@@old child exists") old_child_children = old_child.children split_child.terminal = old_child.terminal split_child.children = old_child_children else: split_child.terminal = True # Remove old child, add new child #current_node.children[current_string[0]] = None #current_node.children.pop(current_string[0]) current_node.children[old_remainder[0]] = split_child # add new node new_child = PrefixTreeNode(remainder) new_child.terminal = True current_node.children[remainder[0]] = new_child print("***********") print("new node at this point is", current_node) print("children at", current_node.children) for child in current_node.children: print(child) print(current_node.children[child].terminal) print("***********") self.size += 1 return elif no_match_index == len(current_node.full_path): print("full match") current_node = current_node.children[ current_string[no_match_index]] current_string = current_string[no_match_index:] # at node to insert at after while loop print("arrived at final parent node", current_node) print("string is", current_string) current_string = current_string[len(current_node.full_path):] new_node = PrefixTreeNode(current_string) new_node.terminal = True current_node.children[current_string[0]] = new_node print("***********") print("current_node is", current_node) print("children at", current_node.children) print("***********") self.size += 1
def insert(self, string): current_node = self.root current_string = string[:] while True: #print("comparing",current_node.full_path,"to",current_string) #print("comparing",current_node.children,"to",current_string) try: current_node = current_node.children[current_string[0]] #print("child exists for",current_string[0],"moving to that node") except KeyError: # No more matching edges, add new node #print("child does NOT exist for",current_string[0],"creating that node") new_node = PrefixTreeNode(current_string) new_node.terminal = True current_node.add_child(current_string[0], new_node) self.size += 1 return #print("checking for partial match for",current_node.full_path,"to",current_string) # Perfect match, make terminal if not already if current_string == current_node.full_path: #print("node is terminal:",current_node.terminal) if (current_node.terminal == False): self.size += 1 current_node.terminal = True return first_mismatch_index = 1 for i in range( 1, min(len(current_string), len(current_node.full_path))): if (current_string[i] == current_node.full_path[i]): first_mismatch_index += 1 #print("first_mismatch_index is",first_mismatch_index) # String partially matches to an existing node if len(current_string) < len( current_node.full_path) or first_mismatch_index < len( current_node.full_path): #print("partial match, fail at index",first_mismatch_index) # child_1 is modified old child or new child that follows old path # child_2 is new child with remainder of string new_path = current_node.full_path[0:first_mismatch_index] child_1_path = current_node.full_path[first_mismatch_index:] child_2_path = current_string[first_mismatch_index:] # set up new nodes and paths current_node.full_path = new_path child_1 = PrefixTreeNode(child_1_path) child_1.terminal = current_node.terminal # transfer current_node's previous children to child_1 #print("current_node is",current_node) #print("children are",current_node.children) to_remove = [] for key in current_node.children: child_1.children[key] = current_node.children[key] to_remove.append(key) for item in to_remove: del current_node.children[item] # add children to current_node current_node.children[child_1_path[0]] = child_1 if (len(child_2_path) > 0): child_2 = PrefixTreeNode(child_2_path) child_2.terminal = True current_node.children[child_2_path[0]] = child_2 current_node.terminal = False else: current_node.terminal = True self.size += 1 return # Node continues on path else: #print("node continuing") current_string = current_string[first_mismatch_index:]