строка — сбалансированная скобка C ++ не работает, что я делаю не так

#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 ++, и я пытаюсь учиться.

объяснение

рассчитывать на сурапen скобки
рассчитывать на sQuare оскобки для ручек
countrp для круглых открытых скобок
countcl для фигурных закрывающих или последних открытых скобок
countsl для квадратных скобок
countrl для круглых скобок
например. вход {()}
сбалансированный выход
вход {(} {)}
выход не сбалансирован
работает до строки 30 и выдает равные значения, после этого выдает ошибку Сегментация (ядро сброшено)

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

    Использование 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,улis equal to«{}». Для того, чтобы иметь возможность обрабатывать это, вам нужно установить значение j в 0, Логика должна быть:

    инкремент j когда нет матча.
    декремент j когда есть совпадение и совпадающие символы удаляются.

Предложение по улучшению

Используйте тип без знака для i а также j чтобы избежать предупреждений компилятора.

Ты можешь использовать:

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

Для того, чтобы иметь возможность обрабатывать ввод, как "{[}{]}" правильно, вы должны немного реструктурировать код. Это не то место, где можно предложить сложный рефакторинг вашего кода, чтобы иметь возможность обрабатывать такие входные данные.

0

Другие решения

Эта линия

str.erase(i, 2);

кажется неправильным как i не является частью цикла. i равно str.length(); что приводит к сбою стирания.

Ты имел ввиду

str.erase(j, 2);
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;
}
}
0