视数据结构写代码(18) KMP算法

看数据结构写代码(18) KMP算法

求 子串 的 位置 有两种方法,一种是暴力搜索法,另一种就是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;
}

视数据结构写代码(18) KMP算法


参考博客:http://blog.csdn.net/v_july_v/article/details/7041827