Remove all occurrences of a word from a given string using Z-algorithm


This article delves into an interesting string manipulation problem: "Remove all occurrences of a word from a given string using Z-algorithm". This problem serves as an excellent use case for the Z-algorithm, highlighting its efficacy in pattern searching problems. Let's explore in detail.

Problem Statement

Given a string S and a word W, the task is to remove all occurrences of W from S using the Z-algorithm.

Understanding the Problem

Consider a string S = "HelloWorldHelloWorld" and a word W = "World". The goal is to remove all occurrences of W from S. Hence, the output would be "HelloHello".

Z-algorithm

The Z-algorithm finds all occurrences of a pattern in a text in linear time. It constructs an array (Z-array), where for a given index i, Z[i] represents the length of the longest substring starting from i which is also a prefix of the string.

Algorithmic Approach

Here are the steps to solve the problem −

  • Create a new string P = W + '$' + S.

  • Apply the Z-algorithm to P and construct the Z-array.

  • Iterate over the Z-array. If Z[i] is equal to the length of W, it means W is present at that index. Remove W from S at that index.

Example

Here's a C++ code that implements the above approach −

#include<bits/stdc++.h>
using namespace std;

vector<int> constructZArray(string str) {
   int n = str.length();
   vector<int> Z(n, 0);
   int L = 0, 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 {
         int 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--;
         }
      }
   }
   return Z;
}

string removeWord(string S, string W) {
   string P = W + '$' + S;
   int len_W = W.length();
   vector<int> Z = constructZArray(P);
   vector<bool> toRemove(S.size(), false);
   for (int i = len_W + 1; i < Z.size(); i++) {
      if (Z[i] == len_W)
         fill(toRemove.begin() + i - len_W - 1, toRemove.begin() + i - 1, true);
   }
   
   string result = "";
   for (int i = 0; i < S.size(); i++) {
      if (!toRemove[i])
         result += S[i];
   }
   return result;
}

int main() {
   string S, W;
   S="Iamwritingwriting";
   W = "writing";
   cout << "String after removal: " << removeWord(S, W);
   return 0;
}

Output

String after removal: Iam

Testcase Example

Let's consider an example −

Suppose S = "Iamwritingwriting" and W = "writing". The program will output "Iam". Here's why −

  • The new string P becomes "writing$Iamwritingwriting".

  • After applying the Z-algorithm, we find that Z[8] and Z[15] are equal to the length of W, which means W is present at these indices in S.

  • We then remove W from these indices in S, resulting in the string "Iam".

Conclusion

The Z-algorithm is a powerful tool for pattern searching problems. In this article, we saw its application in removing all occurrences of a word from a string. This problem is a great example showcasing the benefits of understanding and applying string matching algorithms. Always remember, understanding and learning algorithms open up ways to solve complex problems.

Updated on: 18-May-2023

140 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements