Remove all occurrences of string t in string s using KMP Algorithm
Last Updated :
04 Oct, 2023
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++
#include <bits/stdc++.h>
using namespace std;
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++;
}
}
}
}
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;
}
}
int main()
{
string s = "abcdefgabcabcdefghabc" ;
string t = "abc" ;
string ans = removeOccurrences(s, t);
cout << ans << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.Arrays;
public class GFG {
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++;
}
}
}
}
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();
}
}
public static void main(String[] args) {
String s = "abcdefgabcabcdefghabc" ;
String t = "abc" ;
String ans = removeOccurrences(s, t);
System.out.println(ans);
}
}
|
Python3
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
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
s = "abcdefgabcabcdefghabc"
t = "abc"
ans = removeOccurrences(s, t)
print (ans)
|
C#
using System;
public class Program
{
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++;
}
}
}
}
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;
}
}
public static void Main()
{
string s = "abcdefgabcabcdefghabc" ;
string t = "abc" ;
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 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;
}
const s = "abcdefgabcabcdefghabc" ;
const t = "abc" ;
const ans = removeOccurrences(s, t);
console.log(ans);
|
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.
Share your thoughts in the comments
Please Login to comment...