现在的位置: 首页 > 综合 > 正文

155 字符串匹配实现

2018年01月19日 ⁄ 综合 ⁄ 共 1616字 ⁄ 字号 评论关闭

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
*/

抱歉!评论已关闭.