字符串 求 子串 位置 的 算法 叫做 模式匹配算法。
模式匹配 算法 有 好多种,比较 常见的 有 暴力 匹配算法 和 KMP 算法。暴力匹配算法 时间 复杂度为O(M*N),KMP 时间复杂度为 O(M+N)。
下面给出两种算法的代码
欢迎指出代码不足
// KMP.cpp : 定义控制台应用程序的入口点。
//求子串问题..
#include "stdafx.h"
#include <cstring>
#include <cstdlib>
//暴力匹配算法,时间复杂度 为 O(m*n)
//求在 母串 s 从 第 pos 个位置开始 子串 t的位置
static int runTimes = 0;//执行次数...
int normal(char * s,char * t,int pos){
int sLen = strlen(s);//母串的位置
int tLen = strlen(t);//子串的长度
int i = pos-1,j = 0;//计算起始值
int first = i;//匹配开始的位置
runTimes = 0;
while (i <sLen && j < tLen){
runTimes++;
if (s[i] == t[j]) {//相等
i++,j++;
}
else{//不相等,i = 匹配开始的值+1, j = 0
i = ++first;
j = 0;
}
}
if (j >= tLen){//匹配成功.
return first+1;
}
else{//匹配不成功,返回 -1
return -1;
}
}
//普通 求 Next
void getNext1(char * t,int len,int * next){
next[0] = -1;//初值..
int i = 0,j = -1;
while (i < len -1){
if(j == -1 || t[i] == t[j]){
i++,j++;
next[i] = j;
}
else{
j = next[j];
}
}
}
//求Next 改进
void getNext2(char * t,int len,int * next){
next[0] = -1;//初值..
int i = 0,j = -1;
while (i < len -1){
if(j == -1 || t[i] == t[j]){
i++,j++;
if (t[i] != t[j]){
next[i] = j;
}
else{
next[i] = next[j];
}
}
else{
j = next[j];
}
}
}
//kmp 模式匹配法.
int kmp(char * s,char * t,int pos,int fun){
int sLen = strlen(s);
int tLen = strlen(t);
int i = pos - 1,j = 0;
int * next = (int *) malloc(sizeof(int) * tLen);//next 数组
if (fun == 1){
getNext1(t,tLen,next);//计算next
}
else{
getNext2(t,tLen,next);//计算next
}
runTimes = 0;
while (i < sLen && j < tLen){
runTimes ++;
if (j == -1 || s[i] == t[j]){
i++,j++;
}
else{//i值 不回溯,j = next[j]
j = next[j];
}
}
free(next);//释放空间..
if (j >= tLen){
return i - j + 1;
}
return -1;
}
//打印 信息
//kind , 1: 暴力匹配 2:KMP 3.改进KMP
void printMsg(char * string,int index,int kind){
if (index != -1){
char * point = string + index - 1;
char *s = NULL;
if (kind == 1){
s = "暴力匹配";
}
else if(kind == 2){
s = "kmp匹配";
}
else{
s = "改进kmp匹配";
}
printf("%s 求得字符串为:%s,\t执行次数%d\n",s,point,runTimes);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char * string = "abcdefghijklmnsdfdsdfsfdsd";
char * sub = "sdfd";
int index = normal(string,sub,1);
printMsg(string,index,1);
index = kmp(string,sub,1,1);
printMsg(string,index,2);
index = kmp(string,sub,1,2);
printMsg(string,index,3);
string = "0000000001100000000011000000000111000000000001111aa";
sub = "000000000001111";
index = normal(string,sub,1);
printMsg(string,index,1);
index = kmp(string,sub,1,1);
printMsg(string,index,2);
index = kmp(string,sub,1,2);
printMsg(string,index,3);
return 0;
}
参考书籍:严蔚敏《数据结构。C语言版》