zoukankan      html  css  js  c++  java
  • Trie

    传说中的字典树,来学习一下

    实现字符串快速检索的多叉树结构

    基本操作过程

    1.初始化

    一个空Trie仅包含一个根节点,该点的字符指针为空

    2.插入

    当需要插入一个字符串S时,令一个指针P起初指向根节点,然后依次扫描S中的每个字符c

    1)若P的c字符指针指向一个已经存在的节点Q,则令P=Q;

    2)若P的c字符指针为空,则新建一个节点Q,令P的c字符指针指向Q,然后令P=Q;

    当S中的字符扫描完毕,在当前节点P上标记它是一个字符串的末尾//?

    3.检索

    当需要检索一个字符串S在Trie中是否存在,我们令一个指针P起初指向根节点,然后依次扫描S中的每个字符c:

    1)若P的c字符指针指向一个已经存在的节点Q,则令P=Q;

    2)若P的c字符指针为空,说明S没有被插入过,结束检索;

    当S的字符扫描完毕,若当前节点P被标记为一个字符串末尾,则说明S在Trie中存在。否则,不存在。

    下给出插入检索代码:

    int trie[SIZE][26],tot=1;//初始化,假设每个字符都是小写字母
    void insert(char *str){//插入
              int len =strlen(str),p=1;
              for(int k=0;k<len;k++){
                    int ch=str[k]-'a';
                    if(trie[p][ch]==0)trie[p][ch]=++tot;//tot定位下一个字母位置
                    p=trie[p][ch];
             }
             end[p]=true;
    }
    bool search(char *str)//检索
    {
            int len=strlen(str),p=1;
            for(int k=0;k<len;k++){
                p=trie[p][str[k]-'a'];
                if(p==0)return false;
            }
            return end[p];
    }

     前缀统计

    #include<bits/stdc++.h>
    using namespace std;
    #define SIZE 1000010
    int trie[SIZE][26];
    int tot=1;
    int ed[SIZE];
    int ans=0;
    void insert(char *s)
    {
        int len=strlen(s);
        int p=1;
        for(int i=0;i<len;i++){
            if(trie[p][s[i]-'a']==0){
                trie[p][s[i]-'a']=++tot;
            }
            p=trie[p][s[i]-'a'];
            
        }
        ed[p]++;
    }
    void search(char *s)
    {
        int len=strlen(s);
        int p=1;
        for(int i=0;i<len;i++){
            if(trie[p][s[i]-'a']==0){
                return;
            }
            p=trie[p][s[i]-'a'];
            ans+=ed[p];  
        }
        //ans+=end[p];
        
    }
    char s[1000010];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++){
            scanf("%s",s);
            insert(s);
        }
        for(int i=0;i<m;i++){
             scanf("%s",s);
            ans=0;
            search(s);
            
            cout<<ans<<'
    ';
        }
        
    }

      最大异或对

    沿与Ai当前位置相反的字符指针向下访问

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll A[100005];
    ll ed[4200005];
    int B[4200005][2];
    int tot=1;
    int F[32];
    void div(ll x)
    {
        int i=0;
        while(x){
            if(x&1){
                F[i]=1;
            }
            else F[i]=0;
            x>>=1;
            i++;
        }
        while(i<32){
            F[i]=0;
            i++;
        }
        
    }
    void insert(ll x)
    {
        int p=1;
        div(x);
        for(int i=0;i<32;i++){
           if(!B[p][F[31-i]]){
               B[p][F[31-i]]=++tot;
           }
           
           p=B[p][F[31-i]];
        }
        ed[p]=x;
    }
    ll search(ll x)
    {
        int p=1;
        div(x);
        for(int i=0;i<32;i++){
            if(B[p][!F[31-i]]){
                p=B[p][!F[31-i]];
            }
            else p=B[p][F[31-i]];
           
        }
        return x^ed[p];
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%lld",&A[i]);
            insert(A[i]);
        }
        ll ans;
        for(int i=0;i<n;i++){
            if(i==0)ans=search(A[0]);
            else
            ans=max(ans,search(A[i]));
        }
        cout<<ans<<'
    ';
        
    }

     

  • 相关阅读:
    hdu 1253
    poj 2531 Network Saboteur
    rwkj 1501 数据结构:图的DFS遍历
    rwkj 1306 素数========拓展
    nyist 91 阶乘之和
    nyist 65 另一种阶乘问题
    nyist 31 5个数求最值
    nyist 22 素数求和
    向量 vector
    字符串 统计 ,删除,连接,变换
  • 原文地址:https://www.cnblogs.com/liulex/p/11230942.html
Copyright © 2011-2022 走看看