0
点赞
收藏
分享

微信扫一扫

155 字符串匹配实现


55、字符串匹配实现

请以俩种方法,回溯与不回溯算法实现。


/*
55、字符串匹配实现
请以俩种方法,回溯与不回溯算法实现。

回溯法,即最基本的方法。算法复杂度O( m * n )
  设主串mainStr = { S0, S1, S2, …, Sm },
  模式串matchStr = { T0, T1, T2, …, Tn };
  当T[0]…T[j-1] ==S[i-j]…S[i-1],即模式串的前j个字符已经和主串匹配,
当前要比较T[j]和S[i]是否相等?
  如果T[j] == S[i], 则i++, j++,继续比较下一个
  如果T[j] != S[i], 则i要回溯,也就是i要退回到与j开始匹配时的下一个位置。
同时j=0, 表示模式串从头开始,重新匹配。

不回溯:即用KMP算法。算法复杂度O( m + n )。
  在KMP中,如果T[j] != S[i],则i保持不动(即,不回溯)。
同时,j不用清零,而是向右滑动模式串,用T[k]和S[i]继续匹配。
关键求一个next的数组
*/


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#define N 100
using namespace std;

int search1(char* src, char* pat) //回溯法
{
int i=0,j=0;
int slen=strlen(src),plen=strlen(pat);

while(i<slen&&j<plen)
{
if(src[i]==pat[j]) //如果相同,则两者++,继续比较
{
++i;++j;
}
else
{
//否则,指针回溯,重新开始匹配
i=i-j+1; //退回到最开始时比较的位置
j=0;
}
}
if(j>=plen)//说明已经匹配 跳出的
return i-plen;
else
return -1;
}

int* PrefixFunc(char *query)//处理next数组
{
if (query == NULL)
return NULL;
int len=strlen(query);
int *Pre=new int[len];
int k=-1,i;

Pre[0]=-1;
for(i=1;i<len;i++)
{
while(k>-1&&query[k+1]!=query[i])
k=Pre[k];

if (query[k+1]==query[i])
k++;
Pre[i]=k;
}
return Pre;
}

int KMP(char *src, char *pat)
{
if (src==NULL||pat==NULL)
return -1;

int slen=strlen(src);
int plen=strlen(pat);
int *Prefix;
Prefix=PrefixFunc(pat); //next数组
if (Prefix==NULL)
return -1;

int k=-1,i;
for (i=0;i<slen;i++)
{
while(k>-1&&pat[k+1]!=src[i])
k=Prefix[k];

if (pat[k+1]==src[i]){
k++;
}
if (k==plen-1)
{
cout<<"KMP:match in position:"<<" "<<i-plen+ 1<<" "<<endl;
k=Prefix[i];
delete[] Prefix;//只找一次
return 0;
}

}
delete[] Prefix;
return 0;
}

int main()
{
int n,i;
char src[N],pat[N];
while(1)
{
scanf("%s",src);
if(!strcmp(src,"0")) break;
scanf("%s",pat);

printf("method1:match in position:%d\n",search1(src,pat));
KMP(src,pat);
}
return 0;
}
/*
BBCABCDABABCDABCDABDE
ABCDABD
bacbababaabcbab
abc
*/

155 字符串匹配实现_i++



举报

相关推荐

0 条评论