后缀数组实现及模板详解

本文介绍了后缀数组的概念及其作用,通过基数排序对字符串后缀进行字典序排序,并探讨了后缀数组在求解最长公共前缀(LCP)问题中的应用。同时,文章提到了rank和height辅助数组,以及如何利用RMQ(Range Minimum Query)解决区间最值问题。作者分享了求解height数组的优化方法,并提供了算法理解过程中的个人心得。
摘要由CSDN通过智能技术生成

写在前面

首先要知道后缀数组的作用:将字符串的每一个后缀按照字典序进行排序,当然我们还可以进行其他的操作们可以求解相邻两个后缀之间最长的公共前缀的长度(LCP问题)

后缀数组

首先我们要明白基数排序,如果不明白的话可以看一下我的另一篇博客:基数排序的实现

当我们明白了基数排序之后,我们就可以看一下后缀数组的模板了:

//不怕别人比你聪明,就怕别人比你聪明还比你努力
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include <set>
#include <stack>
#include <map>
#include<vector>
#include <iterator>
#define INF 0x3f3f3f3f
#define ll long long

using namespace std;
const int MAXN = 500;
int n,w;
char str[MAXN];
int SA[MAXN];
int buc[MAXN];
int x[MAXN],y[MAXN],len;
//x数组表示第一元素,y数组表示第二元素

void da()
{
    //SA表示我排在第几位的是谁,SA[k] = i,排在第k位的是第i个后缀
    scanf("%s",str);
    len = strlen(str);
    int m = 127;//m表示第一次我们字符串的范围
    //在进行倍增之前首先对每一个元素进行一次基数排序,然后放到数组SA中
    for(int i =0 ;i < m;i ++) buc[i] = 0;
    for(int i =0 ;i < len;i ++) buc[x[i] = str[i]] ++;
    for(int i = 1;i < m;i ++) buc[i] += buc[i-1];
    for(int i = len-1;i >= 0;i --) SA[ -- buc[x[i]]] = i;
    for(int k = 1;k <= len; k <<= 1)    //进行倍增
    {
        int p = 0;
        for(int i = len - 1; i >= len -k; i --) y[p++] = i;    //我们要得到第二元素,因为要向后移动k个,所以这里表示的是添零操作
        //因为零一定会排在最前面,所以y[p++] = i;表示排在第p位的是第i个后缀,表示的就是最后面的后缀
        for(int i = 0;i < len;i ++) if(SA[i] >= k) y[p++] = SA[i] - k;   //然后我们删除前面几个跳过的元素,这些跳过的元素都是在k之前的,也就是SA[i] < k
        //比如我们要排序的数是:92,81,30,24,57,96;
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值