zoukankan      html  css  js  c++  java
  • tire 学习心得

    一、碎语&心得

           下一周我准备学习 AC 自动机(这个名字是真的喜感不知道为什么要叫做 AC 自动机)。所以我要先学他的前置条件字典树,因为已经有了用数组模拟树的经验,再加上树也学了不少了而且字典树很简单。所以我的学习没有遇到什么困难,花了半个小时看了一会儿模板,在搞懂了几个关键点之后我就写出来了,代码量也比较小,在一些特定问题中对程序运行速度的优化也非常优秀,据我所知这个数据结构经常被用于搜索引擎,这个数据结构具有简单好用,代码量小,这两个优点,像树状数组一样。。而且查找只和字符串长度相关,与 n 无关,在数据量大且单词长度不长的情况下,肯定会比平衡查找树还优秀。

          虽然是我的心得但原理还是稍微记一下,到时候方便复习,而且万一有大佬浏览蒟蒻的心得呢,图就不配了(其实就是太麻烦了懒得整)。

    二、实现原理

         字典树其实是一颗根节点不存放数据的树,每个节点至多有 26 个孩子(用于字符串只包含 26 个字母的情况,当然大部分时候都是运用这种情况)他的原理就好像查字典一样,你要查 apple,肯定首先翻到 a 那一块去,然后在翻到第二个字母是 p 的那一页去等等等等。表现在代码里就是查找根节点有没有挂着 a 这个节点,再看 a 下面有没有挂着 p 这个节点。插入也同理,一个字母一个字母的来新建节点,如果已经建立了,那就直接跳过就行了,在查找时还要注意一件事,那就是标记挂着最后一个字母的节点为结束节点(其实字母挂在边上),不然插入 apple 之后查找 ap 也会返回真。

    三、代码

    头文件和主函数根本不重要就贴个类吧。

    c++代码:

    template<int T>
    class trie
    {
    private:
        int tree[T][30],cnt;
        bitset<T>mark;
    public:
        void insert(string a)
        {
            int r = 0;
            for(int i=0;i<a.size();i++)
            {
                int x = a[i]-'a';
                if(tree[r][x] == 0)
                {
                    tree[r][x] = ++cnt;
                }
                r = tree[r][x];
            }
            mark[r] = 1;
        }
        bool find(string a)
        {
            int r = 0;
            for(int i=0;i<a.size();i++)
            {
                int x = a[i]-'a';
                if(tree[r][x] == 0)
                {
                    return false;
                }
                r = tree[r][x];
            }
            return mark[r];
        }
        trie()
        {
            cnt = 0;
        }
    };

    因为我还在学习 java,所以我同时也用 java 写了一遍。

    java代码:

    public class trie 
    {
        private int[][] tree;
        private int cnt;
        private boolean[] mark;
        public trie(int size)
        {
            tree = new int[200010][size];
            mark = new boolean[200010];
            cnt = 0;
        }
        public void insert(String s)
        {
            int r = 0;
            for(int i = 0;i < s.length();i++)
            {
                int x = s.charAt(i) - 'a';
                if(tree[r][x] == 0)
                {
                    tree[r][x] = ++cnt;
                }
                r = tree[r][x];
            }
            mark[r] = true;
        }
        public boolean find(String s)
        {
            int r = 0;
            for(int i = 0;i < s.length();i++)
            {
                int x = s.charAt(i) - 'a';
                if(tree[r][x] == 0)
                {
                    return false;
                }
                r = tree[r][x];
            }
            return mark[r];
        }
    }

    同时还顺带学习了一下 java 的字符串和二维数组,java 没有重载运算符不能像数组一样用字符串类真的不方便,但是却能很好的区分数组和类,也算是有利有弊吧。

    有了这个下周我就可以学 AC 自动机了,想想还是挺兴奋的。

  • 相关阅读:
    vue 实现返回上一页不请求数据keep-alive
    vue+webpack 实现懒加载的三种方式
    深度解析使用CSS单位px、em、rem、vh、vw、vmin、vmax实现页面布局
    vue2.0中 怎么引用less?
    vue 自定义 提示框(Toast)组件
    Flex 布局教程实例
    Vue.js经典开源项目汇总
    Vue插件编写、用法详解(附demo)
    vue 项目 使用sass以及注意事项
    vue2.0+vue-video-player实现hls播放的案例
  • 原文地址:https://www.cnblogs.com/KALY/p/12442220.html
Copyright © 2011-2022 走看看