zoukankan      html  css  js  c++  java
  • 【挑战程序设计竞赛】后缀数组 实现字符串匹配

    字符串后缀Suffix 指的是从字符串的某个位置开始到其末尾的字符串字串

    后缀数组 Suffix Array 指的是将某个字符串的所有后缀按字典序排序之后得到的数组,不过数组中不直接保存所有

    的后缀子串,只要记录相应的位置就好了。

    下面的代码使用倍增法来构造后缀数组,该算法的复杂度是 O(n log n)常数因子比较大。

    基于后缀数组的字符串匹配,我们可以通过二分搜索来完成,算法复杂度是 O(|T|log|S|) 其中 S 是主串,T是模式串

    具体的后缀数组的原理可以详细去看看国家队集训的论文,罗穗骞《后缀数组——处理字符串的有力工具》:

    #include <iostream>
    #include <cstring>
    #include <cstddef>
    #include <cstdio>
    #include <string>
    #include <algorithm> 
    
    using namespace std;
    const int MAXN = 10001;
    int n,k;
    int rank[MAXN+1],tmp[MAXN+1];
    
    bool comp_sa(int i, int j)
    {
    	if(rank[i] != rank[j]) 
    		return rank[i] < rank[j];
    	int ri = i+k <= n? rank[i+k] : -1;
    	int rj = j+k <= n? rank[j+k] : -1;
    	return ri < rj; 
    }
    
    void calc_sa(string &S, int *sa) //计算字符串S的后缀数组 
    {
    	n = S.size();
    	
    	//初始长度为1 
    	for(int i = 0; i <= n; i++)
    	{
    		sa[i] = i;
    		rank[i] = i < n ? S[i] : -1;
    	}
    	
    	for( k =1; k <= n; k *= 2)
    	{
    		sort(sa,sa+n+1,comp_sa);
    		
    		//先在tmp中临时存储新计算的rank,再转存回rank中 
    		tmp[sa[0]] = 0;
    		for(int i = 1; i <= n; i++)
    		{
    			tmp[sa[i]] = tmp[sa[i-1]] + (comp_sa(sa[i-1],sa[i]) ? 1: 0);
    		}
    		for(int i = 0; i <= n; i++)
    		{
    			rank[i] = tmp[i];
    		}
    	}
    }
    
    void SuffixArrayMatch(string &S, int *sa, string T)
    {
    	calc_sa(S,sa);
    	int lhs = 0, rhs = S.size();
    	
    	//使用二分查找 
    	while(rhs - lhs > 1)
    	{
    		int mid = (lhs + rhs)>>1;
    		int res = S.compare(sa[mid],T.size(),T); 
    		if(res < 0)
    			lhs = mid;
    		else if(res == 0) 
    		{
    			cout<<"match at: "<<sa[mid]<<endl;
    			lhs = mid;
    		}
    		else rhs = mid;
    	}
    }
    int main()
    {
    	string S = "abracadabra";
    	string T = "ab";
    	int *sa = new int[S.size()+1];
     	SuffixArrayMatch(S,sa,T);
     	delete [] sa;
     	sa = NULL;
    }


  • 相关阅读:
    c++指向数组的指针,数组指针
    c#和c++互操作(平台调用相关)
    LA和TA
    RSCP RSRP RSRQ
    HARQ(Hybrid Automatic Repeat Request ) 混合自动重传请求
    传输层的几个部分的ALCAP、SSCOP、MTP3-B、SCCP、SAAL、SCCF、STC、IP、UDP、GTPU
    SSCOP Service Specific Connection Oriented Protocol 业务特定面向连接协议
    SSCF-UNI
    PCRF、PCEF、PCC(转帖)
    LTE中的几个概念——LTE,SAE,EPC,EPS
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3356097.html
Copyright © 2011-2022 走看看