• 后缀数组总结


    2009-10-25 09:05

    后缀数组是处理字符串的有力工具,后缀数组可以解决大多数后缀树解决的问题,由于它的实现要比后缀树简单,因此深受广大ACM爱好者的喜爱,当然还是有一些问题只有后缀树能解决的问题,等学习了后缀树再将其添上。后缀数组最常用的是求取最长公共前缀。

    后缀suffix数组,suffix【i】表示从第i个字符开始的后缀;

    后缀数组sa,保留1~n的某个排列,保证suffix【sa【i】】<suffix【sa【i】】,可以证明任何从不同位置开始的后缀不可能相等,这里不再证明。

    名词数组:名词数组rank【i】保存的是suffix【i】在所有后缀中从小到大排列的名次。简单的说,后缀数组是“排第几的是谁?”,名次数组时“你排第几?”。容易看出,后缀数组和名次数组互为逆运算。

    height数组,height【i】表示suffix【sa【i-1】】和suffix【sa【i】】的最长公共前缀,实际中往往应用最多的就是最长公共前缀,用其求取必要的东西。

    后缀数组可以解决的问题:

    一、单个字符串的问题:

    (1)       重复字串  

    例1:可重叠最长重复子串

    给定一个字符串,求最长重复子串,这两个子串可以重叠。

    算法:只要求出最大的height就可以了。

    例2:不可重叠最长重复子串(pku 1743)

    给定一个字符串,求最长重复子串,这两个子串不能重叠。

    算法:二分答案,变成判定性问题,二分代码和判定部分的代码,个人认为最重要的部分:

    int le=0,ri=nm-1;

    while(le<ri)

    {

             int mid=(le+ri+1)/2;

             if(ok(mid,nm)) le=mid;

             else ri=mid-1;

    }

    最后结果就是le+1;

    int ok(int len,int nm)

    {

             int i,mx=0,mi=nm;

             for(i=0;i<nm;i++)

             {

                       if(h[i]<len){ mx=0;mi=nm;}

                       else

                       {

                                mx=max(mx,sa[i]);

                                mx=max(mx,sa[i+1]);

                                mi=min(mi,sa[i]);

                                mi=min(mi,sa[i+1]);

                       }

                       if(mx-mi>len) return 1;

             }

             return 0;

    }

    例2:可重叠的k次最长重复子串(pku 3261)

    给定一个字符串,求出至少出现k次的最长重复子串,这k个子串可以重叠。

    还是二分判定了。

    判定部分的代码:

    int appk(int x,int k,int n)

    {

             int app=1,i;      

             for(i=0;i<n;i++)

             {

                       if(h[i]>=x)

                       {

                                app++;

                                if(app==k)

                                return 1;

                       }

                       else

                       app=1;

             }

             return 0;

    }

  • 相关阅读:
    浙大PAT CCCC L3-001 凑零钱 ( 0/1背包 && 路径记录 )
    二分图匹配
    Codeforces 939E Maximize ( 三分 || 二分 )
    冲刺第二周第七天
    冲刺第二周第六天
    冲刺第二周第五天
    构建之法阅读笔记04
    冲刺第二周第四天
    构建之法阅读笔记03
    构建之法阅读笔记02
  • 原文地址:https://www.cnblogs.com/ACAC/p/1743090.html
Copyright © 2020-2023  润新知