串匹配——bf、kmp、bm算法

问题描述:给定一个文本,在该文本中查找并定位任意给定字符串:给定两个串S=''s_{1}s_{2}\cdots s_{n}''T=''t_{1}t_{2}\cdots t_{m}'',在主串S中查找子串T的过程,T为模式。

1、bf算法

蛮力法

对主串与模式串一个一个进行比较,若不匹配,则模式串从第一个字符开始,主串往后一个字符,再进行下一趟比较;若匹配,则模式串与主串字符往后进行比较。

直到主串s所剩字符长度小于模式串t长度或模式串所有字符比较完毕。

#include
#include
int BF(char s[],char t[]){
	int n,m,f,i,j;
	n=strlen(s);
	m=strlen(t);
	for(i=0;i<=n-m;i++){
		f=i;
		for(j=0;j

2、kmp算法

首先计算模式串的next[],即最大真前缀值(k)加一,定义为:

例如 , 模式 T = abaababc ″的 next 值计算如下 :
j = 1 , next[1 ] = 0;
j = 2 , next[ 2] = 1;
j = 3 , t 1 t 2 , next[ 3] = 1;
j = 4 , t 1 = t 3 , next[ 4] = 2;
j = 5 , t 2 t 4 , k = next[2 ] = 1 , t 1 = t 4 , next[5 ] = k + 1 = 2;
j = 6 , t 2 = t 5 , next[ 6] = 3;
j = 7 , t 3 = t 6 , next[7 ] = 4 ;
j = 8 , t 4 t 7 , k = next[ 4] = 2, t 2 = t 7 , next[ 8] = k + 1 = 3
 
串匹配——bf、kmp、bm算法_第1张图片

思想(主串不回溯):

若主串s[i]==t[j]:进行下一趟比较;否则

主串i保持不动,j=next[j];

若j移动到最开头被减为-1,则将其加一,使其移动到开头为0,再进行下一趟比较。

直到主串所剩字符长度小于模式串长度或模式串t中所有字符比较完毕。

#include
#include
int KMP(char s[],char t[]){
	int next[105],m,n;	
	next[1]=0;
	int i,j=1,k=0;
	m=strlen(t);
	while(j

 3、bm算法

首先计算dist[](滑动距离函数),定义为:

例如 , T = pattern , dist( p ) = 6 , dist( a ) = 5 , dist( t ) = 3, dist ( e ) = 2, dist ( r ) = 1,
dist( n ) = 7, 字符表 中的其他字符 ch dist( ch ) = 7
 
串匹配——bf、kmp、bm算法_第2张图片
 

模式串从最右开始,主串从位置i=m-1开始从右向左与模式串比较,若匹配,向左移动进行下一趟比较;否则

模式串从最右重新开始,主串i+=dist[s[i]],即移动到i+滑动距离;

直到主串比较完毕或模式串比较完毕。

#include
#include
#include
#include
using namespace std;
int BM(char s[],char t[]){
	int i,j,n,m,dist[200];
	n=strlen(s);
	m=strlen(t);	
	//初始化
	//memset(dist,m-1,sizeof(dist));
	fill(dist,dist+200,m);
	for(j=0;j=0){
			if(s[i]==t[j]){
				i--;
				j--;
			}
			else break;
		}
		if(j<0)return i+2;
		else i+=dist[s[i]];
	} 
	return 0;
}
int main(){
	char s[1000],t[100];
	int k;
	printf("BM算法:\n");
	while(1){
	  gets(s);
	  gets(t); 
	  k=BM(s,t);	    
	  if(k)printf("在主串中第%d个位置找到子串匹配\n",k);
	  else printf("查找失败\n");	
	}	
	return 0;
}

 

你可能感兴趣的:(算法设计与分析,串匹配)