平衡括号 C++ 不工作,我做错了什么

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

我正在尝试平衡括号。输入将包括花括号、圆括号和方括号。我试图找出我在这段代码中做错了什么。我是 c++ 的新手,我正在努力学习。

说明

countcp for curly open brackets
countsp for square open brackets
圆括号
的 countrp countcl 用于大括号或最后一个括号左括号
方括号
的 countsl countrl 圆括号
例如。输入{()}
输出平衡
输入{(}{)}
输出不平衡 它一直工作到第 30 行,然后打印相等,然后给出错误 Segmentation fault (core dumped)

这一行

str.erase(i, 2);

似乎是错误的,因为 i 不是循环的一部分。 i 等于 str.length(); 导致擦除失败。

你是说

str.erase(j, 2);

我看到的问题:

  1. 缺少 return 输入 main。使用:

    int main() ...
    
  2. 越界访问数组。你有:

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

    这还不够。您还需要确保不越界访问 str。因此,将其更改为:

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

    或者更好,

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

    必须使用 j+1,因为您正在循环访问 str[j+1]

  3. 正在从字符串中删除错误的元素。而不是

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

    使用

    str.erase(j, 2);
    //        ^^
    
  4. 您没有正确更新 j 的值。假设 str 等于 "{()}". Whenjis equal to1, you are trying to remove()from the string. After that,stris equal to"{}"。为了能够处理它,您需要将 j 的值设置为 0。逻辑需要是:

    当没有匹配时递增j
    有匹配的时候减j,匹配的字符去掉。

改进建议

ij 使用无符号类型以避免编译器警告。

您可以使用:

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

具有上述修复的 while 循环的更新版本

我还添加了额外的 cout 行来帮助诊断逻辑错误。

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

为了能够像 "{[}{]}" 一样正确地处理输入,您必须稍微重构一下代码。这似乎不是建议精心重构代码以处理此类输入的正确位置。

所以应该是这样的

while(!str.length()==0 and j+1 < str.length())
            {
                     if(str[j]=='{' and str[j+1]=='}')
                    {
                        str.erase(j, 2);
                        countwhile++;
                        j--;
                    }
                else if(str[j]=='(' and str[j+1]==')')
                    {
                        str.erase(j, 2);
                        countwhile++;
                        j--;
                    }
                else if(str[j]=='[' and str[j+1]==']')
                    {
                        str.erase(j, 2);
                        countwhile++;
                        j--;
                    }
                else
                    {
                        j++;
                    }
                if(countwhile>perlen)
                    {
                        countwhile=1;
                        cout<<"reached break"<<endl;
                    }
                if(countwhile==1)
                    {
                        cout<<"Balanced string "<<str1<<endl;
                        break;
                    }
                else
                    {
                        cout<<"not Balanced "<<str1<<endl;
                        break;
                    }
            }