您的位置:首页 > 其它

KMP 算法(上篇)

2015-12-06 21:32 489 查看
/*
* KMP 算法
* 要点如下:
*      1 如何构建next表
*      2 如何利用next表进行模式匹配
*          指针位置的控制问题
*/

#include <cstdio>
#include <cstring>

void get_next(char *str, int *next) {
size_t len = strlen(str);
memset(next, 0, len * sizeof(int));

if (len==0) return;

next[0] = -1;
char *p = str+1;
while (*p != '\0') {
char *q = str + next[p-1-str];
while (q >= str) {
if (*(p-1)==*q) {
next[p-str] = next[q-str] + 1;
break;
}
q = str + next[q-str];
}
if (q < str) {
next[p-str] = next[0] + 1;
}
++p;
}

next[0] = 0;
}

char *KMP_strstr(char *str1, char *str2) {
int *next = new int[strlen(str2)];
get_next(str2, next);

int index = 0;
char *p = str1;
char *q = str1;
while (*q != '\0') {
char *s = str2 + index;
while (*s==*q && *s!='\0')
++s, ++q;

if (*s=='\0') {
break;
}

// 控制 s 的位置
index = next[s-str2];

// 控制 q 的位置
if (s==str2) ++q;

// 控制 p 的位置
p = q - index;
}

delete [] next;
return p;
}

int main() {
char *str1 = "ababaaababababcaaaa";
char str[] = "ababababca";
char *pch = KMP_strstr(str1, str);
printf("%d\n", pch-str1+1);
return 0;
}


/*
* KMP 算法
* 要点如下:
*      1 如何构建next表
*      2 如何利用next表进行模式匹配
*          指针位置的控制问题
*/

#include <cstdio>
#include <cstring>

void get_next(char *str, int *next) {
next[0] = -1;
char *p = str+1;
while (*p != '\0') {
char *q = str + next[p-1-str];
while (q >= str) {
if (*(p-1) == *q) {
next[p-str] = next[q-str] + 1;
break;
}
q = str + next[q-str];
}
if (q < str) {
next[p-str] = next[0] + 1;
}
++p;
}
}

char *KMP_strstr(char *str1, char *str2) {
int *next = new int[strlen(str2)];
get_next(str2, next);

char *p = str1;
char *q = str2;
while (*p != '\0' && *q != '\0') {
if (q < str2 || *p==*q) ++p, ++q;
else q = str2 + next[q-str2];
}

delete [] next;
if (*q == '\0') return p - (q - str2);
return nullptr;
}

int main() {
char *str1 = "ababaaababababcaaaa";
char str[] = "ababababca";
char *pch = KMP_strstr(str1, str);
printf("%d\n", pch-str1+1);
return 0;
}


/*
* KMP 算法
* 要点如下:
*      1 如何构建next表
*      2 如何利用next表进行模式匹配
*          指针位置的控制问题
*  这个是精炼的算法,不好理解
*/

#include <cstdio>
#include <cstring>

void get_next(char *str, int *next) {
next[0] = -1;
char *p = str;
char *q = str-1;
while (*(p+1) != '\0') {
if (q<str || *p==*q)  {
++q, ++p;
if (*p != *q) next[p-str] = q-str;
else next[p-str] = next[q-str];
}
else q = str + next[q-str];
}
}

char *KMP_strstr(char *str1, char *str2) {
int *next = new int[strlen(str2)];
get_next(str2, next);

char *p = str1;
char *q = str2;
while (*p != '\0' && *q != '\0') {
if (q < str2 || *p==*q) ++p, ++q;
else q = str2 + next[q-str2];
}

delete [] next;
if (*q == '\0') return p - (q - str2);
return nullptr;
}

int main() {
char *str1 = "ababaaababababcaaaa";
char str[] = "ababababca";
char *pch = KMP_strstr(str1, str);
printf("%d\n", pch-str1+1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: