输入提示 数据算法 Trie

基本功能

在这里插入图片描述

  1. 实现上述功能,输入提示
  2. 数据结构:Trie 字典树 多叉树 根节点为空值
  3. 缺点:数据要求比较高,会占用大量的空间。例如:26个字母,组成完全的 Trie树的话,就会有26层,总共有26的26次方个节点
  4. 不仅仅可以实现这种功能,类似于有共同前缀的数据,也可以 以这种方式实现

实现代码

from copy import deepcopy
from collections.abc import Iterable
from collections import defaultdict


class Trie:
    def __init__(self, nodes: Iterable):
        """

        :param nodes: list or str,可以为一个多个节点或是一个节点
        """
        self.tree = defaultdict(dict)
        self.depth = 0
        self.init_tree(nodes)

    def insert_node(self, i, node, len_node, tree):
        """
        插入元素
        :param i: 元素的第几个字符
        :param node: 元素
        :param len_node: 元素长度
        :param tree: 树结构
        :return:
        """
        if node[i] in tree:
            self.insert_node(i + 1, node, len_node, tree[node[i]])
        else:
            tree[node[i]] = defaultdict(dict)
            if len_node > i + 1:
                self.insert_node(i + 1, node, len_node, tree[node[i]])

    def init_tree(self, nodes):
        """
        插入元素
        :param nodes: 可迭代对象,对应要插入的元素
        :return:
        """
        if isinstance(nodes, Iterable):
            for node in nodes:
                len_node = len(node)
                if len_node > self.depth:
                    self.depth = len_node
                self.insert_node(0, node, len_node, self.tree)
        else:
            raise ValueError

    def get_level(self, c_tree: dict, result: list, add_signal, path=None):
        """
        获取需要新添加的数据
        :param c_tree: 原始数据
        :param result: 结果
        :param path:
        :param add_signal: 需要添加到结果的条件
        :return:
        """
        if path is None:
            path = []
        for k, v in c_tree.items():
            path_new = deepcopy(path)
            path_new.append(k)
            if add_signal(k, v):
                result.append(path_new)
            if v:
                self.get_level(v, result, add_signal, path=path_new)

    def __find_word(self, i, node, len_node, tree):
        if node[i] in tree:
            if i + 1 < len_node:
                tree = self.__find_word(i + 1, node, len_node, tree[node[i]])
            return tree

    def find_word(self, word):
        """
        获取提示
        """
        len_word = len(word)
        if len_word > self.depth:
            return [word]
        last_tree = self.__find_word(0, word, len_word, self.tree)
        if last_tree is None:
            return []
        result = list()
        self.get_level(last_tree[word[-1]], result, lambda k, v: not v)
        return [word + ''.join(r) for r in result]


if __name__ == '__main__':
    trie = Trie(['hello', 'her', 'hi', 'how', 'so', 'see', 'some', 'solr'])
    print(trie.find_word('s'))
    print(trie.find_word('so'))
    print(trie.find_word('som'))
    print(trie.find_word('some'))
    print(trie.find_word('something'))
    print(trie.find_word('y'))

    trie = Trie([('中国', '北京', '海淀'), ('美国', '华盛顿', '特区')])


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值