求 子串 的 位置 有两种方法,一种是暴力搜索法,另一种就是KMP 算法。他们的效率 在一般的情况下,区别不大。但是在 串的 变化 范围特别小的情况下,例如 只有 0 和 1,KMP 的时间复杂度是 O(m+n),而暴力搜索法定时间 复杂度 是 O(m*n),(m,n分别指 子串 和 母串的 长度)
下面给出两种算法的代码
欢迎指出代码不足
// Kmp2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
//暴力模式匹配(求子串位置)
int stringIndex(char * string,char * sub,int pos){
char * p = string;
int lenString = strlen(string);
int lenSub = strlen(sub);
int matchTimes = 0;
for (int i = pos -1; i <= lenString - lenSub; i++)
{
int temp = i;
for (int j = 0; j < lenSub;)
{
matchTimes++;
if (string[temp] == sub[j])
{
temp++,j++;
if (j == lenSub)
{
printf("暴力匹配算法,执行次数: %d\n",matchTimes);
return i+1;
}
}
else
{
break;
}
}
}
printf("暴力匹配算法,执行次数: %d\n",matchTimes);
return 0;
}
//KMP 模式匹配法..
void getNext(char * sub,int * nextArray);
static int kmpTimes = 0;
int kmpIndex(char * string,char * sub,int pos){
int stringLen = strlen(string);
int subLen = strlen(sub);
int i=pos-1,j=0;
kmpTimes = 0;
int * nextArray = (int *)malloc(sizeof(int) * subLen);
getNext(sub,nextArray);
while (i < stringLen - subLen + 1 && j < subLen)
{
kmpTimes++;
if (j == -1 || string[i] == sub[j] )
{
i++,j++;
}
else
{
j = nextArray[j];
}
}
free(nextArray);
printf("KMP匹配算法,执行次数(包括getNext函数匹配次数): %d\n",kmpTimes);
return j == subLen ? i-subLen+1: 0;
}
void getNext(char * sub,int * nextArray){
int subLen = strlen(sub);
nextArray[0] = -1;
for (int i = 0,j = -1; i < subLen -1;)
{
kmpTimes++;
if (j == -1 || sub[i] == sub[j])
{
i ++ ,j ++;
if (sub[i] != sub[j])
{
nextArray[i] = j;
}
else
{
nextArray[i] = nextArray[j];
}
}
else
{
j = nextArray[j];
}
}
}
//打印 信息
void printMsg(char * string,int index,int kmp){
char * point = string + index - 1;
char * kmpPoint = string + kmp - 1;
printf("暴力模式匹配 字符串为:%s\n,KMP模式匹配算法字符串为:%s\n",point,kmpPoint,kmp);
}
int _tmain(int argc, _TCHAR* argv[])
{
char * string = "abcdefghijklmnsdfdsdfsfdsd";
char * sub = "sdfd";
int index = stringIndex(string,sub,1);
int kmp = kmpIndex(string,sub,1);
printMsg(string,index,kmp);
string = "00000000000000000000000000000000000111111111111111111100";
sub = "000000000001111";
index = stringIndex(string,sub,1);
kmp = kmpIndex(string,sub,1);
printMsg(string,index,kmp);
return 0;
}
原文地址:http://blog.csdn.net/fuming0210sc/article/details/44198353