【问题标题】:balanced bracket C++ not working, what am i doing wrong平衡括号C ++不起作用,我做错了什么
【发布时间】:2016-01-11 07:05:09
【问题描述】:
#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 括号
s四方o圆括号
圆括号的countrp
countcl 用于大括号或最后一个括号打开括号
countsl 用于方括号
圆括号的国家/地区
例如。输入 {()}
输出平衡
输入 {(}{)}
输出不平衡 它一直工作到第 30 行并打印 equal 之后它给出错误 Segmentation fault (core dumped)

【问题讨论】:

  • 解释失败案例
  • 您应该使用调试器检查您的代码,并逐行检查您的代码。这可能比在这里问一个不清楚的问题更有效率。
  • 您只检查str[j]str[j+1]。我建议对这个问题更好地使用堆栈。
  • 你的 while 条件永远不会变为零。

标签: c++ string brackets balance


【解决方案1】:

我看到的问题:

  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() ) 
    

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

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

【讨论】:

  • 非常感谢,现在它可以工作了。我仍在为更大的字符串测试它。
  • 在它适用于 ({}) 的所有编辑之后。但不适用于 ({({}}))。
  • @Dementor,您将需要使用不同的策略和算法来处理此类输入。在更新程序之前,您必须花一些时间在铅笔和纸上完成这些输入。
  • @R Sahu,我匹配相邻的括号他们为什么失败
  • @Dementor,不,你不是。仔细看。
【解决方案2】:

这一行

str.erase(i, 2);

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

你是说

str.erase(j, 2);

【讨论】:

  • 是的,我的意思是 j thnx 寻求帮助,但现在我收到一个错误终止,在抛出 'std::out_of_range' 的实例后调用 what(): basic_string::erase Aborted (core dumped)
  • 我认为您需要在每次擦除后将j 设置回零。或者也许将其设置为-1,因为稍后您有j++。这个想法必须是在删除匹配对时重新开始。
  • 是的,这是我忘记将 j 设为零的问题。 thnx 现在它正在工作
【解决方案3】:

所以应该是这样的

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多