Sunday, February 22, 2015

Calculator (Math)

Question:  design and implement a calculate that can calculate expressions like:
+ 2 4
* 8 ( + 7 12)
( + 7 ( * 8 12 ) ( * 2 (+ 9 4) 7 ) 3 )

(PS:all items are space deli-metered.)

Example answers
+ 2 4 => 2 + 4 = 6
* 8 ( + 7 12) => 8 * ( 7 + 12 ) = 152
"( + + + 7 ( * 8 12 ) ( * * 2 ( + 9 4 ) 7 ) 3 )" => 7+8*12+2*(9+4)*7+3 = 288

Idea: Polish notation (prefix notation). Use a stack. Scan from right to left,
1) if the character is "(" or ")": ignore
2) if the character is an operator, pop two operands for the operator and push back the results
3) if the character is an integer, push to the stack.

Time: O(n) Space: O(n)

Code:
 public class Calculator {  
      public Calculator()  
      {  
           String input1="+ 2 4";  
           String input2="* 8 ( + 7 12 )";  
           String input3="( + + + 7 ( * 8 12 ) ( * * 2 ( + 9 4 ) 7 ) 3 )";  
           System.out.println(calculate(input1));  
           System.out.println(calculate(input2));  
           System.out.println(calculate(input3));  
      }  
      public int calculate(String s)  
      {  
           if(s==null||s.length()==0)  
                return 0;  
           String[] symbols=s.split(" ");  
           Stack<Integer> stack=new Stack<Integer>();  
           for(int i=symbols.length-1;i>=0;i--)  
           {  
                int type=isOperator(symbols[i]);  
                if(type==0)  
                     continue;  
                if(type==5)  
                     stack.push(Integer.parseInt(symbols[i]));  
                else  
                {  
                     int second=stack.pop();  
                     int first=stack.pop();  
                     switch(type)  
                     {  
                     case 1:  
                          stack.push(first+second);  
                          break;  
                     case 2:  
                          stack.push(first-second);  
                          break;  
                     case 3:   
                          stack.push(first*second);  
                          break;  
                     case 4:  
                          stack.push(first/second);  
                          break;  
                     default:  
                          break;  
                     }  
                }  
           }  
           return stack.pop();  
      }  
      public int isOperator(String s)  
      {  
           if(s.equals("(")||s.equals(")"))  
                return 0;  
           if(s.equals("+"))  
                return 1;  
           else if(s.equals("-"))  
                return 2;  
           else if (s.equals("*"))  
                return 3;  
           else if(s.equals("/"))  
                return 4;  
           else  
                return 5;  
      }  
 }  

No comments:

Post a Comment