Checking balanced parantheses code is not behaving as per expectation - c++

I am solving a question in which I have to check if the input string of parentheses are balanced or not,
and if not, code is expected to return the 1-based index of unmatched closing parenthesis, and if not found, return the 1-based index of the opening parenthesis. My code runs fine if I implement only the parenthesis checking part, but as I try to implement the returning index part, the code starts giving 'success' output for all the input.
Here is the code:
#include<iostream>
#include<string>
#include<algorithm>
#include<stack>
using namespace std;
int process_input( string value );
bool closing_bracket_match(char opening_bracket, char closing_bracket);
bool closing_bracket_match(char opening_bracket , char closing_bracket){
if( (opening_bracket == '{' && closing_bracket == '}') || (opening_bracket == '(' && closing_bracket == ')') || (opening_bracket == '[' &&
closing_bracket == ']') ){
return true;
}
else{
return false;
}
}
int process_input( string value ){
stack<char> processed_input{};
int unmatched_index{};
for( size_t i{}; i< value.size() ; ++i ){
if( value.at(i) == '{' || value.at(i) == '(' || value.at(i) == '[' ){ // check for opening brackets
processed_input.push(value.at(i)); // Appending opening bracket into the stack
}
else if( (value.at(i) == '}' || value.at(i) == ')' || value.at(i) == ']') && (processed_input.empty() == false) &&
closing_bracket_match(processed_input.top(),value.at(i)) ){ // the bracket in stack would be popped
processed_input.pop(); // matching brackets ar removed
}
}
if( processed_input.empty()==true ){
return 0;
}//This part is causing the bug
if(processed_input.empty() == false){
auto it = find( value.begin(), value.end(), processed_input.top() );
if( it!= value.end() ){
unmatched_index = distance(value.begin() , it)+1; //returning the 1 -based index of unmatched bracket
}
return unmatched_index;
}
}
int main(){
string input{};
cout<<"Please enter the code here: "; // debug line
cin>> input;
int result{};
result = process_input(input);
if( result == 0 ){
cout<<"Success";
}
else{
cout<<result;
}
}

If you want to return a position of the last (innermost) unmatched paren, you need to store it together with its position on the stack. Seeking for it leads to errors.
Which of potentially several items equal to the one you seek will find() find?
For example, in "(((" there are three unmatched opening parentheses, and all of them are equal to '('. Which one do you want to return as a result? Which one do you actually return?
And how about this input: "()("...?
Added
Here is a possible solution. Please note how it does not find() anything, but it stores on a stack all information necessary to produce the desired output.
#include<iostream>
#include<string>
#include<stack>
using std::string;
using std::stack;
bool is_opening(char c) {
return c == '(' || c == '[' || c == '{';
}
bool is_closing(char c) {
return c == ')' || c == ']' || c == '}';
}
bool is_matching(char opn, char cls) {
switch(opn) {
case '(': return cls == ')';
case '[': return cls == ']';
case '{': return cls == '}';
}
return false;
}
int process_input( string value )
{
stack<char> opn_parens{};
stack<size_t> positions{};
for( size_t i{}; i < value.size() ; ++i )
{
const char ch = value.at(i);
if( is_opening(ch) )
{
opn_parens.push(ch);
positions.push(i);
}
else if( is_closing(ch) )
{
if( opn_parens.empty() ) // a closing paren with no unmatched opening one
return i + 1;
const char opn_ch = opn_parens.top();
const size_t opn_pos = positions.top();
if( ! is_matching(opn_ch, ch) ) // unmatched closing paren
return opn_pos + 1;
opn_parens.pop(); // remove a matched paren
positions.pop();
}
}
if( ! positions.empty() ) // some unmatched parens remain
return positions.top() + 1;
return 0;
}
int main(){
std::cout << process_input("hello(mum[]{(dad()[bro!])})") << std::endl;
std::cout << process_input("))") << std::endl;
std::cout << process_input("([") << std::endl;
std::cout << process_input("([)") << std::endl;
std::cout << process_input("([{") << std::endl;
}
You can see it working at https://godbolt.org/z/e8fYW5fKz

Related

How figlet fit and smush?

