Z algorithm (Linear time pattern searching Algorithm) in C++

C++Server Side ProgrammingProgramming

Z algorithm is used to find the occurrence of a pattern in a string in linear time. Suppose if the length of the string is n and the size of the pattern to be searched is m, the time taken to solve will be of the order O(m+n).

The z-algorithm uses a Z array to find the occurrence of a pattern.

Z array

It is an array of the same length as the string. Each element of the z-array consists of the length of the longest substring of the string starting from I which can be used as a prefix of the string itself.

Algorithm

In this algorithm, we are given a string S of length n and the pattern to be searched p of length m.

We will create a z array. Now, the algorithm loops of all the characters of the string with i = 1 to n-1. Now, we will create a substring s[L-R] which is a prefix substring such that 1 ≤ L ≤ I ≤ R.

Now, for a correct interval for creating the substring [L, R] for i-1 and all z values up to i-1. Compute z[i] and the new interval [L, R] using the following steps −

Step1: if i > R, no larger prefix-substring is possible. So, we will compute new interval bt comparing
S[0] to S[i] i.e. string starting from index 0 i.e. from start with substring starting from index i.
And find z[i] using z[i] = R - L + 1.
Step 2: Else if, i ≤ R, [L, R] can be extended to i. For k = i-L, z[i] ≥ min(Z[k], R-i+1).
Step 2.1: If, Z[k] < R-i+1, no longer prefix substring s[i] exist.
Step 2.2: If Z[k] ≥ R-i+1, then there can be a longer substring. So, we will update [L, R] by changing L = i and changing R by matching from S[R+1].

This process finds all the Z values in a single iteration (looping only once).

Example

Program to show the implementation of the algorithm −

Live Demo

#include<iostream>
using namespace std;
void createZarray(string str, int Z[]){
int n = str.length();
int L, R, k;
L = R = 0;
for (int i = 1; i < n; ++i){
if (i > R){
L = R = i;
while (R<n && str[R-L] == str[R])
R++;
Z[i] = R-L;
R--;
} else {
k = i-L;
if (Z[k] < R-i+1)
Z[i] = Z[k];
else {
L = i;
while (R<n && str[R-L] == str[R])
R++;
Z[i] = R-L;
R--;
}
}
}
}
void zAlgorithm(string text, string pattern){
string str = pattern+"\$"+text;
int len = str.length();
int Z[len];
createZarray(str, Z);
for (int i = 0; i < len; ++i){
if (Z[i] == pattern.length())
cout<<(i-pattern.length()-1)<<"\t";
}
}
int main(){
string str = "Hello! Welcome To tutorials Point programming tutorial";
string pattern = "tutorial";
cout<<"The patter ' "<<pattern<<" ' is found in the string '"<<str<<" ' at index \t";
zAlgorithm(str, pattern);
return 0;
}

Output

The patter ' tutorial ' is found in the string 'Hello! Welcome To tutorials Point programming tutorial ' at index 18 46
Updated on 17-Apr-2020 11:26:30