0% found this document useful (0 votes)
14 views

Module III Problem Solving

The document discusses two algorithms for pattern matching: the naive algorithm and the KMP (Knuth-Morris-Pratt) algorithm. The naive algorithm has a time complexity of O(N^2) and is inefficient for long texts, while the KMP algorithm improves efficiency by using a prefix function to skip unnecessary comparisons, resulting in better performance in worst-case scenarios. The document includes code examples and complexity analysis for both algorithms.

Uploaded by

Anushka Gupta
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

Module III Problem Solving

The document discusses two algorithms for pattern matching: the naive algorithm and the KMP (Knuth-Morris-Pratt) algorithm. The naive algorithm has a time complexity of O(N^2) and is inefficient for long texts, while the KMP algorithm improves efficiency by using a prefix function to skip unnecessary comparisons, resulting in better performance in worst-case scenarios. The document includes code examples and complexity analysis for both algorithms.

Uploaded by

Anushka Gupta
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

Program: Dr.I.

Jasmine

#include <iostream>

#include <string>

using namespace std;

void search(string& pat, string& txt) {

int M = pat.size();

int N = txt.size();

// A loop to slide pat[] one by one

for (int i = 0; i <= N - M; i++) {

int j;

// For current index i, check for pattern match

for (j = 0; j < M; j++) {

if (txt[i + j] != pat[j]) {

break;

// If pattern matches at index i

if (j == M) {

cout << "Pattern found at index " << i << endl;

// Driver's Code

int main() {
// Example 1 Dr.I.Jasmine

string txt1 = "AABAACAADAABAABA";

string pat1 = "AABA";

cout << "Example 1: " << endl;

search(pat1, txt1);

// Example 2

string txt2 = "agd";

string pat2 = "g";

cout << "\nExample 2: " << endl;

search(pat2, txt2);

return 0;

Output

Pattern found at index 0

Pattern found at index 9

Pattern found at index 13

Time Complexity: O(N2)


Auxiliary Space: O(1)

Complexity Analysis of Naive algorithm for Pattern Searching:

Best Case: O(n)

• When the pattern is found at the very beginning of the text (or very early on).

• The algorithm will perform a constant number of comparisons, typically on the order
of O(n) comparisons, where n is the length of the pattern.

Worst Case: O(n2)

• When the pattern doesn’t appear in the text at all or appears only at the very end.

• The algorithm will perform O((n-m+1)*m) comparisons, where n is the length of


the text and m is the length of the pattern.

• In the worst case, for each position in the text, the algorithm may need to compare the
entire pattern against the text.
KMP Algorithm for Pattern Matching

The KMP algorithm is used to solve the pattern matching problem which is a task
of finding all the occurrences of a given pattern in a text. It is very useful when it
comes to finding multiple patterns. For instance, if the text is
"aabbaaccaabbaadde" and the pattern is "aabaa", then the pattern occurs twice in
the text, at indices 0 and 8.

The naive solution to this problem is to compare the pattern with every possible
substring of the text, starting from the leftmost position and moving rightwards.
This takes O(n*m) time, where 'n' is the length of the text and 'm' is the length of
the pattern.

When we work with long text documents, the brute force and naive approaches
may result in redundant comparisons. To avoid such redundancy, Knuth, Morris,
and Pratt developed a linear sequence-matching algorithm named the KMP
pattern matching algorithm. It is also referred to as Knuth Morris Pratt pattern
matching algorithm.

How does KMP Algorithm work?

The KMP algorithm starts the search operation from left to right. It uses the prefix
function to avoid unnecessary comparisons while searching for the pattern. This
function stores the number of characters matched so far which is known as LPS
value. The following steps are involved in KMP algorithm −

• Define a prefix function.

• Slide the pattern over the text for comparison.

• If all the characters match, we have found a match.

• If not, use the prefix function to skip the unnecessary comparisons. If the
LPS value of previous character from the mismatched character is '0', then
start comparison from index 0 of pattern with the next character in the text.
However, if the LPS value is more than '0', start the comparison from index
value equal to LPS value of the previously mismatched character.

Algorithm

def compute_lps(P):

m = len(P)

lps = [0] * m

length = 0

i=1

while i < m:

if P[i] == P[length]:

length += 1

lps[i] = length

i += 1

else:

if length != 0:

length = lps[length - 1]

else:

lps[i] = 0

i += 1

return lps
def KMP_search(T, P):

n = len(T)

m = len(P)

lps = compute_lps(P)

i = 0 # index for T

j = 0 # index for P

matches = []

while i < n:

if P[j] == T[i]:

i += 1

j += 1

if j == m:

matches.append(i - j)

j = lps[j - 1]

elif i < n and P[j] != T[i]:

if j != 0:

j = lps[j - 1]

else:

i += 1

return matches
# Example

T = "AAAAABAAABA"

P = "AAAA"

result = KMP_search(T, P)

print(f"Pattern '{P}' found at positions: {result}")

The KMP algorithm uses a preprocessing step to create a partial match (failure
function) table that helps avoid unnecessary rechecking of characters after
mismatches. This preprocessing step makes the algorithm more efficient than the
naïve approach in worst-case scenarios.

You might also like