I am creating a figlet like code in c++ and i am currently doing fiting by inserting null at left side character and find min space and remove minspace and null the character,( for understanding take null as '0' )
" __0 "
"| _|0 "
"| |0 _____ "
"| |0 |_____|"
"| |0 $ "
"|__|0 "
(if any space line i insert null at start) Now here min space is 3 so i remove 3 space and null in that and this code works perfect and smushing by inheriting the fitting class and i will pass the right side char by inserting null like
" 0"
" 0"
" _0____ "
"|0_____|"
" $0 "
" 0"
it will give result like
" __ 0"
"| _| 0"
"| | _0____ "
"| ||0_____|"
"| | $0 "
"|__| 0"
Now i will store pos of null and remove it, In next loop check the two character before the null, if any one are HardBlank then i return the function else i smush it in next loop, but above are not smush( not work correctly ) due to HardBlank, so i want to know how figlet actually smush i downloaded the figlet code from here but i did not understand the code.
There is any better algorithm than this or How figlet actually do fitting and smushing ?
All suggestions are welcome,
Thanks in advance.
I asked this question long time ago now, But I answering this question now for future readers I have written algorithm a better than this some time ago that do the following,
Kerning or fitting :
The main part of this thing is trim, so lets create an function that takes two input that figs is left side FIGchar and figc is right side FIGchar. The first thing to do is find the number of space that need to be removed from right side of figs and left side of figc, we can easily find this by counting total space in right size of figs and left side of figc. Finally take minimum of that that is the space count that has to be removed here is that implementation,
/**
* #brief trims in a deep
*
* #param figs fig string
* #param figc fig character
*/
void trim_deep(Figs_type &figs, Figc_type &figc) const
{
std::vector<size_type> elem;
for (size_type i = 0; i < figs.size(); ++i)
{
int lcount = 0, rcount = 0;
for (auto itr = figs[i].rbegin(); itr != figs[i].rend(); ++itr)
{
if (*itr == ' ')
++lcount;
else
break;
}
for (auto itr = figc[i].begin(); itr != figc[i].end(); ++itr)
{
if (*itr == ' ')
++rcount;
else
break;
}
elem.push_back(lcount + rcount);
}
size_type space = *std::min_element(elem.begin(), elem.end());
for (size_type i = 0; i < figs.size(); ++i)
{
size_type siz = space;
while (siz > 0 && figs[i].back() == ' ')
{
figs[i].pop_back();
--siz;
}
figc[i].erase(0, siz);
}
}
Smushing:
This smushing can be done easily by using above function with only smush right most character of figs and left side character of figc if it is smushble here is implementation,
/**
* #brief smush rules
* #param lc left character
* #param rc right character
* #return smushed character
*/
char_type smush_rules(char_type lc, char_type rc) const
{
//()
if (lc == ' ')
{
return rc;
}
if (rc == ' ')
{
return lc;
}
//(Equal character smush)
if (lc == rc)
{
return rc;
}
//(Underscores smush)
if (lc == '_' && this->cvt("|/\\[]{}()<>").find(rc) != string_type::npos)
{
return rc;
}
if (rc == '_' && this->cvt("|/\\[]{}()<>").find(lc) != string_type::npos)
{
return lc;
}
//(Hierarchy Smushing)
auto find_class = [](char_type ch) -> size_type
{
if (ch == '|')
{
return 1;
}
if (ch == '/' || ch == '\\')
{
return 3;
}
if (ch == '[' || ch == ']')
{
return 4;
}
if (ch == '{' || ch == '}')
{
return 5;
}
if (ch == '(' || ch == ')')
{
return 6;
}
return 0;
};
size_type c_lc = find_class(lc);
size_type c_rc = find_class(rc);
if (c_lc > c_rc)
{
return lc;
}
if (c_rc > c_lc)
{
return rc;
}
//(Opposite smush)
if (lc == '[' && rc == ']')
{
return '|';
}
if (lc == ']' && rc == '[')
{
return '|';
}
if (lc == '{' && rc == '}')
{
return '|';
}
if (lc == '}' && rc == '{')
{
return '|';
}
if (lc == '(' && rc == ')')
{
return '|';
}
if (lc == ')' && rc == '(')
{
return '|';
}
//(Big X smush)
if (lc == '/' && rc == '\\')
{
return '|';
}
if (lc == '\\' && rc == '/')
{
return 'Y';
}
if (lc == '>' && rc == '<')
{
return 'X';
}
//(universel smush)
return lc;
}
/**
* #brief smush algoriths on kerned Fig string and character
*
* #param figs
* #param figc
*/
void smush(Figs_type &figs, Figc_type figc, char_type hb) const
{
bool smushble = true;
for (size_type i = 0; i < figs.size(); ++i)
{
if (figs[i].size() == 0 || figc[i].size() == 0)
{
smushble = false;
}
else if ((figs[i].back() == hb) && !(figc[i].front() == hb))
{
smushble = false;
}
}
if (smushble)
{
for (size_type i = 0; i < figs.size(); ++i)
{
char_type val = smush_rules(figs[i].back(), figc[i].front());
figs[i].pop_back();
figc[i].erase(0, 1);
figs[i] += string_type(1, val) + figc[i];
}
}
else
{
for (size_type i = 0; i < figs.size(); ++i)
{
figs[i] += figc[i];
}
}
}
This code is directly copied from this file, So the types can be confusing here is overview Figs_type and Figc_type are just like vector of string and other type are reflects in their name and the repo can be found here.

