Open In App

Remove all occurrences of string t in string s using KMP Algorithm

Last Updated : 04 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two strings s and t, the task is to remove all occurrences of t in s and return the modified string s, and you have to use the KMP algorithm to solve this.

Examples:

Input: s = “abcdefgabcabcabdefghabc”, t = “abc”
Output: “defgdefgh”

Input: s = “aaabbbccc”, t = “bbb”
Output: “aaaccc”

Approach: To solve the problem follow the below idea:

We will use the KMP (Knuth-Morris-Pratt) algorithm to solve this problem. The KMP matching algorithm uses degenerating property (pattern having the same sub-patterns appearing more than once in the pattern) of the pattern and improves the worst-case complexity to O(n). The basic idea behind KMP’s algorithm is: whenever we detect a mismatch (after some matches), we already know some of the characters in the text of the next window. We take advantage of this information to avoid matching the characters that we know will anyway match. 

First, we need to compute the LPS array for the pattern string t. The LPS array is an array of integers where lps[i] gives us the length of the longest proper prefix of t[0..i] which is also a suffix of t[0..i]. We can compute the LPS array using the following steps:

  • Initialize len and i to 0, and lps[0] to 0.
  • If t[i] and t[len] match, increment both len and i, and set lps[i] to len.
  • If t[i] and t[len] do not match, we need to reset len to lps[len-1] if len is not equal to 0. If len is 0, we set lps[i] to 0 and increment i.
  • Repeat the above two steps until we reach the end of t.

Once we have computed the LPS array, we can use it to find all occurrences of ‘t’ in ‘s’ and remove them. We can use two pointers, i and j, to traverse s and t, respectively, and a string ans to store the new string without t.    

  • Initialize i and j to 0, and ans to an empty string.
  • If s[i] and t[j] match, increment both i and j.
  • If j becomes equal to the length of t, we have found an occurrence of t in s. We can skip this occurrence by resetting j to lps[j-1], and not copying the characters from i-j to i-1 to ans.
  • If s[i] and t[j] do not match, we need to reset j to lps[j-1], and not increment i. We also need to copy s[i] to ans.
  • Repeat steps 2-4 until we reach the end of s.
  • If ans is empty, it means there were no occurrences of t in s, so we return s. Otherwise, we return ans.

Below is the code to implement the above steps:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to compute the LPS array.
void computeLPS(string t, int lps[])
{
    int m = t.length(), len = 0;
    lps[0] = 0;
    int i = 1;
    while (i < m) {
        if (t[i] == t[len]) {
            len++;
            lps[i] = len;
            i++;
        }
        else {
            if (len != 0) {
                len = lps[len - 1];
            }
            else {
                lps[i] = 0;
                i++;
            }
        }
    }
}
 
// Function to return the modified string
// after removing all occurences
// of t from s.
string removeOccurrences(string s, string t)
{
    int n = s.length(), m = t.length();
    int lps[m];
    computeLPS(t, lps);
    int i = 0, j = 0;
    string ans = "";
    while (i < n) {
        if (s[i] == t[j]) {
            i++;
            j++;
            if (j == m) {
                j = lps[j - 1];
            }
        }
        else {
            if (j != 0) {
                j = lps[j - 1];
            }
            else {
                ans += s[i];
                i++;
            }
        }
    }
    if (ans.length() == 0) {
        return s;
    }
    else {
        return ans;
    }
}
 
// Driver's code
int main()
{
 
    string s = "abcdefgabcabcdefghabc";
    string t = "abc";
 
    // Function call
    string ans = removeOccurrences(s, t);
 
    cout << ans << endl;
 
    return 0;
}


Java




// Java code for the above approach
 
import java.io.*;
import java.util.Arrays;
 
public class GFG {
       // Function to compute the LPS array.
    private static void computeLPS(String t, int[] lps) {
        int m = t.length(), len = 0;
        lps[0] = 0;
        int i = 1;
        while (i < m) {
            if (t.charAt(i) == t.charAt(len)) {
                len++;
                lps[i] = len;
                i++;
            } else {
                if (len != 0) {
                    len = lps[len - 1];
                } else {
                    lps[i] = 0;
                    i++;
                }
            }
        }
    }
    // Function to return the modified string
    // after removing all occurrences
    // of t from s.
    private static String removeOccurrences(String s, String t) {
        int n = s.length(), m = t.length();
        int[] lps = new int[m];
        computeLPS(t, lps);
        int i = 0, j = 0;
        StringBuilder ans = new StringBuilder();
        while (i < n) {
            if (s.charAt(i) == t.charAt(j)) {
                i++;
                j++;
                if (j == m) {
                    j = lps[j - 1];
                }
            } else {
                if (j != 0) {
                    j = lps[j - 1];
                } else {
                    ans.append(s.charAt(i));
                    i++;
                }
            }
        }
        if (ans.length() == 0) {
            return s;
        } else {
            return ans.toString();
        }
    }
  // Driver's code
    public static void main(String[] args) {
        String s = "abcdefgabcabcdefghabc";
        String t = "abc";
      // Function call
        String ans = removeOccurrences(s, t);
        System.out.println(ans);
    }
}


