Remove “b” and “ac” from a given string

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

We strongly recommend that you click here and practice it, before moving on to the solution.


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++

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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 occurences 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

chevron_right



Output:

ad

aa
ret
aa
aaa

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.

filter_none

edit
close

play_arrow

link
brightness_4
code

if (j>1 && str[j-2] == 'a' && str[j-1] =='c')
  j = j-2;

chevron_right


See this for different test cases of modified program.



A Simpler Solution to the Original Problem:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// // A C++ program to remove "b" and 'ac' from input string
#include<bits/stdc++.h>
using namespace std;
  
void stringFilter(char *str)
{
    int n = strlen(str);
  
    int i = -1;  // previous character
    int j = 0;   // current character
  
    while (j < n)
    {
        /* check if current and next character forms ac */
        if (j < n-1 && str[j] == 'a' && str[j+1] == 'c')
            j += 2;
  
        /* if current character is b */
        else if (str[j] == 'b')
            j++;
  
        /* if current char is 'c && last char in output
           is 'a' so delete both */
        else if (i >= 0 && str[j] == 'c' && str[i] == 'a')
            i--,j++;
  
        /* else copy curr char to output string */
        else
            str[++i] = str[j++];
    }
    str[++i] = '\0';
}
  
// Driver program to test above function
int main()
{
    char str1[] = "ad";
    cout << "Input => " << str1 << "\nOutput => ";
    stringFilter(str1);
    cout << str1 << endl << endl;
  
    char str2[] = "acbac";
    cout << "Input => " << str2 << "\nOutput => ";
    stringFilter(str2);
    cout << str2 << endl << endl;
  
    char str3[] = "aaac";
    cout << "Input => " << str3 << "\nOutput => ";
    stringFilter(str3);
    cout << str3 << endl << endl;
  
    char str4[] = "react";
    cout << "Input => " << str4 << "\nOutput => ";
    stringFilter(str4);
    cout << str4 << endl << endl;
  
    char str5[] = "aa";
    cout << "Input => " << str5 << "\nOutput => ";
    stringFilter(str5);
    cout << str5 << endl << endl;
  
    char str6[] = "ababaac";
    cout << "Input => " << str6 << "\nOutput => ";
    stringFilter(str6);
    cout << str6 << endl << endl;
  
    char str[] = "abc";
    cout << "Input => " << str << "\nOutput => ";
    stringFilter(str);
    cout << str << endl << endl;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// A Java program to remove "b" and 'ac' from input string 
class GfG {
  
// The main function that removes occurences of "a" and "bc" 
// in input string 
static void stringFilter(char str[]) 
    int n = str.length; 
    
    int i = -1// previous character 
    int j = 0;   // current character 
    
    while (j < n) 
    
        /* check if current and next character forms ac */
        if (j < n-1 && str[j] == 'a' && str[j+1] == 'c'
            j += 2
    
        /* if current character is b */
        else if (str[j] == 'b'
            j++; 
    
        /* if current char is 'c && last char in output 
           is 'a' so delete both */
        else if (i >= 0 && str[j] == 'c' && str[i] == 'a')  {
            i--;
            j++; 
        }
    
        /* else copy curr char to output string */
        else
            str[++i] = str[j++]; 
              
    
 System.out.println(new String(str).substring(0,i+1));
  
/* Driver program to check above functions */
public static void main(String[] args) 
    String str1 = "ad"
    stringFilter(str1.toCharArray()); 
  
    String str2 = "acbac"
    stringFilter(str2.toCharArray());
  
    String str3 = "aaac"
    stringFilter(str3.toCharArray()); 
  
    String str4 = "react"
    stringFilter(str4.toCharArray()); 
  
    String str5 = "aa"
    stringFilter(str5.toCharArray()); 
  
    String str6 = "ababaac"
    stringFilter(str6.toCharArray()); 
}

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# A Python program to remove "b" and 'ac' from input string
  
# 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)
  
def stringFilter(string):
  
    # length of string
    n = len(string)
  
    i = -1
    j = 0
  
    while j < n:
  
        # Check if current and next character forms ac
        if j < n-1 and string[j] == 'a' and string[j+1] == 'c':
            j += 2
  
        # If current character is b
        elif string[j] == 'b':
            j += 1
  
        # if current char is 'c && last char in output
        # is 'a' so delete both
        elif i >= 0 and string[j] == 'c' and string[i] == 'a':
            i -= 1
            j += 1
  
        # Else copy curr char to output string
        else:
            i += 1
            string[i] = string[j]
            j += 1
  
    i += 1
    return toString(string[:i])
  
# Driver program
string1 = "ad"
print "Input => " + string1 + "\nOutput => ",
print stringFilter(toList(string1)) + "\n"
  
string2 = "acbac"
print "Input => " + string2 + "\nOutput => ",
print stringFilter(toList(string2)) + "\n"
  
string3 = "aaac"
print "Input => " + string3 + "\nOutput => ",
print stringFilter(toList(string3)) + "\n"
  
string4 = "react"
print "Input => " + string4 + "\nOutput => ",
print stringFilter(toList(string4)) + "\n"
  
string5 = "aa"
print "Input => " + string5 + "\nOutput => ",
print stringFilter(toList(string5)) + "\n"
  
string6 = "ababaac"
print "Input => " + string6 + "\nOutput => ",
print stringFilter(toList(string6)) + "\n"
  
string7 = "abc"
print "Input => " + string7 + "\nOutput => ",
print stringFilter(toList(string7)) + "\n"
  
# This code is contributed by BHAVYA JAIN

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to remove "b" and 'ac' from input string 
using System;
  
class GfG 
  
    // The main function that removes occurences of  
    // "a" and "bc" in input string 
    static void stringFilter(char []str) 
    
        int n = str.Length; 
        int i = -1; // previous character 
        int j = 0; // current character 
        while (j < n) 
        
            /* check if current and next character forms ac */
            if (j < n-1 && str[j] == 'a' && str[j+1] == 'c'
                j += 2; 
      
            /* if current character is b */
            else if (str[j] == 'b'
                j++; 
      
            /* if current char is 'c && last char in output 
            is 'a' so delete both */
            else if (i >= 0 && str[j] == 'c' && str[i] == 'a'
            
                i--; 
                j++; 
            
      
            /* else copy curr char to output string */
            else
                str[++i] = str[j++]; 
              
        
        Console.WriteLine(new String(str)); 
    
  
    // Driver Code
    public static void Main() 
    {    
        String str1 = "ad"
        stringFilter(str1.ToCharArray()); 
          
        String str2 = "acbac"
        stringFilter(str2.ToCharArray()); 
          
        String str3 = "aaac"
        stringFilter(str3.ToCharArray()); 
          
        String str4 = "react"
        stringFilter(str4.ToCharArray()); 
          
        String str5 = "aa"
        stringFilter(str5.ToCharArray()); 
          
        String str6 = "ababaac"
        stringFilter(str6.ToCharArray()); 
    
  
// This code is contributed by 
//PrinciRaj1992 

chevron_right



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.

This article is contributed by Varun Jain. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above



My Personal Notes arrow_drop_up



Article Tags :
Practice Tags :


2


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.