Wrote a C++ code to check if expression has balanced parenthesis and my code is not running. I have been stuck for a day now

The code is given below. There is no syntax error and the code used to run perfectly fine if i checked match for only () parenthesis but after i added some if.. else.. statements to check match for other brackets, my code broke. I am unable to figure out my mistake. Please Help!! I think i did some silly mistake but can't figure out what.
// structure of a stack
struct stackStructure
{
// top pointer of the stack
int top;
// pointer to the array/stack
char *array;
}stack;
// function to push element to stack
void push(char data)
{
if(stack.top == 999)
{
cout<<"Stack Overflow"<<endl;
return;
}
else
{
// incrementing the top and then pushing data to the stack
stack.top++;
stack.array[stack.top]= data;
}
} // end of push() function
// function to pop elements from the stack
char pop()
{
if(stack.top == -1)
return '\0';
else
// returning the popped value and then decrementing the top pointer
return stack.array[stack.top--];
} // end of pop() function
int main()
{
// match variable to keep track that closing bracket and opening brackets are in sequence
char match= '\0';
bool isMatching= true;
// resetting the stack variables and attributes
stack.top= -1;
stack.array= new char[1000];
cout<<"Enter the Expression to match the parenthesis: ";
cin>>stack.array;
// traversing through the character array and matching parenthesis
for(int i=0; stack.array[i] != NULL; i++)
{
// if character is an opening bracket
if(stack.array[i] == '(' || stack.array[i] == '{' || stack.array[i] == '[')
push(stack.array[i]);
// if character is a closing bracket
else if(stack.array[i] == ')' || stack.array[i] == '}' || stack.array[i] == ']')
{
match= pop();
if(stack.array[i] != match)
isMatching= false;
}
// if character is anything else we do nothing
else
continue;
}
if(isMatching == true)
cout<<"Parenthesis Matched"<<endl;
else
cout<<"Not matched"<<endl;
return 0;
}
You have 2 bugs. The first is reading your input string into your stack, this will at minimum get very confusing and at worst not work.
The second is that when checking for matching tags you check that the opening bracket is the same as the closing one, this will never be true, you need to check that the opening bracket is the same type as the closing one.
One way of solving both bugs would be:
int main()
{
// match variable to keep track that closing bracket and opening brackets are in sequence
char match = '\0';
bool isMatching = true;
// resetting the stack variables and attributes
stack.top = -1;
stack.array = new char[1000];
std::string input;
cout << "Enter the Expression to match the parenthesis: ";
cin >> input;
std::map<char, char> opening = { { ')', '(' }, { '}', '{' }, { ']', '[' } };
// traversing through the character array and matching parenthesis
for (char ch : input)
{
// if character is an opening bracket
if (ch == '(' || ch == '{' || ch == '[')
push(ch);
// if character is a closing bracket
else if (ch == ')' || ch == '}' || ch == ']')
{
match = pop();
auto open = opening.find(ch);
if (open == opening.end() || open->second != match )
isMatching = false;
}
}
if (isMatching == true)
cout << "Parenthesis Matched" << endl;
else
cout << "Not matched" << endl;
delete[] stack.array;
return 0;
}

C++ Program to detect if Parenthesis, Brackets and Braces are Balanced - Need to Output Caret Under Errors

