#include <stdio.h>
#include <string.h>
#include <conio.h>
#define KMP_NOTMATCH -1
#define KMP_INVALIDPARA -2
#define KMP_OUTOFMEMORY -3
void get_next(char *str, int *next, int n)
{
int i=0, j=-1;
if (n<1)
return;
next[0] = -1;
while (i<n)
{
if (j==-1 || str[i]==str[j])
{
i++; j++;
if (str[i]!=str[j])
next[i]=j;
else
next[i]=next[j];
}
else
j=next[j];
}
}
void show_match(char *main_str, char *sub_str, int i, int j)
{
int k;
printf("main: ");
for (k=0;k<i;k++)
printf("%c", main_str[k]);
textattr(GREEN+(BLACK<<4));
putch(main_str[k++]);
textattr(WHITE+(BLACK<<4));
while (main_str[k])
printf("%c", main_str[k++]);
printf("/nsub : ");
for (k=0;k<i-j;k++)
printf(" ");
for (k=0;k<j;k++)
printf("%c", sub_str[k]);
textattr(GREEN+(BLACK<<4));
putch(sub_str[k++]);
textattr(WHITE+(BLACK<<4));
while (sub_str[k])
printf("%c", sub_str[k++]);
printf("/n--------------------/n");
}
void show_mismatch(char *main_str, char *sub_str, int i, int j)
{
int k;
printf("main: ");
for (k=0;k<i;k++)
printf("%c", main_str[k]);
textattr(RED+(BLACK<<4));
putch(main_str[k++]);
textattr(WHITE+(BLACK<<4));
while (main_str[k])
printf("%c", main_str[k++]);
printf("/nsub : ");
for (k=0;k<i-j;k++)
printf(" ");
for (k=0;k<j;k++)
printf("%c", sub_str[k]);
textattr(RED+(BLACK<<4));
putch(sub_str[k++]);
textattr(WHITE+(BLACK<<4));
while (sub_str[k])
printf("%c", sub_str[k++]);
printf("/n--------------------/n");
}
int match(char *main_str, char *sub_str, int pos)
{
int main_len=strlen(main_str);
int sub_len=strlen(sub_str);
int i=pos,j=0;
int *next=NULL;
if (main_len<1 || sub_len<1)
return KMP_INVALIDPARA;
next=(int*)malloc(sub_len*sizeof(int));
if (next==NULL)
return KMP_OUTOFMEMORY;
get_next(sub_str, next, sub_len);
while (i<main_len && j<sub_len)
{
if (j==-1 || main_str[i]==sub_str[j])
{
if (j != -1)
{
show_match(main_str, sub_str, i, j);
getch();
}
i++; j++;
}
else
{
show_mismatch(main_str, sub_str, i, j);
getch();
j=next[j];
}
}
free(next);
return ((j==sub_len)?i-j:KMP_NOTMATCH);
}
void display(int index)
{
switch (index)
{
case KMP_NOTMATCH:
printf("/nmismatch.");
break;
case KMP_OUTOFMEMORY:
printf("/n system out of memory.");
break;
case KMP_INVALIDPARA:
printf("/n invalid paramater.");
break;
default:
printf("/n matched at %d", index);
}
}
void main(int argc, char **argv)
{
if (argc < 3)
{
printf("Usage:/n/t kmp.exe main-string sub-string.");
return;
}
display(match(argv[1],argv[2],0));
}