字符串匹配--最大最小表示法模板
2015-10-23 08:45
309 查看
最小(大)表示法是字符串问题中不同于匹配与失配的另一种O(n)的算法,它主要解决的是字符串的同构问题。将单个字符串循环左移右移算作该串的同构,最小(大)表示法能够在O(n)时间内求出这个串的所有同构串中的字典序最小的串的起始位置。由于代码简洁容易理解,因此在处理同类问题时往往比后缀数组以及各种匹配算法更加方便运用。
代码如下(注意下标是从0开始的,返回的下标也从0开始):
代码如下(注意下标是从0开始的,返回的下标也从0开始):
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxn=1e5+5; char s[maxn<<1]; inline int max(int a,int b){return a>b?a:b;} inline int min(int a,int b){return a<b?a:b;} int MINR(char s[],int l){ //s是原串(未加倍过),l是原串长 for(int i=0;i<l;++i)s[l+i]=s[i]; //将s串加倍 s[2*l]=0; int i=0,j=1; //利用i,j指针移动 while(i<l&&j<l){ int k=0; while(s[i+k]==s[j+k]&&k<l)++k; //不断比较直到比较完长度为l的串或两个子串不相等 if(k==l)return min(i,j); //若比较出长度为l则直接返回靠前的那个串的开始位置 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位置,因此取这两值的最大值 else j=max(j+k+1,i+1); //同上 } return min(i,j); //返回位置靠前的下标 } int MAXR(char s[],int l){ for(int i=0;i<l;++i)s[l+i]=s[i]; s[2*l]=0; int i=0,j=1; while(i<l&&j<l){ int k=0; while(s[i+k]==s[j+k]&&k<l)++k; if(k==l)return min(i,j); if(s[i+k]<s[j+k])i=max(i+k+1,j+1); else j=max(j+k+1,i+1); } return min(i,j); }
相关文章推荐
- POJ 1860——Currency Exchange——————【最短路、SPFA判正环】
- 1021. 个位数统计 (15)
- 第八周项目2-建立链串的算法库
- Android: LinearLayout布局和其嵌套运用举例
- github 远程仓库
- 九度OJ 1091:棋盘游戏 (DP、BFS、DFS、剪枝)
- PHP开发环境思考
- 九度OJ 1091:棋盘游戏 (DP、BFS、DFS、剪枝)
- 第八周 项目4-字符串加密
- 第七周项目4-队列数组
- 第七周项目4 - 队列数组
- 第七周 项目一 建立顺序环形算法库
- Sql 2005 维护笔记
- 第六周项目2建立链栈算法库
- 如何rename datafile name中存在乱码的数据文件
- vi/vim中替换大全
- datagrid报Cannot read property '' of null
- Linux-CenOS7 Samba的安装与配置
- ASP.NET- 使用NPOI导入导出标准Excel
- 第七周项目4-队列数组