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


    最小(大)表示法是字符串问题中不同于匹配与失配的另一种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 }
  • 相关阅读:
    营山护照办理
    非北京人员 办理护照
    护照填写注意事项
    美国会议签证——我是正当理由去美国,我能支付(或有人为我支付)我在美国期间的所有费用,办完事我肯定回来, 邀请信,行程表这些材料齐全即可
    urllib2使用2
    python 异常
    python urllib和urllib2 区别
    python类继承
    gcc编译4个阶段
    Vim中如何全选并复制?
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4903387.html
Copyright © 2020-2023  润新知