Open In App

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

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.    

Below is the code to implement the above steps:




// 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 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);
    }
}




# 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




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);
    }
}




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.


Article Tags :