zoukankan      html  css  js  c++  java
  • 「模板」 后缀数组

    「模板」 后缀数组

    <题目链接>

    勉强理解吧,思路明白了但是代码很麻烦啊。

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int MAXN=1000010;
    char s[MAXN];
    int n,m=128,SA[MAXN],x[MAXN],y[MAXN],cnt[MAXN];
    void Print(int *a,int n)
    {
    	for(int i=0;i<n;++i)
    		printf("%d ",a[i]);
    	putchar('
    ');
    }
    void GetSA(void)
    {
    	for(int i=0;i<n;++i)
    		++cnt[x[i]=s[i]];
    	for(int i=1;i<m;++i)
    		cnt[i]+=cnt[i-1];
    	for(int i=n-1;i>=0;--i)
    		SA[--cnt[x[i]]]=i;
    	for(int k=1,p;k<=n,p<n/*继续倍增SA也不会改变时退出*/;k<<=1,m=p/*下次基数排序的最大值*/)
    	{
    		p=0;//利用SA排序第二关键字
    		for(int i=n-k;i<n;++i)
    			y[p++]=i;
    		for(int i=0;i<n;++i)
    			if(SA[i]>=k)
    				y[p++]=SA[i]-k;
    		//排第一关键字
    		memset(cnt,0,sizeof cnt);
    		for(int i=0;i<n;++i)
    			++cnt[x[y[i]]];
    		for(int i=1;i<m;++i)
    			cnt[i]+=cnt[i-1];
    		for(int i=n-1;i>=0;--i)
    			SA[--cnt[x[y[i]]]]=y[i];
    		//根据SA和y数组计算新的X数组
    		swap(x,y);
    		p=1,x[SA[0]]=0;
    		for(int i=1;i<n;++i)
    			x[SA[i]]=y[SA[i-1]]==y[SA[i]] && y[SA[i-1]+k]==y[SA[i]+k] ? p-1 : p++;
    	}
    }
    int main(int argc,char *argv[])
    {
    	scanf("%s",s);
    	n=strlen(s);
    	GetSA();
    	for(int i=0;i<n;++i)
    		printf("%d ",SA[i]+1);
    	putchar('
    ');
    	return 0;
    }
    

    谢谢阅读

  • 相关阅读:
    如何学习新技术
    创建模式之工厂方法模式
    SQL Server 存储过程
    ASP.NET Cache的一些总结
    ACE_TSS研究
    利用Thunk让C++成员函数变回调函数
    ACE内存映射学习
    ACE的初始化
    双检锁模式学习
    ACE_Task笔记
  • 原文地址:https://www.cnblogs.com/Capella/p/8258178.html
Copyright © 2011-2022 走看看