我在这里有一个小问题:我们的老师要求我们编写一个程序,检查括号,方括号和卷曲括号是否有效。例如:[[{{{(())}}}]]
是有效用法,但()))
,[[((]]))
(后者在此处交错)是无效的。
这是我的尝试:
int main(){
string input;
cout << "Enter a text: "
cin >> input;
int nSquareBracketRight = count(s.begin(), s.end(), '[');
int nSquareBracketLeftt = count(s.begin(), s.end(), ']');
if(nSquareBracketRight != nSquareBracketLeft)
cout << "Invalid!" << endl;
else
cout << "Valid Usage!" << endl;
return 0;
}
上面看起来还可以,但是如果出现的次数相等,但是如果较小的索引中有一个“正在关闭”的字符,则认为它无效,例如:{}}{
无效。
请帮助,谢谢大家!
答案 0 :(得分:3)
这是堆栈所适合的情况,例如std::stack
,例如:
#include <iostream>
#include <string>
#include <stack>
using namespace std;
bool areBracketsValid(const string &input)
{
stack<char> stk;
for(string::size_type i = 0; i < input.size(); ++i)
{
char ch = input[i];
switch (ch)
{
case '(':
case '[':
case '{':
{
stk.push(ch);
break;
}
case ')':
case ']':
case '}':
{
if (stk.empty())
return false;
char openingCh = (ch == ')') ? '(' : (ch == ']') ? '[' : '{';
if (stk.top() != openingCh)
return false;
stk.pop();
break;
}
}
}
return stk.empty();
}
int main()
{
string input;
cout << "Enter a text: ";
cin >> input;
if (areBracketsValid(input))
cout << "Valid Usage!" << endl;
else
cout << "Invalid!" << endl;
return 0;
}
答案 1 :(得分:1)
使用std :: count很好,但这不是程序中需要的;您还需要一些对索引感兴趣的东西。
您可以为每种类型的括号声明一个变量,该变量保存其出现的次数 并在循环内增加目标变量(如果它与测试的字符匹配)。
在递增后在循环内部,检查左方括号号是否小于右方括号, 如果是这样,则认为它无效。例如:(()))( 正如您在上面看到的,打开和关闭的数量是可以的,但是它被认为是无效的用法,因为从不以括号开头的事实是关闭括号!
因此,请打破循环,告知无效用法。
最终比较循环外的打开和关闭次数,这是因为 在循环内部,我们可以打开n括号,因此只有在循环结束后才进行检查,以获取闭合的数目。例如: (([[[[{{{无法在循环内检查。
#include <iostream>
#include <string>
int main(){
std::string str;
std::cin >> str;
int nParR = 0, nParL = 0, nBrackR = 0,
nBrackL = 0, nCurlR = 0, nCurlL = 0;
for(auto i(0); i != str.length(); ++i){
switch(str[i]){
case '(':
nParR++;
break;
case ')':
nParL++;
break;
case '[':
nBrackR++;
break;
case ']':
nBrackL++;
break;
case '{':
nCurlR++;
break;
case '}':
nCurlL++;
break;
}
if(nParR < nParL || nBrackR < nBrackL ||
nCurlR < nCurlL){
std::cout << "Invalid usage!" << std::endl;
break;
}
}
if(nParR == nParL && nBrackR == nBrackL && nCurlR == nCurlL)
std::cout << "Valid usage!" << std::endl;
else
std::cout << "Invalid Usage!";
std::cout << std::endl;
return 0;
}
答案 2 :(得分:1)
这确实很容易实现:假设您输入了这样的内容:([{}])
被认为是正确的,不是吗?但([)]
无效。
在正确的位置上,您可以看到element i
是左括号,而element i + 1
是同一括号族的右括号。这被认为是有效的,因此诀窍是删除该子集括号,直到堆栈/向量为空。如果是这样,则整个输入正确,否则无效。
提示:在循环内,擦除element i
和element i + 1
(仅当且仅当元素i正在打开且元素i + 1正在关闭并且element i
和element i + 1
属于同一家族,例如:{}, [], ()
。
#include <iostream>
#include <string>
#include <vector>
int main(){
std::string str = "[({}{})]"; // valid
// std::string str = "["; // invalid
// std::string str = "[(])"; // invalid
// std::string str = "[({}{})]]"; // invalid
// std::string str = "[({}{}])"; // invalid
// std::string str = "{{}[{}]{(())}}"; // valid
// std::string str = "][(){}"; // invalid
std::vector<char> vecStr;
bool isDone = false;
for(auto i(0); i != str.length(); ++i)
vecStr.push_back(str[i]);
for(auto i(0); i != vecStr.size(); ++i)
std::cout << vecStr[i];
std::cout << std::endl;
for(auto i(0); i < str.length() / 2 && !isDone; ++i){
for(auto j(0) ; j < vecStr.size() - 1; ++j){
if(!vecStr.size()){
isDone = true;
break;
}
switch(vecStr[j]){
case '{':
if(vecStr[j + 1] == '}'){
vecStr.erase(&vecStr[j]);
vecStr.erase(&vecStr[j]);
}
break;
case '(':
if(vecStr[j + 1] == ')'){
vecStr.erase(&vecStr[j]);
vecStr.erase(&vecStr[j]);
}
break;
case '[':
if(vecStr[j + 1] == ']'){
vecStr.erase(&vecStr[j]);
vecStr.erase(&vecStr[j]);
}
break;
}
}
}
std::cout << "size: " << vecStr.size() << std::endl;
if(vecStr.size())
std::cout << "Invalid Input!" << std::endl;
else
std::cout << "valid Input!" << std::endl;
std::cout << std::endl;
return 0;
}
只需在上面的输入行中取消注释就可以看到结果。或使用std::cin
输入。