Remove "b" and "ac" from a given string
Last Updated :
31 Jan, 2023
Given a string, eliminate all "b" and "ac" in the string, you have to replace them in-place, and you are only allowed to iterate over the string once. (Source Google Interview Question)
Examples:
acbac ==> ""
aaac ==> aa
ababac ==> aa
bbbbd ==> d
The two conditions are: 1. Filtering of all 'b' and 'ac' should be in single pass 2. No extra space allowed. The approach is to use two index variables i and j. We move forward in string using 'i' and add characters using index j except 'b' and 'ac'. The trick here is how to track 'a' before 'c'. An interesting approach is to use a two state machine. The state is maintained to TWO when previous character is 'a', otherwise state is ONE. 1) If state is ONE, then do NOT copy the current character to output if one of the following conditions is true ...a) Current character is 'b' (We need to remove 'b') ...b) Current character is 'a' (Next character may be 'c') 2) If state is TWO and current character is not 'c', we first need to make sure that we copy the previous character 'a'. Then we check the current character, if current character is not 'b' and not 'a', then we copy it to output.
C++
// A C++ program to remove "b" and 'ac' from input string
#include <iostream>
using namespace std;
#define ONE 1
#define TWO 2
// The main function that removes occurrences of "a" and
// "bc" in input string
void stringFilter(char* str)
{
// state is initially ONE (The previous character is not
// a)
int state = ONE;
// i and j are index variables, i is used to read next
// character of input string, j is used for indexes of
// output string (modified input string)
int j = 0;
// Process all characters of input string one by one
for (int i = 0; str[i] != '\0'; i++) {
/* If state is ONE, then do NOT copy the current
character to output if one of the following
conditions is true
...a) Current character is 'b' (We need to remove
'b')
...b) Current character is 'a' (Next character
may be 'c') */
if (state == ONE && str[i] != 'a'
&& str[i] != 'b') {
str[j] = str[i];
j++;
}
// If state is TWO and current character is not 'c'
// (other- wise we ignore both previous and current
// characters)
if (state == TWO && str[i] != 'c') {
// First copy the previous 'a'
str[j] = 'a';
j++;
// Then copy the current character if it is not
// 'a' and 'b'
if (str[i] != 'a' && str[i] != 'b') {
str[j] = str[i];
j++;
}
}
// Change state according to current character
state = (str[i] == 'a') ? TWO : ONE;
}
// If last character was 'a', copy it to output
if (state == TWO) {
str[j] = 'a';
j++;
}
// Set the string terminator
str[j] = '\0';
}
/* Driver program to check above functions */
int main()
{
char str1[] = "ad";
stringFilter(str1);
cout << str1 << endl;
char str2[] = "acbac";
stringFilter(str2);
cout << str2 << endl;
char str3[] = "aaac";
stringFilter(str3);
cout << str3 << endl;
char str4[] = "react";
stringFilter(str4);
cout << str4 << endl;
char str5[] = "aa";
stringFilter(str5);
cout << str5 << endl;
char str6[] = "ababaac";
stringFilter(str6);
cout << str6 << endl;
return 0;
}
Java
// A Java program to remove "b" and
// 'ac' from input String
import java.util.*;
class GFG {
static final int ONE = 1;
static final int TWO = 2;
// The main function that removes occurrences
// of "a" and "bc" in input String
static char[] StringFilter(char[] str)
{
// state is initially ONE
// (The previous character is not a)
int state = ONE;
// i and j are index variables,
// i is used to read next
// character of input String,
// j is used for indexes of output
// String (modified input String)
int j = 0;
// Process all characters of
// input String one by one
for (int i = 0; i < str.length; i++) {
/* If state is ONE, then do NOT copy
the current character to output if
one of the following conditions is true
...a) Current character is 'b'
(We need to remove 'b')
...b) Current character is 'a'
(Next character may be 'c') */
if (state == ONE && str[i] != 'a'
&& str[i] != 'b') {
str[j] = str[i];
j++;
}
// If state is TWO and current character
// is not 'c' (otherwise we ignore both
// previous and current characters)
if (state == TWO && str[i] != 'c') {
// First copy the previous 'a'
str[j] = 'a';
j++;
// Then copy the current character
// if it is not 'a' and 'b'
if (str[i] != 'a' && str[i] != 'b') {
str[j] = str[i];
j++;
}
}
// Change state according to current character
state = (str[i] == 'a') ? TWO : ONE;
}
// If last character was 'a',
// copy it to output
if (state == TWO) {
str[j] = 'a';
j++;
}
return Arrays.copyOfRange(str, 0, j);
}
// Driver Code
public static void main(String[] args)
{
char str1[] = "ad".toCharArray();
str1 = StringFilter(str1);
System.out.print(String.valueOf(str1) + "\n");
char str2[] = "acbac".toCharArray();
str2 = StringFilter(str2);
System.out.print(String.valueOf(str2) + "\n");
char str3[] = "aaac".toCharArray();
str3 = StringFilter(str3);
System.out.print(String.valueOf(str3) + "\n");
char str4[] = "react".toCharArray();
str4 = StringFilter(str4);
System.out.print(String.valueOf(str4) + "\n");
char str5[] = "aa".toCharArray();
str5 = StringFilter(str5);
System.out.print(String.valueOf(str5) + "\n");
char str6[] = "ababaac".toCharArray();
str6 = StringFilter(str6);
System.out.print(String.valueOf(str6) + "\n");
}
}
// This code is contributed by 29AjayKumar
Python
# A Python program to remove "b" and 'ac' from input string
ONE = 1
TWO = 2
# Utility function to convert string to list
def toList(string):
l = []
for x in string:
l.append(x)
return l
# Utility function to convert list to string
def toString(l):
return ''.join(l)
# The main function that removes occurrences of "a" and "bc"
# in input string
def stringFilter(string):
# state is initially ONE (The previous character is not a)
state = ONE
# i and j are index variables, i is used to read next
# character of input string, j is used for indexes of
# output string (modified input string)
j = 0
# Process all characters of input string one by one
for i in xrange(len(string)):
# If state is ONE, then do NOT copy the current character
# to output if one of the following conditions is true
# ...a) Current character is 'b' (We need to remove 'b')
# ...b) Current character is 'a' (Next character may be 'c')
if state == ONE and string[i] != 'a' and string[i] != 'b':
string[j] = string[i]
j += 1
# If state is TWO and current character is not 'c' (other-
# wise we ignore both previous and current characters)
if state == TWO and string[i] != 'c':
# First copy the previous 'a'
string[j] = 'a'
j += 1
# Then copy the current character if it is not 'a' and 'b'
if string[i] != 'a' and string[i] != 'b':
string[j] = string[i]
j += 1
# Change state according to current character
state = TWO if string[i] == 'a' else ONE
# If last character was 'a', copy it to output
if state == TWO:
string[j] = 'a'
j += 1
return toString(string[:j])
# Driver program
string1 = stringFilter(toList("ad"))
print string1
string2 = stringFilter(toList("acbac"))
print string2
string3 = stringFilter(toList("aaac"))
print string3
string4 = stringFilter(toList("react"))
print string4
string5 = stringFilter(toList("aa"))
print string5
string6 = stringFilter(toList("ababaac"))
print string6
# This code is contributed by BHAVYA JAIN
C#
// A C# program to remove "b" and
// 'ac' from input String
using System;
class GFG {
static readonly int ONE = 1;
static readonly int TWO = 2;
// The main function that removes occurrences
// of "a" and "bc" in input String
static char[] StringFilter(char[] str)
{
// state is initially ONE
// (The previous character is not a)
int state = ONE;
// i and j are index variables,
// i is used to read next
// character of input String,
// j is used for indexes of output
// String (modified input String)
int j = 0;
// Process all characters of
// input String one by one
for (int i = 0; i < str.Length; i++) {
/* If state is ONE, then do NOT copy
the current character to output if
one of the following conditions is true
...a) Current character is 'b'
(We need to remove 'b')
...b) Current character is 'a'
(Next character may be 'c') */
if (state == ONE && str[i] != 'a'
&& str[i] != 'b') {
str[j] = str[i];
j++;
}
// If state is TWO and current character
// is not 'c' (otherwise we ignore both
// previous and current characters)
if (state == TWO && str[i] != 'c') {
// First copy the previous 'a'
str[j] = 'a';
j++;
// Then copy the current character
// if it is not 'a' and 'b'
if (str[i] != 'a' && str[i] != 'b') {
str[j] = str[i];
j++;
}
}
// Change state according to
// current character
state = (str[i] == 'a') ? TWO : ONE;
}
// If last character was 'a',
// copy it to output
if (state == TWO) {
str[j] = 'a';
j++;
}
return String.Join("", str)
.Substring(0, j)
.ToCharArray();
}
// Driver Code
public static void Main(String[] args)
{
char[] str1 = "ad".ToCharArray();
str1 = StringFilter(str1);
Console.Write(String.Join("", str1) + "\n");
char[] str2 = "acbac".ToCharArray();
str2 = StringFilter(str2);
Console.Write(String.Join("", str2) + "\n");
char[] str3 = "aaac".ToCharArray();
str3 = StringFilter(str3);
Console.Write(String.Join("", str3) + "\n");
char[] str4 = "react".ToCharArray();
str4 = StringFilter(str4);
Console.Write(String.Join("", str4) + "\n");
char[] str5 = "aa".ToCharArray();
str5 = StringFilter(str5);
Console.Write(String.Join("", str5) + "\n");
char[] str6 = "ababaac".ToCharArray();
str6 = StringFilter(str6);
Console.Write(String.Join("", str6) + "\n");
}
}
// This code is contributed by Rajput-Ji
JavaScript
<script>
// A JavaScript program to remove "b" && 'ac' from input string
const ONE = 1
const TWO = 2
// Utility function to convert string to list
function toList(string){
let l = []
for(let x of string)
l.push(x)
return l
}
// Utility function to convert list to string
function toString(l){
return l.join('')
}
// The main function that removes occurrences of "a" && "bc"
// in input string
function stringFilter(string){
// state is initially ONE (The previous character is not a)
let state = ONE
// i && j are index variables, i is used to read next
// character of input string, j is used for indexes of
// output string (modified input string)
let j = 0
// Process all characters of input string one by one
for(let i=0;i<string.length;i++){
// If state is ONE, then do NOT copy the current character
// to output if one of the following conditions is true
// ...a) Current character is 'b' (We need to remove 'b')
// ...b) Current character is 'a' (Next character may be 'c')
if(state == ONE && string[i] != 'a' && string[i] != 'b'){
string[j] = string[i]
j += 1
}
// If state is TWO && current character is not 'c' (other-
// wise we ignore both previous && current characters)
if(state == TWO && string[i] != 'c'){
// First copy the previous 'a'
string[j] = 'a'
j += 1
// Then copy the current character if it is not 'a' && 'b'
if(string[i] != 'a' && string[i] != 'b'){
string[j] = string[i]
j += 1
}
}
// Change state according to current character
state = string[i] == 'a'? TWO : ONE
}
// If last character was 'a', copy it to output
if(state == TWO){
string[j] = 'a'
j += 1
}
return toString(string.slice(0,j))
}
// Driver program
let string1 = stringFilter(toList("ad"))
document.write(string1,"</br>")
let string2 = stringFilter(toList("acbac"))
document.write(string2,"</br>")
let string3 = stringFilter(toList("aaac"))
document.write(string3,"</br>")
let string4 = stringFilter(toList("react"))
document.write(string4,"</br>")
let string5 = stringFilter(toList("aa"))
document.write(string5,"</br>")
let string6 = stringFilter(toList("ababaac"))
document.write(string6,"</br>")
// This code is contributed by shinjanpatra
</script>
Time Complexity: O(n) where n is the length of string str.
Auxiliary Space: O(1)
An extension of above problem where we don't want "ac" in output at all: The above code looks fine and seems to handle all cases, but what if input string is "aacacc", the above code produces output as "ac" which looks correct as it removes consecutive occurrences of 'a' and 'c'. What if the requirement is to not have an "ac" in output string at all. Can we modify the above program to produce output as empty string for input "aacacc" and produce output as "d" when input is "abcaaccd"? It turns out that it can also be done with given restrictions. The idea is simple. We need to add following lines inside for loop of the above program.
C
if (j & gt; 1 & amp; & str[j - 2] == 'a' & amp; &
str[j - 1] == 'c')
j = j - 2;
C++
if (j > 1 && str[j - 2] == 'a' && str[j - 1] == 'c')
j = j - 2;
//This code is contributed by Akahay Tripathi(akshaytripathi19410)
Java
if (j > 1 && str.charAt(j - 2) == 'a'
&& str.charAt(j - 1) == 'c')
j = j - 2;
Python3
if j > 1 and str[j-2] is 'a' and str[j-1] is 'c':
j = j - 2
# This code is contributed by akashish__
C#
if (j > 1 && str[j - 2] == 'a'&& str[j - 1] == 'c')
j = j - 2;
// This code is contributed by akashish__
JavaScript
if (j > 1 && str.charAt(j - 2) == 'a' && str.charAt(j - 1) == 'c') {
j = j - 2;
}
// This code is contributed by akashish__
Output:
Input => ad
Output => ad
Input => acbac
Output =>
Input => aaac
Output => aa
Input => react
Output => ret
Input => aa
Output => aa
Input => ababaac
Output => aaa
Input => abc
Output =>
Thanks to Gaurav Ahirwar for suggesting this simpler solution.
Similar Reads
Remove a Character from a Given Position Given a string and a position (0-based indexing), remove the character at the given position.Examples: Input : s = "abcde", pos = 1Output : s = "acde"Input : s = "a", pos = 0Output : s = ""Approach - By Using Built-In MethodsWe use erase in C++, string slicing in Python, StringBuilder Delete in Java
5 min read
Remove the forbidden strings Given a string W, change the string in such a way that it does not contain any of the "forbidden" strings S1 to Sn as one of its substrings. The rules that govern this change are as follows: Case of the characters does not matter i.e "XyZ" is the same as "xYZ". Change all the characters that are cov
15+ min read
Program for removing i-th character from a string Given a string S along with an integer i. Then your task is to remove ith character from S. Examples: Input: S = Hello World!, i = 7Output: Hello orld!Explanation: The Xth character is W and after removing it S becomes Hello orld! Input: S = GFG, i = 1Output: GGExplanation: It can be verified that a
5 min read
Remove all characters other than alphabets from string Given a string consisting of alphabets and others characters, remove all the characters other than alphabets and print the string so formed. Examples: Input : $Gee*k;s..fo, r'Ge^eks?Output : GeeksforGeeks Input : P&ra+$BHa;;t*ku, ma$r@@s#in}ghOutput : PraBHatkumarsingh Recommended PracticeRemove
12 min read
Remove consecutive vowels from string Given a string s of lowercase letters, we need to remove consecutive vowels from the string Note : Sentence should not contain two consecutive vowels ( a, e, i, o, u). Examples : Input: geeks for geeksOutput: geks for geksInput : your article is in queue Output : yor article is in quApproach: Iterat
15+ min read