• HDU1251 裸字典树 +HDU 2846 统计子串出现次数


    HDU1251:http://acm.hdu.edu.cn/showproblem.php?pid=1251

    初学字典树,码模板……

    #include<iostream>
    #include<string.h>
    using namespace std;
    char a[15];
    struct node {
        node *nextt[26];
        int v=0;
    };
    node root;
    void init()
    {
        for (int i = 0; i < 26; i++)
        {
            root.nextt[i] = NULL;
        }
    }
    void creatree()
    {
        int len = strlen(a);
        node *p = &root,*q;
        for (int i = 0; i < len; i++)
        {
            int id = a[i] - 'a';
            if (p->nextt[id] == NULL)
            {
                q = (node*)malloc(sizeof(node));
                q->v = 1;
                for (int j = 0; j < 26; j++)
                    q->nextt[j] = NULL;
                p->nextt[id] = q;
                p = p->nextt[id];
            }
            else {
                p->nextt[id]->v++;
                p = p->nextt[id];
            }
        }
    }
    int find()
    {
        int len = strlen(a);
        node *p = &root;
        for (int i = 0; i < len; i++)
        {
            int id = a[i] - 'a';
            p = p->nextt[id];
            if (p == NULL) return 0;
        }
        return p->v;
    }
    int main()
    {
        init();
        while (gets(a) && a[0] != '')
            creatree();
        while (cin >> a)
        {
            cout << find() << endl;
        }
        return 0;
    }

     HDU 2846  http://acm.hdu.edu.cn/showproblem.php?pid=2846

    字典树原本是按前缀搜索的,题中所要求查询的并不一定是字符串的前缀,但我们可以将前缀转化为后缀处理,搜索子串的长度len已知,即便是不同后缀,只要搜索子串第一个后缀前len个字符即可。

    orz想了好久,还是参考了大佬的题解,膜拜大佬做法,一语道破天机

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    using namespace std;
    char a[25];
    int len;
    struct node {
        node *nextt[26];
        int v;
        int mark;
        node()   //加个构造函数,下面设node变量的时候就不用再初始化nextt数组了
        {
            v= 0;
            mark = -1;
            for (int i = 0; i < 26; i++)
                nextt[i] = NULL;
        }
    };
    node *root = new node();
    void creat(int i,int j)   //j标记当前所访问的字符串
    {
        node *p = root;
        for (; i < len; i++)
        {
            int id = a[i] - 'a';
            if (p->nextt[id] == NULL)
            {
                p->nextt[id]= new node();
                p = p->nextt[id];
                p->mark = j;
                p->v = 1;
            }
            else 
            {
                p = p->nextt[id];
                if (p->mark != j)    //在mark!=j的时候更新v,避免同一母串的部分前缀相同的子串多次更新,比如add
                {
                    p->mark = j;
                    p->v++;
                }
            }
        }
    }
    int find()
    {
        node *p = root;
        for (int i = 0; i < len; i++)
        {
            int id = a[i] - 'a';
            if (p->nextt[id] == NULL) return 0;
            p = p->nextt[id];
        }
        return p->v;
    }
    int main()
    {
        int n;
        cin >> n;
        while (n--)
        {
            cin >> a;
            len = strlen(a);
            for(int i=0;i<len;i++)
            creat(i,n);
        }
        cin >> n;
        while (n--)
        {
            cin >> a;
            len = strlen(a);
            cout << find() << endl;
        }
        return 0;
    }
  • 相关阅读:
    设备树实践
    设备树实例解析
    设备树语法
    设备树基本概念
    设备树中#address-cells和#size-cells作用
    Linux设备驱动详解 宋宝华 硬件基础
    jffs2镜像制作
    ltp-ddt eth_iperf_tcp iperf dualtest遇到的问题
    shell 函数传递参数的几种方式
    windows logstash配置
  • 原文地址:https://www.cnblogs.com/Egoist-/p/7429362.html
Copyright © 2020-2023  润新知