kmp算法字符串匹配
在leetcode做题时,有道题就是写一个strstr函数,先用思路最简单的直接两个循环做,提示时间超过限制。就查了查kmp的资料
翻了下算法导论,感觉像在看数学书,看不太懂,最后还是网上看的博客……
理解kmp的思路可以看这个http://kb.cnblogs.com/page/176818/
/************************************************************ Copyright (C), 2015, Leon, All Rights Reserved. FileName: kmp_strstr.c Description: kmp算法字符串匹配实现 Author: Leon Version: 1.0 Date: 2016年3月28日14:15:50 Function: History: <author> <time> <version> <description> Leon ************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*next数组下标表示字符串长度,因此初始化要多初始化一个位置*/
void compute_next(char *s, int *next)
{
int i = 0, len = strlen(s);
int k = 0;
next[0] = next[1] = 0;
for(i = 1; i < len; i++)
{
while(k > 0 && s[k] != s[i])
k = next[k];
if(s[k] == s[i])
k++;
next[i+1] = k;
}
}
char *kmp_strstr(char *s, char *t)
{
int s_len, t_len, i, j=0;
int *next = NULL;
if(!s || !t)
return NULL;
s_len = strlen(s);
t_len = strlen(t);
if(t_len == 0)
return s;
next = (int *)malloc(sizeof(int) * (t_len + 1));
if(!next)
return NULL;
compute_next(t, next);
for(i = 0; i < s_len; i++)
{
while(j > 0 && s[i] != t[j])
j = next[j];
if(s[i] == t[j])
j++;
if(j == t_len)
{
//printf("match %d\n", i-j+1);
free(next);
return s+i-j+1;
}
}
free(next);
return NULL;
}
int main(int argc, char *argv[])
{
char *s;
s = kmp_strstr(argv[1], argv[2]);
printf("%s\n", s?s:"NULL");
printf("%s\n", strstr(argv[1], argv[2])?:"NULl");
return 0;
}
即便理解了思路,写程序的时候还是在下标计算哪里卡了很久
leetcode跑了60来个测试用例,显示运行时间0ms,处在第一梯队,说明kmp算法即便在极端的情况下,效率依然不错。