0
#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 用于弯圆括号countsp 用于s方圆括号countrp 用于圆开括号countcl 用于大括号或最后一个括号开括号 countsl 用于方括号 countrl 用于圆闭括号 例如。输入 {()} 输出平衡 输入 {(}{)} 输出不平衡 它一直工作到第 30 行并打印 equal 之后它给出错误 Segmentation fault (core dumped)








4

3 回答 3

0

我看到的问题:

  1. 中缺少返回类型main。利用:

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

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

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

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

    或更好,

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

    使用 ofj+1是必要的,因为您正在str[j+1]循环中访问。

  3. 从字符串中删除错误的元素。代替

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

    利用

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

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

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

于 2016-01-11T07:43:38.907 回答
0

所以应该是这样的

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;
                    }
            }
于 2016-01-11T08:13:31.110 回答
0

这条线

str.erase(i, 2);

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

你的意思

str.erase(j, 2);
于 2016-01-11T07:27:57.313 回答