Harry Wang
Harry Wang

Reputation: 85

Matching balanced and nested braces in input text

I attended a quiz, I gave the code but the auto-test shows that one of the eight test cases failed. I myself tested my code many times, but all passed. I can't find where is the problem.

The question is to design a algorithm to check whether the brackets in a string match.

1) Just consider rounded brackets () and square brackets [], omit ohter chars.
2) Each pair brackets should match each other. That means matches ), and [ matches ].
3) Intercrossing is not allowed, such as : ([)]. There are two pairs of brackets, but they intercross each other.

To solve the problem, my method is described as follows:

  1. Search each char in the whole input string, the index from 0 to str.size() - 1.
  2. Use two stacks to record the opening tag (, and [, each type in one stack. When encountering one of them, push its index in the corresponding stack.
  3. When encouterning the closing tag ) and ], we pop the corresponding stack.
  4. Before popping, check the top of two stacks, the current stack should have the max index, otherwise that means there are unmatched opening tag with the other type, so the intercrossing can be checked this way.

My Code is Here:

#include <iostream>
#include <stack>
using namespace std;

int main()
{
    string str;
    cin >> str;

    stack<int> s1, s2;
    int result = 0;
    for (int ix = 0, len = str.size(); ix < len; ix++)
    {
        if (str[ix] == '(')
        {
            s1.push(ix);
        }
        else if (str[ix] == '[')
        {
            s2.push(ix);
        }
        else if (str[ix] == ')')
        {
            if (s1.empty() || (!s2.empty() && s1.top() < s2.top()))
            {
                result = 1;
                break;
            }
            s1.pop();
        }
        else if (str[ix] == ']')
        {
            if (s2.empty() || (!s1.empty() && s2.top() < s1.top()))
            {
                result = 1;
                break;
            }
            s2.pop();
        }
        else
        {
            // do nothing
        }
    }
    if (!s1.empty() || !s2.empty())
    {
        result = 1;
    }
    cout << result << endl;
}

As methoned before, this question can be solved by just on stack, so I modified my code, and here is the single stack version. [THE KEY POINT IS NOT TO ARGUE WHITCH IS BETTER, BUT WHAT'S WRONG WITH MY CODE.]

#include <iostream>
#include <stack>
using namespace std;

int main()
{
    string str;
    cin >> str;

    stack<char> s;
    const char *p = str.c_str();
    int result = 0;
    while (*p != '\0')
    {
        if (*p == '(' || *p == '[')
        {
            s.push(*p);
        }
        else if (*p == ')')
        {
            if (s.empty() || s.top() != '(')
            {
                result = 1;
                break;
            }
            s.pop();
        }
        else if (*p == ']')
        {
            if (s.empty() || s.top() != '[')
            {
                result = 1;
                break;
            }
            s.pop();
        }
        else
        {
            // do nothing
        }
        p++;
    }
    if (!s.empty())
    {
        result = 1;
    }
    cout << result << endl;
}

Upvotes: 4

Views: 2613

Answers (1)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153840

When using formatted input to read a std::string only the first word is read: after skipping leading whitespate a string is read until the first whitespace is encountered. As a result, the input ( ) should match but std::cin >> str would only read (. Thus, the input should probably look like this:

if (std::getline(std::cin, str)) {
    // algorithm for matching parenthesis and brackets goes here
}

Using std::getline() still makes an assumption about how the input is presented, namely that it is on one line. If the algorithm should process the entire input from std::cin I would use

str.assign(std::istreambuf_iterator<char>(std::cin),
           std::istreambuf_iterator<char>());

Although I think the algorithm is unnecessary complex (on stack storing the kind of parenthesis would suffice), I also think that it should work, i.e., the only problem I spotted is the way the input is obtained.

Upvotes: 1

Related Questions