任务是检查给定的字符串是否包含{}
,[]
和()
的平衡集。
例如,check("{[}]")
必须返回false
,check("{[]()}")
必须返回true
等。
解决方案:
bool check(const std::string & s)
{
constexpr auto brackets1 = "()";
constexpr auto brackets2 = "[]";
constexpr auto brackets3 = "{}";
constexpr size_t brackets_pair_size = 2;
constexpr auto brackets = "()[]{}";
std::string s2;
for (auto & c : s)
{
if (strchr(brackets, c) != nullptr)
{
s2 += c;
}
}
auto brackets1_pos{ std::string::npos };
auto brackets2_pos{ std::string::npos };
auto brackets3_pos{ std::string::npos };
while ((brackets1_pos = s2.find(brackets1)) != std::string::npos ||
(brackets2_pos = s2.find(brackets2)) != std::string::npos ||
(brackets3_pos = s2.find(brackets3)) != std::string::npos
)
{
if (brackets1_pos != std::string::npos) {
s2.erase(brackets1_pos, brackets_pair_size);
continue;
}
if (brackets2_pos != std::string::npos) {
s2.erase(brackets2_pos, brackets_pair_size);
continue;
}
if (brackets3_pos != std::string::npos) {
s2.erase(brackets3_pos, brackets_pair_size);
continue;
}
}
return s2.empty();
}
想法是: - 将所有的句子,括号和大括号复制到另一个字符串, - 从第二个字符串中删除一对括号, - 检查第二个字符串是否为空。
有没有办法改进算法?
可能是一些普遍的正则表达式吗?
答案 0 :(得分:3)
检查嵌套大括号似乎是std::stack
的自然情况。在迭代输入时将大括号推入堆栈,并在看到右大括号时测试正确的匹配。
bool check(const std::string &expression) // balanced and nested?
{
std::stack<char> stack;
for (auto ch : expression) {
switch (ch) {
case '(': // open parenthesis
case '<': // open angle
case '[': // open bracket
case '{': // open brace
stack.push(ch);
break;
case ')': // close parenthesis
if (stack.empty() || stack.top() != '(') return false;
stack.pop();
break;
case '>': // close angle
if (stack.empty() || stack.top() != '<') return false;
stack.pop();
break;
case ']': // close bracket
if (stack.empty() || stack.top() != '[') return false;
stack.pop();
break;
case '}': // close brace
if (stack.empty() || stack.top() != '{') return false;
stack.pop();
break;
}
}
return stack.empty(); // no unmatched braces left?
}
答案 1 :(得分:1)
这个任务不适用于正则表达式,因为它们没有记忆,也记不起括号的深度。
您应该使用解析器(可能是recursive descent parser)来完成任务。
语法看起来像这样(未经测试):
input: /* empty */
| expr input
expr: paren-expr
| bracket-expr
| curly-bracket-expr
paren-expr: '(' input ')'
bracket-expr: '[' input ']'
curly-bracket-expr: '{' input '}'
示例代码:
#include <iostream>
#include <iterator>
#include <string>
class parenthesis_checker {
template <class It>
It parse_open_close(It first, It last, char op, char cl) const {
if(op != *first) return first;
It r = parse_input(first+1, last);
if(last == r) return first;
if(cl != *r) return first;
return r+1;
}
template <class It>
It parse_expr(It first, It last) const {
It r = parse_open_close(first, last, '(', ')');
if(r != first) return r;
r = parse_open_close(first, last, '[', ']');
if(r != first) return r;
r = parse_open_close(first, last, '{', '}');
if(r != first) return r;
return first;
}
template <class It>
It parse_input(It first, It last) const {
while(first != last) {
It r = parse_expr(first, last);
if(r == first) return r;
first = r;
}
return first;
}
public:
template <class It>
bool operator()(It first, It last) const {
return last==parse_input(first, last);
}
template <class Cont>
bool operator()(Cont value) const {
return (*this)(value.begin(), value.end());
}
bool operator()(const char* str) const {
return (*this)(std::string(str));
}
};
int main() {
parenthesis_checker check;
std::cout << check("{[}]") << std::endl;
std::cout << check("{[]()}") << std::endl;
}
答案 2 :(得分:1)
你的解决方案看起来过于复杂,我不得不承认我并没有太努力去理解它,但对我来说这是不正确的,甚至是正确的。 这个问题的一个非常简单的解决方案是创建一个堆栈并通过字符串将开括号推到堆栈并在关闭括号时从堆栈弹出(当你弹出时,你必须检查开始括号和右括号是否匹配)。 p>
遗憾的是,用正则表达式解决这个问题是不可能的,因为平衡括号的语言不是regular。
答案 3 :(得分:1)
您可以通过以下简单的代码检查匹配的括号。
int bracketMatcher(string s)
{
list<int> *countsList = new list<int>();
string expression = s;
int correctBrackets = 1;
for (int index = 0; index < expression.size(); index++) {
char ch = expression[index];
if (ch == '(')
{
countsList->push_back(index);
}
else if (ch == ')')
{
if (countsList->size() == 0)
{
correctBrackets = 0;
break;
}
countsList->pop_back();
}
}
if (countsList->size() != 0)
{
correctBrackets = 0;
}
return correctBrackets;
}
或者如果要查找特定的括号类型,也可以使用以下功能。
bool bracketMatcher(string s , char c)
{
list<int> *countsList = new list<int>();
string expression = s;
bool correctBrackets = true;
char secondCh =' ';
switch (c) {
case '(': // open parenthesis
secondCh = ')';
break;
case '<': // open angle
secondCh = '>';
break;
case '[': // open bracket
secondCh = ']';
break;
case '{': // open brace
secondCh = '}';
break;
default:
break;
}
for (int index = 0; index < expression.size(); index++) {
char ch = expression[index];
if (ch == c)
{
countsList->push_back(index);
}
else if (ch == secondCh)
{
if (countsList->size() == 0)
{
correctBrackets = false;
break;
}
countsList->pop_back();
}
}
if (countsList->size() != 0)
{
correctBrackets = false;
}
return correctBrackets;
}
int main() {
string s = " ((hello ) (()) llll {}word <aaa>(aad))";
//always specify the opening bracket here
bool parenthesisMatch = bracketMatcher(s,'(');
bool angleBracketsMatch = bracketMatcher(s,'<');
bool bracketMatch = bracketMatcher(s,'[');
bool bracesMatch = bracketMatcher(s, '{');
if(parenthesisMatch && angleBracketsMatch && bracketMatch && bracesMatch) {
cout << "found all matching brackets" << endl;
}
else{
cout << "could not find all matching brackets" << endl;
}
return 0;
}
答案 4 :(得分:0)
请告诉我我的代码有什么问题,它总是不提供
string isBalanced(string s) {
stack<char> comp;
char temp;
int i;
for(i=s.size()-1;(s[i]=='}' ) || (s[i]==')' ) || (s[i]==']');i--)
{
comp.push(s[i]);
}
if(comp.size()!=i+1)
return ("NO");
while(!comp.empty() && i>=0)
{
temp=comp.top();
if(temp!=s[i])
return ("NO");
comp.pop();
i--;
}
return("YES");
}