java - Dijkstra's two-stack algorithm for expression evaluation -


i'm reading book on algorithms , data structures , try follow examples. try implement dijkstra's two-stack algorithm expression evaluation. takes input in form of string ( 1 + 2 ) * 3 , evaluates expression. code compiles doesn't produce correct output.

the output above expression is:

3.0 

here's code:

public class eval {     public static void main(string[] args) {         string s = "( 1 + 2 ) * 3";         evaluateandprintresult(s);     }     public static void evaluateandprintresult(string s)     {         string[] str = s.split("\\s+");         queue<string> q = new linkedlist<string>();         for(string ss : str)             q.add(ss);         stack<string> ops = new stack<string>();         stack<double> vals = new stack<double>();         while (!q.isempty())         { // read token, push if operator.             string token = q.poll();             if (token.equals("(")) ;             else if (token.equals("+")) ops.push(s);             else if (token.equals("-")) ops.push(s);             else if (token.equals("*")) ops.push(s);             else if (token.equals("/")) ops.push(s);             else if (token.equals("sqrt")) ops.push(s);             else if (token.equals(")"))             { // pop, evaluate, , push result if token ")".                 string op = ops.pop();                 double v = vals.pop();                 if (op.equals("+")) v = vals.pop() + v;                 else if (op.equals("-")) v = vals.pop() - v;                 else if (op.equals("*")) v = vals.pop() * v;                 else if (op.equals("/")) v = vals.pop() / v;                 else if (op.equals("sqrt")) v = math.sqrt(v);                 vals.push(v);             } // token not operator or paren: push double value.             else vals.push(double.parsedouble(token));         }         system.out.println(vals.pop());     } }    

i don't understand program enough correct it. how can correct program?

your problem in several places use ops.push(s). should using ops.push(token).

you pushing whole expression, should push current token.

this code correctly prints 9.0.

public static void evaluateandprintresult(string s) {     string[] str = s.split("\\s+");     queue<string> q = new linkedlist<>();     q.addall(arrays.aslist(str));     stack<string> ops = new stack<>();     stack<double> vals = new stack<>();     while (!q.isempty()) { // read token, push if operator.         string token = q.poll();         if (token.equals("(")) {         } else if (token.equals("+")) {             ops.push(token);         } else if (token.equals("-")) {             ops.push(token);         } else if (token.equals("*")) {             ops.push(token);         } else if (token.equals("/")) {             ops.push(token);         } else if (token.equals("sqrt")) {             ops.push(token);         } else if (token.equals(")")) { // pop, evaluate, , push result if token ")".             // replace top exp it' result.             double v = vals.pop();             string op = ops.pop();             if (op.equals("+")) {                 v = vals.pop() + v;             } else if (op.equals("-")) {                 v = vals.pop() - v;             } else if (op.equals("*")) {                 v = vals.pop() * v;             } else if (op.equals("/")) {                 v = vals.pop() / v;             } else if (op.equals("sqrt")) {                 v = math.sqrt(v);             }             vals.push(v);         } else {             // token not operator or paren: push double value.             vals.push(double.parsedouble(token));         }     }     system.out.println(vals.pop()); }  public void test() {     evaluateandprintresult("( ( 1 + 2 ) * 3 )"); } 

however, expression "( 1 + 2 ) * 3" still evaluates 3.0. solve need evaluate last op pushed, if there one.

public static void evaluateandprintresult(string s) {     string[] str = s.split("\\s+");     queue<string> q = new linkedlist<>();     q.addall(arrays.aslist(str));     stack<string> ops = new stack<>();     stack<double> vals = new stack<>();     while (!q.isempty()) { // read token, push if operator.         string token = q.poll();         if (token.equals("(")) {         } else if (token.equals("+")) {             ops.push(token);         } else if (token.equals("-")) {             ops.push(token);         } else if (token.equals("*")) {             ops.push(token);         } else if (token.equals("/")) {             ops.push(token);         } else if (token.equals("sqrt")) {             ops.push(token);         } else if (token.equals(")")) {             vals.push(evaluateop(ops, vals));         } else {             // token not operator or paren: push double value.             vals.push(double.parsedouble(token));         }     }     system.out.println(evaluateop(ops, vals)); }  private static double evaluateop(stack<string> ops, stack<double> vals) {     // replace top exp result.     double v = vals.pop();     string op = ops.pop();     if (op.equals("+")) {         v = vals.pop() + v;     } else if (op.equals("-")) {         v = vals.pop() - v;     } else if (op.equals("*")) {         v = vals.pop() * v;     } else if (op.equals("/")) {         v = vals.pop() / v;     } else if (op.equals("sqrt")) {         v = math.sqrt(v);     }     return v; }  public void test() {     evaluateandprintresult("( 1 + 2 ) * 3"); } 

and - tidier way of doing it.

public static void evaluateandprintresult(string s) {     string[] str = s.split("\\s+");     queue<string> q = new linkedlist<>();     q.addall(arrays.aslist(str));     stack<string> ops = new stack<>();     stack<double> vals = new stack<>();     while (!q.isempty()) { // read token, push if operator.         string token = q.poll();         switch (token) {             case "(":                 break;             case "+":             case "-":             case "*":             case "/":             case "sqrt":                 ops.push(token);                 break;             case ")":                 vals.push(evaluateop(ops, vals));                 break;             default:                 // token not operator or paren: push double value.                 vals.push(double.parsedouble(token));                 break;         }     }     system.out.println(s + " = " + evaluateop(ops, vals)); }  private static double evaluateop(stack<string> ops, stack<double> vals) {     // replace top exp result.     double v = vals.pop();     if (!ops.empty()) {         string op = ops.pop();         switch (op) {             case "+":                 v = vals.pop() + v;                 break;             case "-":                 v = vals.pop() - v;                 break;             case "*":                 v = vals.pop() * v;                 break;             case "/":                 v = vals.pop() / v;                 break;             case "sqrt":                 v = math.sqrt(v);                 break;             default:                 break;         }     }     return v; }  public void test() {     evaluateandprintresult("( ( 1 + 2 ) * 3 )"); } 

Comments

Popular posts from this blog

javascript - Laravel datatable invalid JSON response -

java - Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; -

sql server 2008 - My Sql Code Get An Error Of Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value '8:45 AM' to data type int -