python 实现 tire树的相关操作

题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

from TrieNodeAbstract import TrieNodeAbstract
from ChildrenDictionary import ChildrenDictionary
import math
from typing import Dict, List, Union

# For help in traversing children
ALPHABET = 'abcdefghijklmnopqrstuvwxyz'


class TrieTree(TrieNodeAbstract):
    def __init__(self, char='', value: str = ''):
        '''
        Initializes:
            This node's char, `self._char`, ie. your current character in the key
            This node's set of subtrees, 'children', using a dictionary
            This node's value, `self._value`  only set iff its a valid word in the dictionary
        '''
        self._value = value
        self._children: ChildrenDictionary = ChildrenDictionary()
        self._char = char

    # TASK 1
    def insert(self, word: str) -> None:
        '''
        Insert your new word, keep in mind, you must insert all child nodes
        >>> trie = TrieTree()
        >>> trie.insert("word")
        >>> trie.insert("water")
        >>> trie.insert("banana")
        >>> "word" in str(trie)
        True
        >>> "water" in str(trie)
        True
        >>> "bob" in str(trie)
        False
        >>> "banana" in str(trie)
        True
        '''

        cur = self
        for c in word:
            if c not in cur._children:
                cur._children[c] = TrieTree()
            cur = cur._children[c]
            cur._char = c
        cur._value = word
        # raise NotImplementedError

    # TASK 2
    def __contains__(self, key: str):
        '''
        Returns True iff key is in tree, otherwise False
        >>> trie = TrieTree()
        >>> trie.insert("word")
        >>> "word" in trie
        True
        >>> "other" in trie
        False
        '''
        # TODO
        cur = self
        for c in key:
            if c not in cur._children:
                return False
            cur = cur._children[c]
        return (bool)(cur._value)

        # raise NotImplementedError

    # TASK 3
    def __delitem__(self, key: str):
        '''
        Deletes entry in tree and prunes unecessary branches if key exists, otherwise changes nothing
        >>> trie = TrieTree()
        >>> trie.insert("word")
        >>> "word" in trie
        True
        >>> del trie["word"]
        >>> "word" in trie
        False
        >>> str(trie)
        'TrieTree'
        >>> trie.insert('ab')
        >>> trie.insert('abs')
        >>> str(trie)
        'TrieTree\\n   `- a\\n      `- b : ab\\n         `- s : abs'
        >>> del trie['ab']
        >>> str(trie)
        'TrieTree\\n   `- a\\n      `- b\\n         `- s : abs'
        '''

        # TODO
        if not self.__contains__(key):
            return False
        cur = self
        cur2 = self
        last1 = self
        last2 = self
        ch = key[0]
        for c in key:
            if c in cur._children:
                if(len(cur._children)>1):
                    cur2 = cur
                    ch = c
                cur = cur._children[c]

                if ((bool)(cur._value) & (last1 == self)):
                    last1 = cur
                elif ((bool)(cur._value) & (last1 != self) & (last2 == self)):
                    last2 = cur
                elif ((bool)(cur._value) & (last1 != self) & (last2 != self)):
                    last1 = last2
                    last2 = cur
        if last2 == self:
            if cur._children:
                cur._value = ''
            else:
                cur2._children.pop(ch)
        else:
            if last2._children:
                last2._value = ''
            else:
                last1._children = ChildrenDictionary()

        # raise NotImplementedError

    # TASK 4
    def get_completion_words(self, pre_string):
        word_list = []
        # 叶节点退出递归,返回完整字符串
        if self._value:
            word_list.append(pre_string)
            # return word_list
        # 通过字典树的每个分支对之前的字符串进行补充
        for c in self._children:
            cur = self._children[c]
            word_list.extend(cur.get_completion_words(pre_string + str(c)))
        # 返回最终结果
        return word_list

    def sort(self, decreasing=False):
        '''
        Returns list of words in tree sorted alphabetically
        >>> trie = TrieTree()
        >>> trie.insert('banana')
        >>> trie.insert('cherry')
        >>> trie.insert('apple')
        >>> trie.sort()
        ['apple', 'banana', 'cherry']
        >>> trie.sort(decreasing=True)
        ['cherry', 'banana', 'apple']
        '''
        # TODO
        if (decreasing == False):
            ans = self.get_completion_words('')
            ans.sort()
            return ans
        if (decreasing):
            ans = self.get_completion_words('')
            ans.sort(reverse=True)
            return ans

    # TASK 5
    def autoComplete(self, prefix, N=10):
        '''
        if given a valid prefix, return a list containing N number of suggestions starting with that prefix in alphabetical order
        else return an empty list
        >>> trie = TrieTree()
        >>> trie.insert('apple')
        >>> trie.insert('dad')
        >>> trie.insert('apples')
        >>> trie.insert('application')
        >>> trie.insert('app')
        >>> trie.insert('about')
        >>> trie.autoComplete('a')
        ['about', 'app', 'apple', 'apples', 'application']
        >>> trie.autoComplete('a', N=2)
        ['about', 'app']
        >>> trie.autoComplete('app')
        ['app', 'apple', 'apples', 'application']
        >>> trie.autoComplete('c')
        []
        >>> trie.autoComplete('d')
        ['dad']
        '''

        # TODO
        cur = self
        # last = cur
        for c in prefix:
            if c in cur._children:
                # last = cur
                cur = cur._children[c]
        if (cur == self):
            return []
        a = cur.sort()
        b = []
        if len(a) <= N:
            for str in a:
                str = prefix + str
                b.append(str)
        else:
            a = a[0:N]
            for str in a:
                str = prefix + str
                b.append(str)
        return b
        # raise NotImplementedError

    # TASK 6
    def autoCorrect(self, word, errorMax = 2):
        '''
        Given a word, if misspelt return a list of possible valid words from the last valid prefix, with up to errorMax errors
        >>> trie = TrieTree()
        >>> trie.insert('dab')
        >>> trie.autoCorrect('dod')
        ['dab']
        >>> trie.autoCorrect('dod', errorMax=1)
        []
        >>> trie.autoCorrect('dad', errorMax=1)
        ['dab']
        >>> trie.insert('apple')
        >>> trie.insert('dad')
        >>> trie.insert('dude')
        >>> trie.insert('apples')
        >>> trie.insert('application')
        >>> trie.insert('app')
        >>> trie.insert('about')
        >>> trie.insert("apples")
        >>> trie.insert("application")
        >>> trie.insert('app')
        >>> trie.insert('apple')
        >>> sorted(trie.autoCorrect('apl', errorMax=10))
        ['app', 'apple', 'apples', 'application']
        >>> trie.autoCorrect('aboot')
        ['about']
        >>> sorted(trie.autoCorrect('dea'))
        ['dab', 'dad']
        >>> sorted(trie.autoCorrect('dod'))
        ['dab', 'dad', 'dude']
        >>> sorted(trie.autoCorrect('dea', errorMax=3))
        ['dab', 'dad', 'dude']
        '''
        # TODO
        i4 = 0
        ans = []
        cur22 = self
        for c1 in word:
            if c1 in cur22._children:
                cur22 = cur22._children[c1]
                i4 = i4+1
            else:
                break
        becompared = cur22.sort()
        word2 = word[i4:]
        while becompared:
            error = 0
            len1 = len(word2)
            len2 = len(becompared[0])
            len3 = min(len1,len2)
            len4 = max(len1,len2)
            for i in range(len3):
                if(word[i] != becompared[0][i]):
                    error = error+1
            error = error+(len4-len3)
            if error<=errorMax:
                ans.append(becompared[0])
            becompared.pop(0)
        for i3 in range(len(ans)):
            ans[i3] = word[:i4] + ans[i3]
        return ans
        # raise NotImplementedError

    # TASK 7
    def merge(self, otherTrie: TrieNodeAbstract):
        '''
        Merges another TrieTree into this one
        >>> trie1 = TrieTree()
        >>> trie2 = TrieTree()
        >>> trie1.insert('amazing')
        >>> trie2.insert('amazon')
        >>> trie1.merge(trie2)
        >>> 'amazon' in trie1
        True
        '''
        # TODO
        temp = otherTrie.sort()
        while temp:
            self.insert(temp[0])
            temp.pop(0)
        # raise NotImplementedError

    def pPrint(self, _prefix="", _last=True, index=0):
        '''
        DONT CHANGE THIS
        '''
        ret = ''
        if index:
            ret = _prefix + ("`- " if _last else "|- ") + self._char
            _prefix += "   " if _last else "|  "
            if self._value:
                ret += ' : ' + str(self._value)
            ret += '\n'
        else:
            ret = _prefix + "TrieTree"
            _prefix += "   " if _last else "|  "
            ret += '\n'
        child_count = len(self._children)
        for i, child in enumerate(self._children):
            _last = i == (child_count - 1)
            ret += self._children[child].pPrint(_prefix, _last, index + 1)
        return ret

    def __str__(self):
        return self.pPrint().strip()


if __name__ == '__main__':
    import doctest

    doctest.testmod()
    '''
    trie = TrieTree()

    trie.insert('deal')

    trie.insert('dear')
    trie.insert('do')

    trie.insert('heat')
    trie.insert('hen')

    trie.insert('he')

    # trie.__str__()
    # trie.__delitem__('he')
    # a = trie.__contains__('he')

    # a = trie.sort(True)
    # a = trie.sort(False)
    b = trie.autoComplete('he')
    print(b)
    '''

这个代码里面的task1到task7是需要完成的函数,其他的函数是不需要更改的。当然了,这个代码是不完整的,还有其他的一些.py文件,可以从这里下载完整的代码学习。

用python去对tire树进行操作,这个项目是很全面的。 谢谢使用

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

指针的值是地址

觉得还不错,我会继续努力的。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值