Task is to check if given string contains balanced sets of {}
, []
and ()
.
For example, check(\"{[}]\")
must return
This task is not doable with a regex because they have no memory and cannot remember the depth of parenthesing.
You should use a parser, probably a recursive descent parser, to do the task.
The grammar would look like this (not tested):
input: /* empty */
| expr input
expr: paren-expr
| bracket-expr
| curly-bracket-expr
paren-expr: '(' input ')'
bracket-expr: '[' input ']'
curly-bracket-expr: '{' input '}'
Example code:
#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;
}
Please tell me what is wrong with my code it's always giving NO
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");
}
Checking for nested braces seems like a natural case for std::stack
. Push braces onto the stack as you iterate over the input and test for correct matches when you see a closing brace.
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?
}
Your solution seems overcomplicated and I have to admit that I didn't try too hard to understand it but it is not obvious to me that it is even correct. A very simple solution to this problem is to create a stack and go through the string pushing opening parentheses to the stack and popping from the stack on closing parentheses (when you pop you have to check that the opening and closing parentheses match).
It is unfortunately impossible to solve this problem with regular expressions as the language of well balanced parentheses is not regular.
You can check the matching brackets by following simple piece of code.
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;
}
or if you want to find a specific bracket type then can also use following function.
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;
}