Skip to content

Instantly share code, notes, and snippets.

@umedaikiti
Last active August 29, 2015 14:14
Show Gist options
  • Save umedaikiti/4ccc7d224a47518b242b to your computer and use it in GitHub Desktop.
Save umedaikiti/4ccc7d224a47518b242b to your computer and use it in GitHub Desktop.
KMP法のテーブル作成プログラム

KMP法のテーブル作成プログラム

  • たぶんO(n)くらいで動く
  • 証明もだいたい考えたので気が向いたら載せる
#include <stdio.h>
#include <string.h>
/*
lenが小さい時(len == 0,1)はオーバーフロー注意
skip[n] : n文字目で不一致の時何文字進めるか
u[n] : str[0..m-1] == str[n-m..n-1] を満たす最大のm(0<=m<n)
t[n] : str[0..m-1] == str[n-m..n-1] かつ s[m] != s[n]を満たす最大のm(0<=m<n)で、存在しなければ-1
*/
void kmp_table(char *str, int *t, int *u, int *skip, int len)
{
u[0] = 0;
u[1] = 0;
t[0] = -1;
skip[0] = 1;
int m = 1, n;
for(n=2;n<len;n++){
while(str[m-1] != str[n-1]){
if(m == 1){
u[n] = 0;
break;
}
m = u[m-1] + 1;
}
if(str[m-1] == str[n-1]){
u[n] = m;
}
m = u[n] + 1;
}
for(n=1;n<len;n++){
if(str[u[n]] == str[n]){
t[n] = t[u[n]];
}
else{
t[n] = u[n];
}
skip[n] = n - t[n];
}
}
int main()
{
char str[128];
int u[128], t[128], skip[128];
int len, i;
scanf("%120s", str);
len = strlen(str);
kmp_table(str, t, u, skip, len);
for(i=0;i<len;i++){
printf("%c\t%d\t%d\t%d\n", str[i], t[i], u[i], skip[i]);
}
return 0;
}
kmp: kmp.c
gcc kmp.c -o kmp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment