常见的模式匹配算法有两种:
- BF算法(简单模式匹配算法)
- KMP算法
C语言实现的BF算法:
#include <stdio.h>
//pos是从1开始的一个下标
int index_force(char * s, char * t,int pos)
{
int i=pos-1;
//判断pos是否合法
if(!s[i])
printf("起始位置不合法");
int j=0;
while(s[i]!='\0' && t[j]!='\0') { //主串或者模式串遍历完成
if(s[i]==t[j]) { //如果主串和模式串对应位置的值相等,则比较后面的字符
++i;
++j;
}
else { //如果不相等,则模式串需要回朔到第一个字符,而主串则从下一个字符开始
i=i-j+1;
j=0;
}
}
if(t[j]=='\0') { //如果循环是由于模式串遍历完了而结束的,说明找到了对应子串的位置
return i-j+1;
}
else { //否则,主串不包含模式串
return 0;
}
}
int main (void){ //用于测试的主函数
char *p="abcdefgh"; //主串
char *q="fg"; //模式串
int index;
index=index_force(p,q,1);
printf("%d\n",index); //输出结果
}
运行结果:
C语言实现的KMP算法:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Max 100 //宏定义
#define TRUE 1
#define FALSE 0
typedef unsigned char SString[Max+1]; //类型重命名
typedef int Status; //类型重命名
Status StrAssign(SString T,char *strs) { //形式参数为:一个字符串 ,一个字符型指针
int i;
T[0]=0; //首元素存放字符串的长度
for(i=0;strs[i];i++){ //赋值
T[i+1]=strs[i];
T[0]=i+1;
}
}
void get_next(SString T,int *next){ //计算next的函数,求出模式串T的next函数值并存入next数组
int i,j;
i=1;
j=0;
next[1]=0;
while(i<T[0]){
if(j==0||T[i]==T[j]){
++i;
++j;
next[i]=j;
}
else
j=next[j];
}
}
int Index_KMP(SString S,SString T,int pos){ //KMP模式匹配函数
int i=pos;
int j=1;
int next[255];
get_next(T,next);
while(i<=S[0]&&j<=T[0]){ //从字符串的首元素获取字符串长度,并判断是否越界
if(j==0||S[i]==T[j]){ //相等则继续判断
++i;
++j;
}
else{ //不相等,则调用next函数,获取下一个应该跳到的位置
j=next[j];
}
}
if(j>T[0])
return i-T[0];
else
return 0;
}
int main(){
SString S,T; //两个字符串
int m; //m用来接收匹配结果
char strs1[Max]; //定义了两个长100的数组
char strs2[Max];
scanf("%s %s",strs1,strs2); //输入函数,按指定格式输入两个字符串,并赋值给strs1,strs2
StrAssign(S,strs1); //调用函数将字符数组转为字符串
StrAssign(T,strs2);
m=Index_KMP(S,T,1); //调用KMP模式匹配函数 并指定从主串的第一个开始匹配
if(m) //m非0表示匹配成功 为0,表示主串中不存在模式串
printf("%d\n",m);
else
printf("0\n");
return 0;
}