Last active
August 29, 2015 14:27
-
-
Save pyk/e621467ce90bcad61562 to your computer and use it in GitHub Desktop.
Knuth–Morris–Pratt algorithm in C https://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
void create_failure_fn(char *p, int lenp, int table[]); | |
int search_kmp(char *s, int lens, char *p, int lenp, int table[]); | |
int | |
main() | |
{ | |
int i; | |
char *str = "ABC ABCDAB ABCDABCDABDE"; | |
char *pattern = "ABCDABD"; | |
int lens = strlen(str); | |
int lenp = strlen(pattern); | |
int table[lenp]; | |
create_failure_fn(pattern, lenp, table); | |
printf("%d\n", search_kmp(str, lens, pattern, lenp, table)); | |
} | |
// create_failure_fn is creates a failure function for pattern p. Where | |
// table[0] = -1, table[1] = 0 and table[i] is the value of the longest | |
// suffix that also a prefix of p[0:i-1]. Such that 1 < i < lenp. | |
void | |
create_failure_fn(char *p, int lenp, int table[]) | |
{ | |
// the current position we are computing in table | |
int pos = 2; | |
// the zero-based index in pattern p of the next character of the current | |
// candidate substring | |
int cnd = 0; | |
table[0] = -1; | |
table[1] = 0; | |
while(pos < lenp) { | |
// first case: the substring continues | |
if (p[pos-1] == p[cnd]) { | |
cnd += 1; | |
table[pos] = cnd; | |
pos += 1; | |
} else if(cnd > 0) { | |
// second case: it doesn't, but we can fall back | |
cnd = table[cnd]; | |
} else { | |
// third case: we have run out candidates | |
table[pos] = 0; | |
pos += 1; | |
} | |
} | |
} | |
// search_kmp search a pattern using KMP algorithm. | |
int | |
search_kmp(char *s, int lens, char *p, int lenp, int table[]) | |
{ | |
// the beginning of the current match in string s | |
int m = 0; | |
// the position of the current char in pattern p | |
int i = 0; | |
while(m+i < lens) { | |
if(p[i] == s[m+i]) { | |
if(i == lenp-1) | |
return m; | |
i += 1; | |
} else { | |
if(table[i] > -1) { | |
m += i - table[i]; | |
i = table[i]; | |
} else { | |
i = 0; | |
m += 1; | |
} | |
} | |
} | |
// pattern p not found in string s | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment