串的模式匹配

来源:互联网 发布:超级优化全本下载 编辑:程序博客网 时间:2024/05/21 03:26

问题描述:

       对于两个字符串A,B。请设计一个高效算法,找到B在A中第一次出现的起始位置。若B未在A中出现,则返回-1。
给定两个字符串A和B,及它们的长度lena和lenb,请返回题目所求的答案。
测试样例:
"acbc",4,"bc",2
返回:2


      思路:1,该类型题目的一般思路是暴力求解,采用两层循环,我们会从A[0] 跟B[0] 匹配,如果相等则匹配下一个字符,直到出现不相等的情况,此时我们会简单的丢弃前面的匹配信息,然后从A[1] 跟 B[0]匹配,循环进行,直到主串结束,或者出现匹配的情况。这种简单的丢弃前面的匹配信息,造成了极大的浪费和低下的匹配效率。时间复杂度是o(nlogn)。

(暴力方法)AC代码如下:

class StringPattern {public:    int findAppearance(string A, int lena, string B, int lenb) {        // write code here        int i,j,k;        for(i=0;i<lena;i++){            k=i;            for(j=0;j<lenb;j++,k++)                if(A[k]!=B[j])                  break;            if(j==lenb)                return i;        }        return -1;    }};

       2,采用KMP算法,可以使时间复杂度降低到o(m+n)。

       网上关于KMP算法的介绍有很多,我在这里简单介绍一下思路:

      我们需要一个辅助数组next[],用于存放我们事先计算的模式串的内部匹配信息,在匹配失败时最大的移动模式串,以减少匹配次数。next数组的长度和模式串的长度是一样的,next在位置index中存放的内容是模式串的index位置之前的整个子串的最长的相同的前缀和后缀的长度。右移的距离是如此计算的:在已经匹配的模式串子串中,找出最长的相同的前缀和后缀,然后移动使它们重叠。·

      模式匹配过程中,如果主串和模式串的对应字符相等,则主串下标和模式串下标均加1,如果主串和模式串的字符不相等,则判断模式串的下标是否为0,若为0,则是主串的下标加1,继续匹配,若不为0,则使模式串的下标等于next数组中对应位置的值,继续匹配,知道主串下标等于主串的长度或者模式串的下标值等于模式串的长度。这时模式串的下标值若为模式串的长度,则返回主串的下标值减去模式串的长度,否则返回-1。

(KMP算法)AC代码:

class StringPattern {public:    int findAppearance(string A, int lena, string B, int lenb) {        // write code here        if(lenb==0)            return -1;        int next[lenb];        next[0]=-1;        next[1]=0;        int pos=2;        int cn=0;        while(pos<lenb){           //计算next数组            if(B[pos-1]==B[cn])                next[pos++]=++cn;            else if(cn>0)                cn=next[cn];            else                next[pos++]=0;        }        int j=0,k=0;        while(j<lenb && k<lena){    //模式匹配过程            if(A[k]!=B[j]){                if(j==0)                    k++;                    else                    j=next[j];            }            else{                j++;                k++;            }         }          if(j>=lenb)           return k-lenb;        return -1;    }};


0 0