Search code examples
c++stringbrackets

balanced bracket C++ not working, what am i doing wrong


#include<iostream>
#include<string>
using namespace std;

main()
{
    int i, j=0, perlen, countcp=0, countsp=0, countrp=0, countcl=0, countsl=0, countrl=0;
    string str, str1;
    cout<<"Please enter string"<<endl;
    getline(cin, str);
    perlen=(str.length())/2;
    for(i=0; i<str.length(); i++)
    {
        if(str[i]=='{')
            countcp++;  
        if(str[i]=='[')
            countsp++;
        if(str[i]=='(')
            countrp++;
        if(str[i]=='}')
            countcl++;
        if(str[i]==']')
            countsl++;
        if(str[i]==')')
            countrl++;
    }
    str1=str;

    if(countcp==countcl and countsp==countsl and countrp==countrl)
    {
        cout<<"equal"<<endl;
        int countwhile=0, j=0;
        while(!str.length()==0)
        {
            if(str[j]=='{' and str[j+1]=='}')
            {
                str.erase(i, 2);
                countwhile++;
            }
            else if(str[j]=='(' and str[j+1]==')')
            {
                str.erase(i, 2);
                countwhile++;
            }
            else if(str[j]=='[' and str[j+1]==']')
            {
                str.erase(i, 2);
                countwhile++;
            }
            if(countwhile>perlen)
            {
                countwhile=1;
                cout<<"reached break"<<endl;
                break;
            }
            j++;
        }
        if(countwhile==1)
        {
            cout<<"Balanced string "<<str1<<endl;
        }
    }
}

i am trying to balance brackets. input will include curly, round and square brackets. i am trying to find what i did wrong in this code. i am new to c++ and i am trying to learn.

explanation

countcp for curly open brackets
countsp for square open brackets
countrp for round open brackets
countcl for curly close or last bracket open brackets
countsl for square close brackets
countrl for round close brackets
eg. input {()}
output balanced
input {(}{)}
output not balanced it works till line 30 and prints equal after that it gives error Segmentation fault (core dumped)


Solution

  • Problems I see:

    1. Missing return type in main. Use:

      int main() ...
      
    2. Accessing array out of bounds. You have:

      while ( !str.length() == 0 ) 
      

      That is not adequate. You also need to make sure that you don't access str out of bounds. Hence, change that to:

      while ( !str.length() == 0 && j+1 < str.length() ) 
      

      or, better,

      while ( !str.empty() && j+1 < str.length() ) 
      

      Use of j+1 is necessary since you are accessing str[j+1] in the loop.

    3. Erasing the wrong elements from the string. Instead of

      str.erase(i, 2);
      //        ^^
      

      use

      str.erase(j, 2);
      //        ^^
      
    4. You are not updating the value of j properly. Say str is equal to "{()}". Whenjis equal to1, you are trying to remove()from the string. After that,stris equal to"{}". In order to be able process that, you need to set the value of j to 0. The logic needs to be:

      Increment j when there is no match.
      Decrement j when there is a match and the matching characters are removed.

    Suggestion for improvement

    Use an unsigned type for i and j to avoid compiler warnings.

    You can use:

    std::string::size_type i = 0;
    std::string::size_type j = 0;
    

    Updated version of the while loop with the above fixes

    I have also added additional cout lines to help diagnose logic errors.

      int countwhile=0;
      std::string::size_type j=0;
      while(!str.length()==0 && j+1 < str.length())
      {
         if(str[j]=='{' and str[j+1]=='}')
         {
            cout<<"erasing {}"<<endl;
            str.erase(j, 2);
            cout << str << endl;
            countwhile++;
            --j;
         }
         else if(str[j]=='(' and str[j+1]==')')
         {
            cout<<"erasing ()"<<endl;
            str.erase(j, 2);
            cout << str << endl;
            countwhile++;
            --j;
         }
         else if(str[j]=='[' and str[j+1]==']')
         {
            cout<<"erasing []"<<endl;
            str.erase(j, 2);
            cout << str << endl;
            countwhile++;
            --j;
         }
         else
         {
            j++;
         }
         if(countwhile>perlen)
         {
            countwhile=1;
            cout<<"reached break"<<endl;
            break;
         }
      }
    

    In order to be able process input like "{[}{]}" correctly, you have to restructure the code a bit. This does not seem like the right place to suggest an elaborate refactoring of your code to be able to handle such input.