Remove all occurrences of a string t in string s using Boyer-Moore Algorithm
Last Updated :
31 Jul, 2023
Given a string s and string t, the task is to remove all occurrences of a string t in a string s using the Boyer-Moore algorithm.
Examples:
Input: s = "ababaababa", t = "aba"
Output: baab
Input: s = "Geeksforgeeks", t = "eek"
Output: Gsforgs
Approach: This can be solved with the following idea:
- We initialize the bad character rule and then loop through s using the Boyer-Moore algorithm to find all occurrences of . When we find a match, we remove the matched substring from s.
- In the preBadChar() function we create an array called badChar[] that stores the index of the last occurrence of each character in t. This is called the "bad character rule", and it allows the algorithm to skip over some characters in s that do not match t. We then define the removeOccurrences function.
Below are the steps involved in the implementation of the code:
- We first calculate the lengths of the input strings s and t and initialize the badChar array of size 256 with all elements set to -1. The badChar array will be used to store the index of the last occurrence of each character in the pattern t.
- We then call the preBadChar() function which populates the badChar array with the index of the last occurrence of each character in the pattern t.
- We initialize the variable i to 0, which will be used to keep track of the index of the start of the window of s that we will compare to the pattern t.
- We start a while loop that will continue until i is less than or equal to n - m, where n is the length of s and m is the length of t. This ensures that we don't go past the end of the s string while searching for occurrences of t.
- Inside the while loop, we initialize the variable j to m - 1. This will be used to keep track of the index of the end of the window of s that we will compare to the pattern t. We start from the end of the pattern and compare it to the corresponding characters in s starting from index i + j.
- We then start another while loop which will compare the characters in the pattern t with the corresponding characters in s. We will continue to compare the characters until either we have matched all the characters in t with the corresponding characters in s, or until we find a character in t that doesn't match the corresponding character in s.
- If we have matched all the characters in t, we have found an occurrence of t in s. We remove the matched substring from s using the erase() function and update the value of n to reflect the new length of s. We then update the value of i to skip over the matched substring.
- If we didn't match all the characters in t, we have found a mismatch. We calculate the index of the bad character in s using the badChar array. If the bad character doesn't exist in t, we can skip over the entire window of s. Otherwise, we move the window to the right by the maximum of 1 and j minus the index of the bad character in s. This allows us to skip over some unnecessary comparisons and potentially find the next occurrence of t faster.
- We repeat steps 5-8 until we have searched through the entire s string.
- Finally, the modified s string with all occurrences of t removed is returned.
Below is the implementation of the above approach:
C++
// C++ Implementation
#include <bits/stdc++.h>
#define NO_OF_CHARS 256
using namespace std;
void preBadChar(string t, int m, int badChar[])
{
int i;
for (i = 0; i < NO_OF_CHARS; i++) {
badChar[i] = -1;
}
for (i = 0; i < m; i++) {
badChar[(int)t[i]] = i;
}
}
// Function to remove occurrence of string
void removeOccurrences(string& s, string t)
{
int m = t.length();
int n = s.length();
int badChar[NO_OF_CHARS];
preBadChar(t, m, badChar);
int i = 0;
while (i <= n - m) {
int j = m - 1;
while (j >= 0 && t[j] == s[i + j]) {
j--;
}
if (j < 0) {
s.erase(i, m);
n = s.length();
i += m;
}
else {
i += max(1, j - badChar[s[i + j]]);
}
}
}
// Driver code
int main()
{
string s = "Geeksforgeeks";
string t = "eek";
// Function call
removeOccurrences(s, t);
cout << s << endl;
return 0;
}
Java
import java.util.Arrays;
public class Main {
static final int NO_OF_CHARS = 256;
// Function to pre-process the bad character array
static void preBadChar(String t, int m, int[] badChar) {
// Initialize all occurrences as -1
Arrays.fill(badChar, -1);
// Fill the actual value of last occurrence of a character
for (int i = 0; i < m; i++) {
badChar[t.charAt(i)] = i;
}
}
// Function to remove occurrences of the given pattern from the given string
static void removeOccurrences(StringBuilder s, String t) {
int m = t.length();
int n = s.length();
int[] badChar = new int[NO_OF_CHARS];
preBadChar(t, m, badChar);
int i = 0;
while (i <= n - m) {
int j = m - 1;
// Keep reducing the index j of pattern while characters of pattern
// and string are matching at this shift s
while (j >= 0 && t.charAt(j) == s.charAt(i + j)) {
j--;
}
// If the pattern is present at current shift, then remove it
if (j < 0) {
s.delete(i, i + m);
n = s.length();
i += m;
}
else {
// Shift the pattern so that the bad character in text aligns with the last occurrence of it in pattern.
i += Math.max(1, j - badChar[s.charAt(i + j)]);
}
}
}
// Driver code
public static void main(String[] args) {
StringBuilder s = new StringBuilder("Geeksforgeeks");
String t = "eek";
// Function call
removeOccurrences(s, t);
System.out.println(s);
}
}
Python
# Function to precompute bad character table
def preBadChar(t, m):
# Initialize an array to store bad character position
badChar = [-1]*256
# Fill the array with the last occurrence of each character in t
for i in range(m):
badChar[ord(t[i])] = i
return badChar
# Function to remove all occurrences of t in s
def removeOccurrences(s, t):
m = len(t)
n = len(s)
# Precompute the bad character table
badChar = preBadChar(t, m)
i = 0
while i <= n - m:
j = m - 1
# Compare characters from right to left
while j >= 0 and t[j] == s[i+j]:
j -= 1
if j < 0:
# If pattern is found, remove it from s
s = s[:i] + s[i+m:]
n = len(s)
i += m
else:
# Shift the pattern so that bad character aligns
i += max(1, j - badChar[ord(s[i+j])])
return s
# Driver code
s = "Geeksforgeeks"
t = "eek"
# Function call
s = removeOccurrences(s, t)
print(s)
C#
// C# code to implement the above approach.
using System;
public class GFG
{
const int NO_OF_CHARS = 256;
// Function to pre-process the bad character array
static void PreBadChar(string t, int m, int[] badChar)
{
// Initialize all occurrences as -1
Array.Fill(badChar, -1);
// Fill the actual value of last occurrence of a character
for (int i = 0; i < m; i++)
{
badChar[(int)t[i]] = i;
}
}
// Function to remove occurrences of the given pattern
// from the given string
static void RemoveOccurrences(ref string s, string t)
{
int m = t.Length;
int n = s.Length;
int[] badChar = new int[NO_OF_CHARS];
PreBadChar(t, m, badChar);
int i = 0;
while (i <= n - m)
{
int j = m - 1;
// Keep reducing the index j of pattern while
// characters of pattern
// and string are matching at this shift s
while (j >= 0 && t[j] == s[i + j])
{
j--;
}
// If the pattern is present at current shift,
// then remove it
if (j < 0)
{
s = s.Remove(i, m);
n = s.Length;
i += m;
}
else
{
// Shift the pattern so that the bad character
// in text aligns with the last occurrence of it in
// pattern.
i += Math.Max(1, j - badChar[(int)s[i + j]]);
}
}
}
// Driver code
public static void Main(string[] args)
{
string s = "Geeksforgeeks";
string t = "eek";
// Function call
RemoveOccurrences(ref s, t);
Console.WriteLine(s);
}
}
// This code is contributed by Vaibhav Nandan
JavaScript
// Function to pre-process the bad character array
function preBadChar(t, m) {
// Initialize all occurrences as -1
var badChar = new Array(256).fill(-1);
// Fill the actual value of last occurrence of a character
for (var i = 0; i < m; i++) {
badChar[t.charCodeAt(i)] = i;
}
return badChar;
}
// Function to remove occurrences of the given pattern from the given string
function removeOccurrences(s, t) {
var m = t.length;
var n = s.length;
var badChar = preBadChar(t, m);
var i = 0;
while (i <= n - m) {
var j = m - 1;
// Keep reducing the index j of pattern while characters of pattern
// and string are matching at this shift s
while (j >= 0 && t[j] == s[i+j]) {
j -= 1;
}
// If the pattern is present at current shift, then remove it
if (j < 0) {
s = s.slice(0, i) + s.slice(i+m);
n = s.length;
i += m;
}
// Shift the pattern so that the bad character in text aligns with
// the last occurrence of it in pattern.
else {
i += Math.max(1, j - badChar[s.charCodeAt(i+j)]);
}
}
return s;
}
// Test case
var s = "Geeksforgeeks";
var t = "eek";
s = removeOccurrences(s, t);
console.log(s);
PHP
<?php
// Function to preprocess bad character table
function preBadChar($t, $m, &$badChar)
{
// Initialize all entries as -1
for ($i = 0; $i < 256; $i++) {
$badChar[$i] = -1;
}
// Fill the actual value of last occurrence of a character
for ($i = 0; $i < $m; $i++) {
$badChar[ord($t[$i])] = $i;
}
}
// Function to remove occurrence of string
function removeOccurrences(&$s, $t)
{
$m = strlen($t);
$n = strlen($s);
$badChar = array();
preBadChar($t, $m, $badChar);
$i = 0;
while ($i <= $n - $m) {
$j = $m - 1;
while ($j >= 0 && $t[$j] == $s[$i + $j]) {
$j--;
}
if ($j < 0) {
// If pattern occurs, remove it
$s = substr_replace($s, '', $i, $m);
$n = strlen($s);
$i += $m;
}
else {
// Shift the pattern so that the bad character in text aligns with the last occurrence of it in pattern
$i += max(1, $j - $badChar[ord($s[$i + $j])]);
}
}
}
// Driver code
$s = "Geeksforgeeks";
$t = "eek";
// Function call
removeOccurrences($s, $t);
echo $s . "\n";
?>
Time Complexity: O(mn)
Auxiliary Space: O(k)
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Array Data Structure Guide In this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
4 min read
Sorting Algorithms A Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read