I need to write a program that uses a stack to verify if a string expression is balanced, in regards to the parenthesis, brackets, and curly braces contained in it. The string's are to be inputted by the user, and all errors (i.e. mismatched parenthesis, brackets, and curly braces) need to be pointed out by a caret on the next line, directly under it, like this:
(a bit hard to show here...)
(()
^
In my "balanced" function, I am taking the current index of the loop, and assigning it to either "unmatchedRightPosition" or "unmatchedLeftPosition," whichever one is needed, at the time. I think that a lot of my program works already, but I'm having problems with placing the carets under the errors. My professor suggested that I may choose to use a stack class that holds structs, where each struct contains both a char and the char's position, but I am a bit puzzled by that.
Thanks for looking
#include <iostream>
#include <string>
#include <stdlib.h>
#include <sstream>
using namespace std;
struct Stack{
static const unsigned MAX_SIZE = 5;
char data[ MAX_SIZE ];
unsigned size;
};
struct Stack2{
unsigned unmatchedLeftPos, unmatchedRightPos;
};
void initialize( Stack & stack );
void show( const Stack & stack );
unsigned getSize( const Stack & stack );
void push( Stack & stack, char c );
char pop( Stack & stack );
char top( const Stack & stack );
bool die( const string & msg );
bool balanced (unsigned & unmatchedLeftPos, unsigned & unmatchedRightPos, const string & expr);
int main(){
Stack2 s2;
cout << "\nPlease enter your expression - enter a blank line to quit. \n";
for(;;){
string line;
getline(cin, line);
if( line.size() == 0 ) break;
if (balanced(s2.unmatchedLeftPos, s2.unmatchedRightPos, line) == 1){
cout << "OK\n";
}
else if (balanced(s2.unmatchedLeftPos, s2.unmatchedRightPos, line) == 0){
cout << string(s2.unmatchedLeftPos, ' ') << '^';
cout << string(s2.unmatchedRightPos, ' ') << '^';
}
}
return 0;
}
void initialize( Stack & stack ){
stack.size = 0;
}
void show( const Stack & stack ){
cout <<"[" << stack.size <<"]:";
for( unsigned i = 0; i < stack.size; i++ )
cout <<stack.data[i];
cout <<endl;
} // show
unsigned getSize( const Stack & stack ) {return stack.size;}
void push( Stack & stack, char c ){
if( stack.size == Stack::MAX_SIZE ) die( "push: overflow" );
stack.data[stack.size++] = c;
} // push
char pop( Stack & stack ){
if( stack.size == 0 ) die( "pop: underflow" );
return stack.data[--stack.size];
} // pop
char top( const Stack & stack ){
if( stack.size == 0 ) die( "top: underflow" );
return stack.data[stack.size-1];
} // pop
bool die( const string & msg ){
cerr <<endl <<"Fatal error: " << msg <<endl;
exit( EXIT_FAILURE );
}
bool balanced (unsigned & unmatchedLeftPos, unsigned & unmatchedRightPos, const string & expr){
Stack s;
initialize(s);
unsigned i;
for (i = 0; i < expr.size(); i++){
char c = expr[i];
if( expr.size() == Stack::MAX_SIZE) {
die( "push: overflow" );
}
if (c == '(')
{
push(s, c);
}
else if (c == '['){
push(s, c);
}
else if (c == '{'){
push(s, c);
}
if (s.size == 0 && (c == ')' || c == ']' || c == '}'))
{
unmatchedRightPos = i;
return false;
}
else if (c == ')' && top(s) == '('){
pop(s);
}
else if (c == ']' && top(s) == '['){
pop(s);
}
else if (c == '}' && top(s) == '{'){
pop(s);
}
}
if (s.size == 0){
return true;
}
else if (top(s) == '(' || top(s) == '[' || top(s) == '{'){
unmatchedLeftPos = i;
return false;
}
}
You are currently using stack, with an array of characters:
char data[ MAX_SIZE ];
Instead, you would go for a struct, that holds both character and position in the input string
struct info {
char data;
int pos;
};
info data[ MAX_SIZE ];
So at the end, you just check your stack, and in addition to invalid characters, you also have the position in the input string.
Hope that helps.
You can move your main to the bottom to avoid forward function declarations. You also don't need to use another stack for the errors (actually I think it's easier if you don't). You just need to hold both the bracket and its position on a single stack, i.e.
struct Item
{
char bracket;
size_t position;
}
std::stack<Item> st;
As well as either an array or, better a string initialized to the same length as the input string with all spaces which you change to '^' upon encountering an error, i.e.
std::string errorString(input.size(), ' ');
if ( /* brackets don't match */ )
{
errorString[st.top().position] = '^';
}
In case you cannot use STL stack, you need to modify your own to hold Item objects instead of char (i.e. Item data[ MAX_SIZE ];). Your code looks very much like C thought and it would be better if you made use of std::string and std::stack instead.

Parsing Parenthesis using stack template class in C++

I have a homework and its just bugging for the last 2 days, I've been doing exactly what the pseudo code and still haven't got it right yet.
For example, if I put in "mike]" or "mike]123", my program will crash, due to the stack is empty...From what I observe, the program will crash when:
- The stack is empty
- And there is a close parenthesis
PS: with the help of us2012, I can fix the crash problem. However, the result is not right.
Instead of printing out "invalid", it outputs "valid"
:(
Here is the pseudo code from my professor:
def parse_parenthesis(str):
stack = create a new empty stack of OpenParen objects
for i from 0 to str.size() - 1:
if str[i] is an open parenthesis
stack.push(new OpenParen(str[i]))
else if str[i] is not a close parenthesis:
# str[i] is not a parenthesis of any kind, so ignore it
continue
# otherwise str[i] must be a close parenthesis, try to
# match it with the most recent open paren, on the top
# of the stack
else if stack is empty
return false;
else if stack.peek() is of the same type as str[i]:
# close properly
stack.pop()
else
return false;
if stack is not empty
return false;
else
return true
and here is what I have so far:
.cpp file
bool ParenMatching(const string& s, unique_ptr<string>& output)
{
unique_ptr<OpenParen> stack(new OpenParen);
bool validOpen, validClose, valid;
bool match; //haveCloseParen;
/*string unMatch = "Unmatch";
string unExpected = "Unexpected close paren";
string noError = "No Error";*/
for (size_t i = 0; i < s.length(); i++)
{
// check if its open parenthesis
validOpen = stack->IsOpenParen(s[i]);
// check if its close parenthesis
validClose = stack->IsCloseParen(s[i]);
// if there is open paren, push into the stack
if(validOpen)
stack->PushObj(s[i]);
else if(!validClose)
{
continue;
}
else if(stack->GetObj().IsEmpty())
valid = false;
else if(match = IsMatchParen(s[i], stack))
stack->PopObj();
else
valid = false;
}
if(!stack->GetObj().IsEmpty())
valid = false;
else
valid = true;
return valid;
}
bool IsMatchParen(const char c, const unique_ptr<OpenParen>& stack)
{
bool valid;
if(c == ')' && stack->PeekObj() == '(')
valid = true;
else if (c == ']' && stack->PeekObj() == '[')
valid = true;
else if (c == '}' && stack->PeekObj() == '{')
valid = true;
else if (c == '>' && stack->PeekObj() == '<')
valid = true;
else
valid = false;
return valid;
}
OpenParen.cpp
// Check if its open paren
bool OpenParen::IsOpenParen(const char c)
{
bool isOpen;
if(c == '(' || c == '[' || c == '{' || c == '<')
isOpen = true;
else
isOpen = false;
return isOpen;
}
// check if its close paren
bool OpenParen::IsCloseParen(const char c)
{
bool isClose;
if(c == ')' || c == ']' || c == '}' || c == '>')
isClose = true;
else
isClose = false;
return isClose;
}
gcc 4.7.3: g++ -Wall -Wextra -std=c++0x parens.cpp
#include <iostream>
#include <stack>
#include <string>
#include <vector>
bool isOpen(char c) {
return c == '(' || c == '[' || c == '{' || c == '<'; }
bool isClose(char c) {
return c == ')' || c == ']' || c == '}' || c == '>'; }
bool isMatch(char c1, char c2) {
return (c1 == '(' && c2 == ')')
|| (c1 == '[' && c2 == ']')
|| (c1 == '{' && c2 == '}')
|| (c1 == '<' && c2 == '>'); }
bool parse(const std::string& s) {
std::stack<std::string::value_type> stk;
for (std::string::size_type i = 0; i < s.size(); ++i) {
if (isOpen(s[i])) { stk.push(s[i]); }
else if (isClose(s[i])) {
if (!stk.empty() && isMatch(stk.top(), s[i])) { stk.pop(); }
else { return false; } } }
return stk.empty(); }
int main() {
std::vector<std::string> ptests = {
"", "()", "()()", "(())", "a(a)a" };
std::vector<std::string> ftests = {
"(", ")", ")(", ")()(", "))((" };
for (const auto& t : ptests) {
if (!parse(t)) { std::cout << "fail: " << t << std::endl; } }
for (const auto& t : ftests) {
if (parse(t)) { std::cout << "fail: " << t << std::endl; } }
}
One important thing you should keep in mind about C++ : Multiple else ifs do not live at the same level. That's because else if is not a single entity, it's an else that belongs to the preceding statement and an ifthat begins a new statement, so
if (cond1)
a();
else if (cond 2)
b();
else if (cond 3)
c();
else
d();
is actually
if (cond1)
a();
else {
if (cond 2)
b();
else {
if (cond 3)
c();
else
d();
}
}
Therefore, your check whether the stack is empty needs to be before the check whether the current close parens matches the top of the stack. Otherwise, your program will try to examine the top of the stack when it's empty, and that results in a crash.
Also, setting valid = false is not the right thing to do when you find a condition that indicates a non-match. The loop will still continue and can reset valid to true in a later iteration. You need to immediately return false, as you can already see in your pseudocode.

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:
Search each char in the whole input string, the index from 0 to str.size() - 1.
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.
When encouterning the closing tag ) and ], we pop the corresponding stack.
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;
}
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.