字符串匹配--最大最小表示法模板

最小(大)表示法是字符串问题中不同于匹配与失配的另一种O(n)的算法,它主要解决的是字符串的同构问题。将单个字符串循环左移右移算作该串的同构,最小(大)表示法能够在O(n)时间内求出这个串的所有同构串中的字典序最小的串的起始位置。由于代码简洁容易理解,因此在处理同类问题时往往比后缀数组以及各种匹配算法更加方便运用。

代码如下(注意下标是从0开始的,返回的下标也从0开始):

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int maxn=1e5+5;
 7 char s[maxn<<1];
 8 
 9 inline int max(int a,int b){return a>b?a:b;}
10 inline int min(int a,int b){return a<b?a:b;}
11 
12 int MINR(char s[],int l){        //s是原串(未加倍过),l是原串长
13     for(int i=0;i<l;++i)s[l+i]=s[i];    //将s串加倍
14     s[2*l]=0;
15     int i=0,j=1;                    //利用i,j指针移动
16     while(i<l&&j<l){
17         int k=0;
18         while(s[i+k]==s[j+k]&&k<l)++k;    //不断比较直到比较完长度为l的串或两个子串不相等
19         if(k==l)return min(i,j);        //若比较出长度为l则直接返回靠前的那个串的开始位置
20         if(s[i+k]>s[j+k])i=max(i+k+1,j+1);    //i串比j串大,那么i到i+k中的串都比j串大,i可以直接移动到i+k+1位置,而起始位置比j小的肯定都在j移动过程中比较过,所以i可以直接移动到j+1位置,因此取这两值的最大值
21         else j=max(j+k+1,i+1);    //同上
22     }
23     return min(i,j);            //返回位置靠前的下标
24 }
25 
26 int MAXR(char s[],int l){
27     for(int i=0;i<l;++i)s[l+i]=s[i];
28     s[2*l]=0;
29     int i=0,j=1;
30     while(i<l&&j<l){
31         int k=0;
32         while(s[i+k]==s[j+k]&&k<l)++k;
33         if(k==l)return min(i,j);
34         if(s[i+k]<s[j+k])i=max(i+k+1,j+1);
35         else j=max(j+k+1,i+1);
36     }
37     return min(i,j);
38 }

 

转载于:https://www.cnblogs.com/cenariusxz/p/4903387.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值