Пример #1
0
    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
Пример #2
0
    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:]