Python3




# Python code for the above approach
 
# Function to compute the LPS array.
def computeLPS(t):
    m = len(t)
    lps = [0] * m
    length = 0
    i = 1
    while i < m:
        if t[i] == t[length]:
            length += 1
            lps[i] = length
            i += 1
        else:
            if length != 0:
                length = lps[length - 1]
            else:
                lps[i] = 0
                i += 1
    return lps
 
# Function to return the modified string
# after removing all occurences
# of t from s.
 
 
def removeOccurrences(s, t):
    n = len(s)
    m = len(t)
    lps = computeLPS(t)
    i = 0
    j = 0
    ans = ""
    while i < n:
        if s[i] == t[j]:
            i += 1
            j += 1
            if j == m:
                j = lps[j - 1]
        else:
            if j != 0:
                j = lps[j - 1]
            else:
                ans += s[i]
                i += 1
    if len(ans) == 0:
        return s
    else:
        return ans
 
 
# Driver's code
s = "abcdefgabcabcdefghabc"
t = "abc"
 
# Function call
ans = removeOccurrences(s, t)
 
print(ans)
 
# This code is contributed by Sakshi


C#




using System;
 
public class Program
{
    // Function to compute the LPS array.
    public static void ComputeLPS(string t, int[] lps)
    {
        int m = t.Length;
        int len = 0;
        lps[0] = 0;
        int i = 1;
        while (i < m)
        {
            if (t[i] == t[len])
            {
                len++;
                lps[i] = len;
                i++;
            }
            else
            {
                if (len != 0)
                {
                    len = lps[len - 1];
                }
                else
                {
                    lps[i] = 0;
                    i++;
                }
            }
        }
    }
 
    // Function to return the modified string
    // after removing all occurences
    // of t from s.
    public static string RemoveOccurrences(string s, string t)
    {
        int n = s.Length;
        int m = t.Length;
        int[] lps = new int[m];
        ComputeLPS(t, lps);
        int i = 0;
        int j = 0;
        string ans = "";
        while (i < n)
        {
            if (s[i] == t[j])
            {
                i++;
                j++;
                if (j == m)
                {
                    j = lps[j - 1];
                }
            }
            else
            {
                if (j != 0)
                {
                    j = lps[j - 1];
                }
                else
                {
                    ans += s[i];
                    i++;
                }
            }
        }
        if (ans.Length == 0)
        {
            return s;
        }
        else
        {
            return ans;
        }
    }
 
    // Driver's code
    public static void Main()
    {
        string s = "abcdefgabcabcdefghabc";
        string t = "abc";
        // Function call
        string ans = RemoveOccurrences(s, t);
        Console.WriteLine(ans);
    }
}


Javascript




function computeLPS(t) {
    const m = t.length;
    const lps = new Array(m).fill(0);
    let len = 0;
    let i = 1;
    while (i < m) {
        if (t[i] === t[len]) {
            len++;
            lps[i] = len;
            i++;
        } else {
            if (len !== 0) {
                len = lps[len - 1];
            } else {
                lps[i] = 0;
                i++;
            }
        }
    }
    return lps;
}
 
/*
 * Function to return the modified string after
 removing all occurrences of t from s.
 */
function removeOccurrences(s, t) {
    const n = s.length;
    const m = t.length;
    const lps = computeLPS(t);
    let i = 0;
    let j = 0;
    let ans = "";
    while (i < n) {
        if (s[i] === t[j]) {
            i++;
            j++;
            if (j === m) {
                j = lps[j - 1];
            }
        } else {
            if (j !== 0) {
                j = lps[j - 1];
            } else {
                ans += s[i];
                i++;
            }
        }
    }
    return ans;
}
 
// Driver's code
const s = "abcdefgabcabcdefghabc";
const t = "abc";
const ans = removeOccurrences(s, t);
console.log(ans);


Output

defgdefgh








Time Complexity: O(n + m), where n is the length of the string s and m is the length of the string t.
Auxiliary Space: O(m), as we use an array of size m to store the LPS array.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads