``--- layout: layouts/plain.njk title: Knuth Morris Pratt String Matching problem in C description: In this tutorial we will create a program in C which will ask the user to enter a word and a main string and search for the occurrences for the word in the main string. summary: In this tutorial we will create a program in C that will ask the user to enter a word and a main string and search for the occurrences for the word in the main string. tags:
This is an implementation of Knuth Morris Pratt algorithm for string matching in C.
The KMP algorithm is a very fast algorithm for string matching. It is used in many applications like searching for a substring in a large string. The algorithm is based on the idea that if we know the longest prefix of the pattern that is also a suffix of the pattern, then the pattern can be searched in O(n) time. This is called the Knuth-Morris-Pratt algorithm. If a mismatch occurs, we can simply skip the characters of the pattern already matched. We can do this by specifying the length of the longest prefix which is also a suffix. This way we can skip the characters of the pattern already matched. This is called the skip table.
This program will ask the user for a word and a main string and then search for the occurrences for the word in the main string.
Input: word: abc, main string: abcabc
Output: The word is found at index 0
In this approach we'll not make use of any functions. We'll just loop through all the characters of the main string and check whether the word is a substring of the main string.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void inputLine(char *line, int maxLen) {
fflush(stdin);
int i = 0;
char c;
while ((c = getchar()) != '\n' && i < maxLen) {
line[i++] = tolower(c);
}
line[i] = '\0';
}
int main(void)
{
char word[100];
char mainString[100];
int i, j, k;
int wordLen, mainStringLen;
int skipTable[100];
int wordIndex, mainStringIndex;
printf("Enter the word: ");
inputLine(word, 100);
printf("Enter the main string: ");
inputLine(mainString, 100);
wordLen = strlen(word);
mainStringLen = strlen(mainString);
for (i = 0; i < wordLen; i++) {
skipTable[i] = 1;
}
for (i = 1; i < wordLen; i++) {
j = i - 1;
k = i;
while (j >= 0 && word[j] == word[k]) {
skipTable[k] = j + 1;
j--;
k--;
}
}
wordIndex = 0;
mainStringIndex = 0;
while (mainStringIndex < mainStringLen) {
if (word[wordIndex] == mainString[mainStringIndex]) {
wordIndex++;
mainStringIndex++;
} else {
mainStringIndex += skipTable[wordIndex];
wordIndex = 0;
}
if (wordIndex == wordLen) {
printf("The word is found at index %d\n", mainStringIndex - wordLen);
wordIndex = 0;
}
}
if (wordIndex != 0) {
printf("The word is not found\n");
}
return 0;
}
This is the naive approach. We'll loop through all the characters of the main string and check whether the word is a substring of the main string. If the word is a substring of the main string, we'll print the index of the word. If the word is not a substring of the main string, we'll print the index of the main string.
Time complexity of this algorithm is O(n).
Space complexity of this algorithm is O(n).
> ./kmp-str-match
Enter the word: aba
Enter the main string: abc ana dhg aana aba
The word is found at index 17
> ./kmp-str-match
Enter the word: dhg
Enter the main string: abc ana dhg aana aba
The word is found at index 8