What am I doing wrong? Implementing infix to postfix using a stack - c++11

I'm trying to write an infix to postfix expression converter using a stack. Basically, it's an implementation of the Shunting Yard algorithm as found on wikipedia.
/*
This function returns the precedence of a presented token. To keep comparisons
simple, the higher the return value, the higher the precedence. Not to be
confused with priority.
From https://web.archive.org/web/20120822075917/http://en.literateprograms.org:80/Special:DownloadCode/Shunting_yard_algorithm_(Python)
*/
int precedence(string token)
{
switch(token.at(0))
{
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
case '(':
return 0;
case ')':
return 0;
}
return 0;
}
/*
Returns true if the supplied token is an operator.
*/
bool is_operator(const string& token)
{
return token == "*"
|| token == "/"
|| token == "+"
|| token == "-";
}
/*
Returns true if the supplied token is an operand (not an operator).
*/
bool is_operand(const string& token)
{
return !is_operator(token) && (token != "(") && (token != ")");
}
void display(const vector<string>& v)
{
for(unsigned int i=0; i<v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
}
string associativity(const string& token)
{
if(token == "*" || token == "+")
{
return "left";
}
else if(token == "/" || token =="-")
{
return "left";
}
return "?";
}
/*
From wikipedia:
while there are tokens to be read:
read a token.
if the token is a number, then push it to the output queue.
if the token is an operator, then:
while (there is an operator at the top of the operator stack with
greater precedence) or (the operator at the top of the operator stack has
equal precedence and
the operator is left associative) and
(the operator at the top of the stack is not a left bracket):
pop operators from the operator stack, onto the output queue.
push the read operator onto the operator stack.
if the token is a left bracket (i.e. "("), then:
push it onto the operator stack.
if the token is a right bracket (i.e. ")"), then:
while the operator at the top of the operator stack is not a left bracket:
pop operators from the operator stack onto the output queue.
pop the left bracket from the stack.
if there are no more tokens to read:
while there are still operator tokens on the stack:
pop the operator onto the output queue.
exit.
*/
vector<string> infix_to_postfix(const vector<string>& infix, bool& error)
{
vector<string> postfix;
stack<string> operators;
for(string token : infix)
{
if(is_operand(token))
{
postfix.push_back(token);
}
if(is_operator(token))
{
while
(
(!operators.empty() && precedence(operators.peek()) > precedence(token))
|| (!operators.empty() && (precedence(operators.peek()) == precedence(token)) && (associativity(token) == "left") && (token != "("))
)
{
string tk = operators.pop();
if(tk != "(" && tk != ")")
{
postfix.push_back(tk);
}
}
operators.push(token);
}
if(token == "(")
{
operators.push(token);
}
if(token == ")")
{
while(!operators.empty() && operators.peek() != "(")
{
postfix.push_back(operators.pop());
}
if(!operators.empty())
{
operators.pop();
}
}
}
while(!operators.empty())
{
postfix.push_back(operators.pop());
}
return postfix;
}
I expect this code to return a valid postfix expression in the form of a vector containing the relevant tokens.
The following evaluate function returns weird numbers for a longer expression I'm testing with.
double evaluate(const vector<string>& postfix, bool& error)
{
error = false;
double result;
stack<double> numbers;
for(unsigned int i=0; i<postfix.size(); i++)
{
string token = postfix[i];
if(is_operand(token))
{
numbers.push(stod(token));
}
else
{
double operand1 = numbers.pop();
double operand2 = numbers.pop();
switch(token.at(0))
{
case '+':
numbers.push(operand1 + operand2);
break;
case '-':
numbers.push(operand1 - operand2);
break;
case '*':
numbers.push(operand1 * operand2);
break;
case '/':
numbers.push(operand1 / operand2);
break;
}
}
}
For example, consider this input and output:
Infix: ( 3 + 3 * 5 ) * 6 - 2 / 1 + 3 + 3 * 5 * ( 4 + 1 )
Postfix: 3 3 5 * + 6 * 2 1 / 3 3 5 4 1 + * * + + -
Result: -29.5
Google says its 184.
Update:
I included an associativity function from wikipedia. I also updated the expression result.
Update 2:
Incorporated the comments that made this code work.

Obviously your postfix conversion output is already wrong. ( 3 + 3 * 5 ) should have become 3 3 5 * +, not 3 3 + 5 *
while
(
(!operators.empty() && precedence(token) <= precedence(operators.peek()))
|| (!operators.empty() && operators.peek() != "(")
)
This part is wrong. The text says (pred(operators.peek()) > pred(token)) || (pred(operators.peek()) == pred(token) && token != "(").
As a result, you did always wrongly pop the operator whenever it was not a closing parantheses, ignoring operator precedence.
double operand1 = numbers.pop();
double operand2 = numbers.pop();
That part is also wrong. Operand 2 is the one higher on the stack. Switch them around.

Related

Runtime Error: Segmentation Fault (SIGSEGV)

I am trying to write a program to convert infix expression to postfix expression. But I am getting the error
Runtime Error: Segmentation Fault (SIGSEGV)
I know that
SIGSEGV is an error caused by an invalid memory reference
Algorithm used
Scan the infix expression from left to right.
If the scanned character is an operand, output it.
Else,
1 If the precedence of the scanned operator is greater than the precedence of the operator in the stack(or the stack is empty or the stack contains a ‘(‘ ), push it.
2 Else, Pop all the operators from the stack which are greater than or equal to in precedence than that of the scanned operator. After doing that Push the scanned operator to the stack. (If you encounter parenthesis while popping then stop there and push the scanned operator in the stack.)
If the scanned character is an ‘(‘, push it to the stack.
If the scanned character is an ‘)’, pop the stack and and output it until a ‘(‘ is encountered, and discard both the parenthesis.
Repeat steps 2-6 until infix expression is scanned.
Print the output
Pop and output from the stack until it is not empty.
Code
class Solution
{
int prec(char a)
{
if (a == '^')
return 3;
else if (a == '*' || a == '/')
return 2;
else if (a == '+' || a == '-')
return 1;
else
return -1;
}
public:
string infixToPostfix(string str)
{
stack<char> stk;
string ans;
for (auto e : str)
{
if ((e >= 'a' && e <= 'z') || (e >= 'A' && e <= 'Z'))
ans += e;
else if (e == '(')
stk.push(e);
else if (stk.empty())
stk.push(e);
else if (prec(stk.top()) < prec(e))
{
if (e != ')')
stk.push(e);
else
{
while (!stk.empty() && stk.top() != '(')
{
ans = ans + stk.top();
stk.pop();
}
if (stk.empty())
continue;
else
stk.pop();
}
}
else if (prec(stk.top()) >= prec(e))
{
while (prec(stk.top()) >= prec(e) && !stk.empty())
{
if (prec(stk.top()) > prec(e))
{
ans = ans + stk.top();
stk.pop();
}
else
{
//same precedence so checking for associativity
if (stk.top() == '^') //associativity from R->L
stk.push(e);
else //associativity from L->R
{
ans = ans + stk.top();
stk.pop();
}
}
}
stk.push(e);
}
}
if (stk.empty())
return ans;
else
{
while (!stk.empty())
{
ans = ans + stk.top();
stk.pop();
}
return ans;
}
}
};
I have tried a lot to find out the fault in the code, but I was unable to figure it out. Please help me.

Spoj question ONP Transform the expression giving signal abort

I am trying to solve ONP - Transform the Expression in spoj. The question is to transform infix expression into postfix expression. I have used std::stack as my data structure and shunting-yard algorithm for solving it. The code runs fine on my computer using g++. But on spoj, it gives SIGABRT error. Even on ideone, it gives run time error free() invalid pointer.
I have tried several test cases. At first, I thought that my program was taking too much memory, but upon testing with time -v (ubuntu), I found that the maximum space taken was in KB.
// ------------------- infix to postfix conversion ---------------
#include <iostream>
#include <string>
#include <stack>
#include <algorithm>
#include <utility>
using std::stack;
using std::pair;
using std::cout;
using std::cin;
using std::endl;
using std::string;
stack< pair<char, short> > op_st; // operator stack
short op_precedence(char op) {
// return operator precedence
// input: operator; output: its precedence value
switch (op) {
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '^': return 4;
case '(': return 6;
}
}
inline bool is_operator(char sym) {
// is sym an operator?
return (sym == '+' || sym == '-' || sym == '*' || sym == '/' || sym == '^' || sym == '(');
}
inline bool is_operand(char sym) {
// is sym an operand?
return (sym >= 'a' && sym <= 'z');
}
void in_to_post(string & expr) {
// infix to postfix converter
// input: infix expression
for (int i = 0; i < expr.length(); ++i) {
if (is_operator(expr[i])) { // operator
// pop op_stack until the
// top of the stack has less precedence
// than curr operator or stack is empty
while(1) {
if (op_st.empty()) { // stack is empty; straight away push
op_st.push(std::make_pair(expr[i], op_precedence(expr[i])));
break;
}
pair <char, short> & top_op = op_st.top();
if (op_precedence(top_op.second) >= op_precedence(expr[i])) {
cout << top_op.first;
op_st.pop();
}
else {
op_st.push(std::make_pair(expr[i], op_precedence(expr[i])));
break;
}
}
}
else if (is_operand(expr[i])) { // operand; push it to output queue immediately
cout << expr[i];
}
else if (expr[i] == ')') { // right paranthesis
while (1) {
if (op_st.empty()) { // invalid expression; ')' reached before matching '('
//cout << "No matching '(' found\n";
abort();
}
pair <char, short> & top_op = op_st.top();
if (top_op.first == '(') { // matching '(' found; stop
op_st.pop();
break;
}
else {
cout << top_op.first;
op_st.pop();
}
}
}
}
// pop out the whole op_st (if any)
while (!(op_st.empty())) {
pair <char, short> & top_op = op_st.top();
cout << top_op.first;
op_st.pop();
}
}
int main() {
int t;
cin >> t;
for (int i = 0; i < t; ++i) {
string expr;
cin >> expr;
//cout << expr.length() << endl;
in_to_post(expr);
cout << "\n";
}
return 0;
}
Input to program given on my system:
((a+b)-c*(d+e))^((a+b)-c*(d+e))+((a+b)-c*(d+e))-((a+b)-c*(d+e))+((a+b)-c*(d+e))^((a+b)-c*(d+e))+((a+b)-c*(d+e))-((a+b)-c*(d+e))-((a+b)-c*(d+e))^((a+b)-c*(d+e))+((a+b)-c*(d+e))-((a+b)-c*(d+e))*((a+b)-c*(d+e))^((a+b)-c*(d+e))+((a+b)-c*(d+e))-((a+b)-c*(d+e))^((a+b)-c*(d+e))^((a+b)-c*(d+e))+((a+b)-c*(d+e))-((a+b)-c*(d+e))+((a+b)-c*(d+e))^((a+b)-c*(d+e))+((a+b)-c*(d+e))-((a+b)-c*(d+e))^((a+b)-c*(d+e))^((a+b)-c*(d+e))+((a+b)-c*(d+e))-((a+b)-c*(d+e))
Successfully gives the output:
ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*-ab+cde+*--+^^-+^+-+^^-+^*-+^--+^+-+^.
But, the same code gives free() invalid pointer error in ideone. Why is that?
op_precedence(top_op.second) calls op_precedence with the number returned by earlier op_precedence call - not with the operator character.
When op_precedence is passed an argument that doesn't match one of the recognized operators, the program exhibits undefined behavior, by way of reaching the end of a non-void function without encountering a return statement.
So, after Igor Tandetnik kindly pointed the mistake to me, in line 58, I changed op_precedence(top_op.second) to top_op.second. I also added default case to op_precedence function to correct the warning. After compiling and running, this code did actually abort() on line 75 for simple input ((a+b)). It turns out, that my implementation of the algorithm was wrong. My code didn't take into consideration associativity of operator '('. According to the question, we don't need to take into consideration associativity for other operators but for '(' we need its precedence to be higher than all other operators when outside of the stack, and lower than all other operators when inside of the stack. This is to ensure that when any operator other than '(' is the input and the top of the stack is '(', we could push the input operator into the stack. The corrected code is below:
// ------------------- infix to postfix conversion ---------------
#include <iostream>
#include <string>
#include <stack>
#include <algorithm>
#include <utility>
using std::stack;
using std::pair;
using std::cout;
using std::cin;
using std::endl;
using std::string;
short op_out_precedence(char op) {
// return operator precedence (when outside of stack)
// in and out precedence is to take care of associativity
// Here we don't require the associativity of any other operator except '('
// input: operator; output: its precedence value
switch (op) {
case '+': return 1;
case '-': return 2;
case '*': return 3;
case '/': return 4;
case '^': return 5;
case '(': return 6;
default : abort(); // not supposed to happen
// operator can't be other than the mentioned cases
}
}
short op_in_precedence(char op) {
// return operator precedence (when inside of stack)
// in and out precedence is to take care of associativity
// Here we don't require the associativity of any other operator except '('
// input: operator; output: its precedence value
switch (op) {
case '+': return 1;
case '-': return 2;
case '*': return 3;
case '/': return 4;
case '^': return 5;
case '(': return 0;
default : abort(); // not supposed to happen
// operator can't be other than the mentioned cases
}
}
inline bool is_operator(char sym) {
// is sym an operator?
return (sym == '+' || sym == '-' || sym == '*' || sym == '/' || sym == '^' || sym == '(');
}
inline bool is_operand(char sym) {
// is sym an operand?
return (sym >= 'a' && sym <= 'z');
}
void in_to_post(string & expr) {
// infix to postfix converter
// input: infix expression
stack< pair<char, short> > op_st; // operator stack
int len = expr.length();
for (int i = 0; i < len; ++i) {
if (is_operator(expr[i])) { // operator
// pop op_stack until the
// top of the stack has less or equal precedence
// than curr operator or stack is empty
while(1) {
if (op_st.empty()) { // stack is empty; straight away push
op_st.push(std::make_pair(expr[i], op_in_precedence(expr[i])));
break;
}
pair <char, short> & top_op = op_st.top();
if (top_op.second > op_out_precedence(expr[i])) {
cout << top_op.first;
op_st.pop();
}
else {
op_st.push(std::make_pair(expr[i], op_in_precedence(expr[i])));
break;
}
}
}
else if (is_operand(expr[i])) { // operand; push it to output queue immediately
cout << expr[i];
}
else if (expr[i] == ')') { // right paranthesis
while (1) {
if (op_st.empty()) { // invalid expression; ')' reached before matching '('
cout << "No matching '(' found\n";
abort();
}
pair <char, short> & top_op = op_st.top();
if (top_op.first == '(') { // matching '(' found; stop
op_st.pop();
break;
}
else {
cout << top_op.first;
op_st.pop();
}
}
}
}
// pop out the whole op_st (if any)
while (!(op_st.empty())) {
pair <char, short> & top_op = op_st.top();
cout << top_op.first;
op_st.pop();
}
}
int main() {
int t;
cin >> t;
for (int i = 0; i < t; ++i) {
string expr;
cin >> expr;
//cout << expr.length() << endl;
in_to_post(expr);
cout << "\n";
}
return 0;
}

Algorithm to sum all the numbers in the string [duplicate]

I want to know if there is a way to solve infix expressions in a single pass using 2 stacks?
The stacks can be one for operator and the other for operands...
The standard way to solve by shunt-yard algorithm is to convert the infix expression to postfix(reverse polish) and then solve. I don't want to convert the expression first to postfix.
If the expression is like 2*3-(6+5)+8, how to solve?
Quite late, but here is the answer.
Take two stacks:
operator stack { for operators and parentheses }.
operand stack.
Algorithm
If character exists to be read:
If character is operand push on the operand stack, if character is (, push on the operator stack.
Else if character is operator
While the top of the operator stack is not of smaller precedence than this character.
Pop operator from operator stack.
Pop two operands (op1 and op2) from operand stack.
Store op1 op op2 on the operand stack back to 2.1.
Else if character is ), do the same as 2.2 - 2.4 till you encounter (.
Else (no more character left to read):
Pop operators untill operator stack is not empty.
Pop top 2 operands and push op1 op op2 on the operand stack.
return the top value from operand stack.
The method given in the link is really good.
Let me quote the source:
We will use two stacks:
Operand stack: to keep values (numbers) and
Operator stack: to keep operators (+, -, *, . and ^).
In the following, “process” means, (i) pop operand stack once (value1) (ii) pop operator stack once (operator) (iii) pop operand stack again (value2) (iv) compute value1 operator value2 (v) push the value obtained in operand stack.
Algorithm:
Until the end of the expression is reached, get one character and perform only one of the steps (a) through (f):
(a) If the character is an operand, push it onto the operand stack.
(b) If the character is an operator, and the operator stack is empty then push it onto the operator stack.
(c) If the character is an operator and the operator stack is not empty, and the character's precedence is greater than the precedence of the stack top of operator stack, then push the character onto the operator stack.
(d) If the character is "(", then push it onto operator stack.
(e) If the character is ")", then "process" as explained above until the corresponding "(" is encountered in operator stack. At this stage POP the operator stack and ignore "(."
(f) If cases (a), (b), (c), (d) and (e) do not apply, then process as explained above.
When there are no more input characters, keep processing until the operator stack becomes empty. The values left in the operand stack is the final result of the expression.
I hope this helps!
create an empty operator stack.
create an empty operand stack.
for each token in the input String
a. get the next token in the infix string.
b. if the next is an operand, place it on the operand stack.
c. if the next token is an operator
Evaluate the operator.
while operator stack is not empty, pop operator and operands (left and right),evaluate left operator right and push result onto operand stack.
pop result from operator stack.
Below is my attempt at infix expression evaluation in java. Please let me know if you find any bugs :)
import java.util.*;
public class ArithmeticExpressionEvaluation {
public static void main(String[] args) {
Scanner readExpression = new Scanner(System.in);
System.out.print("Enter the expression: ");
String expression = readExpression.nextLine();
System.out.println(expression);
System.out.println("Result: " + calculateExpression(expression));
}
public static long calculateExpression(String expression) {
Stack<Long> operandStack = new Stack<>();
Stack<Character> operatorStack = new Stack<>();
if (!isValidExpression(expression)) {
System.out.println("Not a valid expression to evaluate");
return 0;
}
int i = 0;
String currentInteger = null;
while (i < expression.length()) {
// System.out.println(expression.charAt(i));
if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
currentInteger = expression.charAt(i) + "";
i++;
while (i != expression.length() && (expression.charAt(i) >= '0' && expression.charAt(i) <= '9')) {
currentInteger = currentInteger + expression.charAt(i);
i++;
}
operandStack.push(Long.parseLong(currentInteger));
} else {
if (expression.charAt(i) == ')') {
while (operatorStack.peek() != '(') {
performArithmeticOperation(operandStack, operatorStack);
}
operatorStack.pop();
} else {
Character currentOperator = expression.charAt(i);
Character lastOperator = (operatorStack.isEmpty() ? null : operatorStack.peek());
if (lastOperator != null && checkPrecedence(currentOperator, lastOperator)) {
performArithmeticOperation(operandStack, operatorStack);
}
operatorStack.push(expression.charAt(i));
}
i++;
}
}
while (!operatorStack.isEmpty()) {
performArithmeticOperation(operandStack, operatorStack);
}
// System.out.println(Arrays.toString(operandStack.toArray()));
// System.out.println(Arrays.toString(operatorStack.toArray()));
return operandStack.pop();
}
public static void performArithmeticOperation(Stack<Long> operandStack, Stack<Character> operatorStack) {
try {
long value1 = operandStack.pop();
long value2 = operandStack.pop();
char operator = operatorStack.pop();
long intermediateResult = arithmeticOperation(value1, value2, operator);
operandStack.push(intermediateResult);
} catch (EmptyStackException e) {
System.out.println("Not a valid expression to evaluate");
throw e;
}
}
public static boolean checkPrecedence(Character operator1, Character operator2) {
List<Character> precedenceList = new ArrayList<>();
precedenceList.add('(');
precedenceList.add(')');
precedenceList.add('/');
precedenceList.add('*');
precedenceList.add('%');
precedenceList.add('+');
precedenceList.add('-');
if(operator2 == '(' ){
return false;
}
if (precedenceList.indexOf(operator1) > precedenceList.indexOf(operator2)) {
return true;
} else {
return false;
}
}
public static long arithmeticOperation(long value2, long value1, Character operator) {
long result;
switch (operator) {
case '+':
result = value1 + value2;
break;
case '-':
result = value1 - value2;
break;
case '*':
result = value1 * value2;
break;
case '/':
result = value1 / value2;
break;
case '%':
result = value1 % value2;
break;
default:
result = value1 + value2;
}
return result;
}
public static boolean isValidExpression(String expression) {
if ((!Character.isDigit(expression.charAt(0)) && !(expression.charAt(0) == '('))
|| (!Character.isDigit(expression.charAt(expression.length() - 1)) && !(expression.charAt(expression.length() - 1) == ')'))) {
return false;
}
HashSet<Character> validCharactersSet = new HashSet<>();
validCharactersSet.add('*');
validCharactersSet.add('+');
validCharactersSet.add('-');
validCharactersSet.add('/');
validCharactersSet.add('%');
validCharactersSet.add('(');
validCharactersSet.add(')');
Stack<Character> validParenthesisCheck = new Stack<>();
for (int i = 0; i < expression.length(); i++) {
if (!Character.isDigit(expression.charAt(i)) && !validCharactersSet.contains(expression.charAt(i))) {
return false;
}
if (expression.charAt(i) == '(') {
validParenthesisCheck.push(expression.charAt(i));
}
if (expression.charAt(i) == ')') {
if (validParenthesisCheck.isEmpty()) {
return false;
}
validParenthesisCheck.pop();
}
}
if (validParenthesisCheck.isEmpty()) {
return true;
} else {
return false;
}
}
}

Minimum number of swap of operator to complement expression tree evaluation

I have an expression tree where each leaf node contains 0 or 1 as value, and all the internal nodes contain "&" or "||" as operator. Now I need to evaluate the tree; the result will be either 0 or 1.
The question is minimum number of swap of internal node required to complement the result of original expression tree. Any internal node can be flipped; e.g. if it is a "&", we can make it "||", and vice versa.
To solve this I tried the following technique but I didn't succeed in it:
My approach was that I would check the root whether it is a "&" or "||" operator and whether the result of evaluation tree 0 or 1, depending on that I went forward with the evaluation.
i'm not sure if i understood you question. if it's how do evaluate the whole tree my answer is:
try a recursion.
something like this:
evalute() {
if_the_root_is_an_operator() {
l= evaluate(left operant)
r= evaluate(right operant)
return calculate(l,r) // depending on what operator it was
}
// not an operator, so it'S a leaf
return value;
}
optimizations could be, to check if l or r are values, and skip the evaluation if their values already define the final result.
"0 AND (subtree)" is surely 0,
"1 OR (subtree)" is 1, so subtree doesn't need to be evaluated
evalute() {
if (the_root_is_an_operator()) {
if ( operator_is_and() &&
(left_is_leaf() && value(left)==0) ||
(right_is_leaf() && value(right)==0))
return 0;
if ( operator_is_or() &&
(left_is_leaf() && value(left)==1) ||
(right_is_leaf() && value(right)==1))
return 1;
l= evaluate(left operant)
r= evaluate(right operant)
return calculate(l,r) // depending on what operator it was
}
// not an operator, so it'S a leaf
return value;
}
This is an example of problem asked in question.
OR
/ \
OR AND
/ \ / \
1 0 1 1
Output is 1. Need to found min numbers of operands to be changed to change the output to 0.
Min number of operators required to be changed are 2.
class A {
int min=Integer.max;
int minNumber(Tree node) {
if(node==null) return Math.max;
if(node.left==null && node.right==null) return Math.max;
String c = node.data;
int l = evaluate(node.left);
int r = evaluate(node.right);
if(l || r==0) { min_number = 1; }
else {
if(l && r == 1 )
{
min_number = 0;
}
else if(l && r == 0)
{
min_number = 0;
}
int left = min_number + minNumber(node.left)
int right = min_number + minNumber(node.right);
min_number = Math.min(left,right);
}
if(min_number<min) min = min_number; return min;
}

How to find validity of a string of parentheses, curly brackets and square brackets?

I recently came in contact with this interesting problem. You are given a string containing just the characters '(', ')', '{', '}', '[' and ']', for example, "[{()}]", you need to write a function which will check validity of such an input string, function may be like this:
bool isValid(char* s);
these brackets have to close in the correct order, for example "()" and "()[]{}" are all valid but "(]", "([)]" and "{{{{" are not!
I came out with following O(n) time and O(n) space complexity solution, which works fine:
Maintain a stack of characters.
Whenever you find opening braces '(', '{' OR '[' push it on the stack.
Whenever you find closing braces ')', '}' OR ']' , check if top of stack is corresponding opening bracket, if yes, then pop the stack, else break the loop and return false.
Repeat steps 2 - 3 until end of the string.
This works, but can we optimize it for space, may be constant extra space, I understand that time complexity cannot be less than O(n) as we have to look at every character.
So my question is can we solve this problem in O(1) space?
With reference to the excellent answer from Matthieu M., here is an implementation in C# that seems to work beautifully.
/// <summary>
/// Checks to see if brackets are well formed.
/// Passes "Valid parentheses" challenge on www.codeeval.com,
/// which is a programming challenge site much like www.projecteuler.net.
/// </summary>
/// <param name="input">Input string, consisting of nothing but various types of brackets.</param>
/// <returns>True if brackets are well formed, false if not.</returns>
static bool IsWellFormedBrackets(string input)
{
string previous = "";
while (input.Length != previous.Length)
{
previous = input;
input = input
.Replace("()", String.Empty)
.Replace("[]", String.Empty)
.Replace("{}", String.Empty);
}
return (input.Length == 0);
}
Essentially, all it does is remove pairs of brackets until there are none left to remove; if there is anything left the brackets are not well formed.
Examples of well formed brackets:
()[]
{()[]}
Example of malformed brackets:
([)]
{()[}]
Actually, there's a deterministic log-space algorithm due to Ritchie and Springsteel: http://dx.doi.org/10.1016/S0019-9958(72)90205-7 (paywalled, sorry not online). Since we need log bits to index the string, this is space-optimal.
If you're willing to accept one-sided error, then there's an algorithm that uses n polylog(n) time and polylog(n) space: http://www.eccc.uni-trier.de/report/2009/119/
If the input is read-only, I don't think we can do O(1) space. It is a well known fact that any O(1) space decidable language is regular (i.e writeable as a regular expression). The set of strings you have is not a regular language.
Of course, this is about a Turing Machine. I would expect it to be true for fixed word RAM machines too.
Edit: Although simple, this algorithm is actually O(n^2) in terms of character comparisons. To demonstrate it, one can simply generate a string as '(' * n + ')' * n.
I have a simple, though perhaps erroneous idea, that I will submit to your criticisms.
It's a destructive algorithm, which means that if you ever need the string it would not help (since you would need to copy it down).
Otherwise, the algorithm work with a simple index within the current string.
The idea is to remove pairs one after the others:
([{}()])
([()])
([])
()
empty -> OK
It is based on the simple fact that if we have matching pairs, then at least one is of the form () without any pair character in between.
Algorithm:
i := 0
Find a matching pair from i. If none is found, then the string is not valid. If one is found, let i be the index of the first character.
Remove [i:i+1] from the string
If i is at the end of the string, and the string is not empty, it's a failure.
If [i-1:i] is a matching pair, i := i-1 and back to 3.
Else, back to 1.
The algorithm is O(n) in complexity because:
each iteration of the loop removes 2 characters from the string
the step 2., which is linear, is naturally bound (i cannot grow indefinitely)
And it's O(1) in space because only the index is required.
Of course, if you can't afford to destroy the string, then you'll have to copy it, and that's O(n) in space so no real benefit there!
Unless, of course, I am deeply mistaken somewhere... and perhaps someone could use the original idea (there is a pair somewhere) to better effect.
I doubt you'll find a better solution, since even if you use internal functions to regexp or count occurrences, they still have a O(...) cost. I'd say your solution is the best :)
To optimize for space you could do some run-length encoding on your stack, but I doubt it would gain you very much, except in cases like {{{{{{{{{{}}}}}}}}}}.
http://www.sureinterview.com/shwqst/112007
It is natural to solve this problem with a stack.
If only '(' and ')' are used, the stack is not necessary. We just need to maintain a counter for the unmatched left '('. The expression is valid if the counter is always non-negative during the match and is zero at the end.
In general case, although the stack is still necessary, the depth of the stack can be reduced by using a counter for unmatched braces.
This is an working java code where I filter out the brackets from the string expression and then check the well formedness by replacing wellformed braces by nulls
Sample input = (a+{b+c}-[d-e])+[f]-[g] FilterBrackets will output = ({}[])[][] Then I check for wellformedness.
Comments welcome.
public class ParanString {
public static void main(String[] args) {
String s = FilterBrackets("(a+{b+c}-[d-e])[][]");
while ((s.length()!=0) && (s.contains("[]")||s.contains("()")||s.contains("{}")))
{
//System.out.println(s.length());
//System.out.println(s);
s = s.replace("[]", "");
s = s.replace("()", "");
s = s.replace("{}", "");
}
if(s.length()==0)
{
System.out.println("Well Formed");
}
else
{
System.out.println("Not Well Formed");
}
}
public static String FilterBrackets(String str)
{
int len=str.length();
char arr[] = str.toCharArray();
String filter = "";
for (int i = 0; i < len; i++)
{
if ((arr[i]=='(') || (arr[i]==')') || (arr[i]=='[') || (arr[i]==']') || (arr[i]=='{') || (arr[i]=='}'))
{
filter=filter+arr[i];
}
}
return filter;
}
}
The following modification of Sbusidan's answer is O(n2) time complex but O(log n) space simple.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
char opposite(char bracket) {
switch(bracket) {
case '[':
return ']';
case '(':
return ')';
}
}
bool is_balanced(int length, char *s) {
int depth, target_depth, index;
char target_bracket;
if(length % 2 != 0) {
return false;
}
for(target_depth = length/2; target_depth > 0; target_depth--) {
depth=0;
for(index = 0; index < length; index++) {
switch(s[index]) {
case '(':
case '[':
depth++;
if(depth == target_depth) target_bracket = opposite(s[index]);
break;
case ')':
case ']':
if(depth == 0) return false;
if(depth == target_depth && s[index] != target_bracket) return false;
depth--;
break;
}
}
}
}
void main(char* argv[]) {
char input[] = "([)[(])]";
char *balanced = is_balanced(strlen(input), input) ? "balanced" : "imbalanced";
printf("%s is %s.\n", input, balanced);
}
If you can overwrite the input string (not reasonable in the use cases I envision, but what the heck...) you can do it in constant space, though I believe the time requirement goes up to O(n2).
Like this:
string s = input
char c = null
int i=0
do
if s[i] isAOpenChar()
c = s[i]
else if
c = isACloseChar()
if closeMatchesOpen(s[i],c)
erase s[i]
while s[--i] != c ;
erase s[i]
c == null
i = 0; // Not optimal! It would be better to back up until you find an opening character
else
return fail
end if
while (s[++i] != EOS)
if c==null
return pass
else
return fail
The essence of this is to use the early part of the input as the stack.
I know I'm a little late to this party; it's also my very first post on StackOverflow.
But when I looked through the answers, I thought I might be able to come up with a better solution.
So my solution is to use a few pointers.
It doesn't even have to use any RAM storage, as registers can be used for this.
I have not tested the code; it's written it on the fly.
You'll need to fix my typos, and debug it, but I believe you'll get the idea.
Memory usage: Only the CPU registers in most cases.
CPU usage: It depends, but approximately twice the time it takes to read the string.
Modifies memory: No.
b: string beginning, e: string end.
l: left position, r: right position.
c: char, m: match char
if r reaches the end of the string, we have a success.
l goes backwards from r towards b.
Whenever r meets a new start kind, set l = r.
when l reaches b, we're done with the block; jump to beginning of next block.
const char *chk(const char *b, int len) /* option 2: remove int len */
{
char c, m;
const char *l, *r;
e = &b[len]; /* option 2: remove. */
l = b;
r = b;
while(r < e) /* option 2: change to while(1) */
{
c = *r++;
/* option 2: if(0 == c) break; */
if('(' == c || '{' == c || '[' == c)
{
l = r;
}
else if(')' == c || ']' == c || '}' == c)
{
/* find 'previous' starting brace */
m = 0;
while(l > b && '(' != m && '[' != m && '{' != m)
{
m = *--l;
}
/* now check if we have the correct one: */
if(((m & 1) + 1 + m) != c) /* cryptic: convert starting kind to ending kind and match with c */
{
return(r - 1); /* point to error */
}
if(l <= b) /* did we reach the beginning of this block ? */
{
b = r; /* set new beginning to 'head' */
l = b; /* obsolete: make left is in range. */
}
}
}
m = 0;
while(l > b && '(' != m && '[' != m && '{' != m)
{
m = *--l;
}
return(m ? l : NULL); /* NULL-pointer for OK */
}
After thinking about this approach for a while, I realized that it will not work as it is right now.
The problem will be that if you have "[()()]", it'll fail when reaching the ']'.
But instead of deleting the proposed solution, I'll leave it here, as it's actually not impossible to make it work, it does require some modification, though.
/**
*
* #author madhusudan
*/
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new Main().validateBraces("()()()()(((((())))))()()()()()()()()");
// TODO code application logic here
}
/**
* #Use this method to validate braces
*/
public void validateBraces(String teststr)
{
StringBuffer teststr1=new StringBuffer(teststr);
int ind=-1;
for(int i=0;i<teststr1.length();)
{
if(teststr1.length()<1)
break;
char ch=teststr1.charAt(0);
if(isClose(ch))
break;
else if(isOpen(ch))
{
ind=teststr1.indexOf(")", i);
if(ind==-1)
break;
teststr1=teststr1.deleteCharAt(ind).deleteCharAt(i);
}
else if(isClose(ch))
{
teststr1=deleteOpenBraces(teststr1,0,i);
}
}
if(teststr1.length()>0)
{
System.out.println("Invalid");
}else
{
System.out.println("Valid");
}
}
public boolean isOpen(char ch)
{
if("(".equals(Character.toString(ch)))
{
return true;
}else
return false;
}
public boolean isClose(char ch)
{
if(")".equals(Character.toString(ch)))
{
return true;
}else
return false;
}
public StringBuffer deleteOpenBraces(StringBuffer str,int start,int end)
{
char ar[]=str.toString().toCharArray();
for(int i=start;i<end;i++)
{
if("(".equals(ar[i]))
str=str.deleteCharAt(i).deleteCharAt(end);
break;
}
return str;
}
}
Instead of putting braces into the stack, you could use two pointers to check the characters of the string. one start from the beginning of the string and the other start from end of the string. something like
bool isValid(char* s) {
start = find_first_brace(s);
end = find_last_brace(s);
while (start <= end) {
if (!IsPair(start,end)) return false;
// move the pointer forward until reach a brace
start = find_next_brace(start);
// move the pointer backward until reach a brace
end = find_prev_brace(end);
}
return true;
}
Note that there are some corner case not handled.
I think that you can implement an O(n) algorithm. Simply you have to initialise an counter variable for each type: curly, square and normal brackets. After than you should iterate the string and should increase the coresponding counter if the bracket is opened, otherwise to decrease it. If the counter is negative return false. AfterI think that you can implement an O(n) algorithm. Simply you have to initialise an counter variable for each type: curly, square and normal brackets. After than you should iterate the string and should increase the coresponding counter if the bracket is opened, otherwise to decrease it. If the counter is negative return false. After you count all brackets, you should check if all counters are zero. In that case, the string is valid and you should return true.
You could provide the value and check if its a valid one, it would print YES otherwise it would print NO
static void Main(string[] args)
{
string value = "(((([{[(}]}]))))";
List<string> jj = new List<string>();
if (!(value.Length % 2 == 0))
{
Console.WriteLine("NO");
}
else
{
bool isValid = true;
List<string> items = new List<string>();
for (int i = 0; i < value.Length; i++)
{
string item = value.Substring(i, 1);
if (item == "(" || item == "{" || item == "[")
{
items.Add(item);
}
else
{
string openItem = items[items.Count - 1];
if (((item == ")" && openItem == "(")) || (item == "}" && openItem == "{") || (item == "]" && openItem == "["))
{
items.RemoveAt(items.Count - 1);
}
else
{
isValid = false;
break;
}
}
}
if (isValid)
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("NO");
}
}
Console.ReadKey();
}
var verify = function(text)
{
var symbolsArray = ['[]', '()', '<>'];
var symbolReg = function(n)
{
var reg = [];
for (var i = 0; i < symbolsArray.length; i++) {
reg.push('\\' + symbolsArray[i][n]);
}
return new RegExp('(' + reg.join('|') + ')','g');
};
// openReg matches '(', '[' and '<' and return true or false
var openReg = symbolReg(0);
// closeReg matches ')', ']' and '>' and return true or false
var closeReg = symbolReg(1);
// nestTest matches openSymbol+anyChar+closeSymbol
// and returns an obj with the match str and it's start index
var nestTest = function(symbols, text)
{
var open = symbols[0]
, close = symbols[1]
, reg = new RegExp('(\\' + open + ')([\\s\\S])*(\\' + close + ')','g')
, test = reg.exec(text);
if (test) return {
start: test.index,
str: test[0]
};
else return false;
};
var recursiveCheck = function(text)
{
var i, nestTests = [], test, symbols;
// nestTest with each symbol
for (i = 0; i < symbolsArray.length; i++)
{
symbols = symbolsArray[i];
test = nestTest(symbols, text);
if (test) nestTests.push(test);
}
// sort tests by start index
nestTests.sort(function(a, b)
{
return a.start - b.start;
});
if (nestTests.length)
{
// build nest data: calculate match end index
for (i = 0; i < nestTests.length; i++)
{
test = nestTests[i];
var end = test.start + ( (test.str) ? test.str.length : 0 );
nestTests[i].end = end;
var last = (nestTests[i + 1]) ? nestTests[i + 1].index : text.length;
nestTests[i].pos = text.substring(end, last);
}
for (i = 0; i < nestTests.length; i++)
{
test = nestTests[i];
// recursive checks what's after the nest
if (test.pos.length && !recursiveCheck(test.pos)) return false;
// recursive checks what's in the nest
if (test.str.length) {
test.str = test.str.substring(1, test.str.length - 1);
return recursiveCheck(test.str);
} else return true;
}
} else {
// if no nests then check for orphan symbols
var closeTest = closeReg.test(text);
var openTest = openReg.test(text);
return !(closeTest || openTest);
}
};
return recursiveCheck(text);
};
Using c# OOPS programming... Small and simple solution
Console.WriteLine("Enter the string");
string str = Console.ReadLine();
int length = str.Length;
if (length % 2 == 0)
{
while (length > 0 && str.Length > 0)
{
for (int i = 0; i < str.Length; i++)
{
if (i + 1 < str.Length)
{
switch (str[i])
{
case '{':
if (str[i + 1] == '}')
str = str.Remove(i, 2);
break;
case '(':
if (str[i + 1] == ')')
str = str.Remove(i, 2);
break;
case '[':
if (str[i + 1] == ']')
str = str.Remove(i, 2);
break;
}
}
}
length--;
}
if(str.Length > 0)
Console.WriteLine("Invalid input");
else
Console.WriteLine("Valid input");
}
else
Console.WriteLine("Invalid input");
Console.ReadKey();
This is my solution to the problem.
O(n) is the complexity of time without complexity of space.
Code in C.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool checkBraket(char *s)
{
int curly = 0, rounded = 0, squre = 0;
int i = 0;
char ch = s[0];
while (ch != '\0')
{
if (ch == '{') curly++;
if (ch == '}') {
if (curly == 0) {
return false;
} else {
curly--; }
}
if (ch == '[') squre++;
if (ch == ']') {
if (squre == 0) {
return false;
} else {
squre--;
}
}
if (ch == '(') rounded++;
if (ch == ')') {
if (rounded == 0) {
return false;
} else {
rounded--;
}
}
i++;
ch = s[i];
}
if (curly == 0 && rounded == 0 && squre == 0){
return true;
}
else {
return false;
}
}
void main()
{
char mystring[] = "{{{{{[(())}}]}}}";
int answer = checkBraket(mystring);
printf("my answer is %d\n", answer);
return;
}

Resources