botgob

fungerande calculator

Feb 15th, 2021
909
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.62 KB | None | 0 0
  1. import java.util.*;
  2.  
  3. import static java.lang.Double.NaN;
  4. import static java.lang.Double.valueOf;
  5. import static java.lang.Math.incrementExact;
  6. import static java.lang.Math.pow;
  7.  
  8.  
  9. /*
  10.  *   A calculator for rather simple arithmetic expressions
  11.  *
  12.  *   This is not the program, it's a class declaration (with methods) in it's
  13.  *   own file (which must be named Calculator.java)
  14.  *
  15.  *   NOTE:
  16.  *   - No negative numbers implemented
  17.  */
  18. public class Calculator {
  19.  
  20.     // Here are the only allowed instance variables!
  21.     // Error messages (more on static later)
  22.     final static String MISSING_OPERAND = "Missing or bad operand";
  23.     final static String DIV_BY_ZERO = "Division with 0";
  24.     final static String MISSING_OPERATOR = "Missing operator or parenthesis";
  25.     final static String OP_NOT_FOUND = "Operator not found";
  26.  
  27.     // Definition of operators
  28.     final static String OPERATORS = "+-*/^";
  29.  
  30.     // Method used in REPL
  31.     double eval(String expr) {
  32.         if (expr.length() == 0) {
  33.             return NaN;
  34.         }
  35.         List<String> tokens = tokenize(expr);
  36.         List<String> postfix = infix2Postfix(tokens);
  37.         return evalPostfix(postfix);
  38.     }
  39.  
  40.     // ------  Evaluate RPN expression -------------------
  41.  
  42.     double evalPostfix(List<String> postfix) {
  43.         Deque<String> stack = new ArrayDeque<String>();
  44.         List<String> results = new ArrayList<String>();
  45.         double a,b;
  46.         if (postfix.size() == 1){
  47.             return valueOf(postfix.get(0));
  48.         }
  49.         for (int i = 0; i < postfix.size() ; i++) {
  50.             if(!isOperator(postfix.get(i))){
  51.                 stack.push(postfix.get(i));
  52.             }
  53.             else{
  54.                 a = Double.valueOf(stack.pop());
  55.                 b = Double.valueOf(stack.pop());
  56.                 stack.push(applyOperator(postfix.get(i), a, b)+"");
  57.             }
  58.         }
  59.         return Double.valueOf(stack.pop());
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.         /*
  68.         Deque<String> que = new ArrayDeque<String>();
  69.         Double a,b, result;
  70.         for (int i = 0; i < postfix.size(); i++) {
  71.             if (!isOperator(postfix.get(i))){
  72.                 que.push(postfix.get(i));
  73.             } else {
  74.                 List<double> results = new ArrayList<double>();
  75.                 a = valueOf(que.pop());
  76.                 b = valueOf(que.pop());
  77.  
  78.                 result = applyOperator(postfix.get(i), a, b);
  79.             }
  80.         }
  81.         return 0;
  82.         */
  83.     }
  84.  
  85.     boolean isOperator(String s){
  86.         String[] operators = {"+","-", "*", "/", "^", "(", ")"};
  87.         for (int i = 0; i < operators.length; i++) {
  88.             if (operators[i].contains(s)){
  89.                 return true;
  90.             }
  91.         }
  92.         return false;
  93.     }
  94.  
  95.     double applyOperator(String op, double d1, double d2) {
  96.         switch (op) {
  97.             case "+":
  98.                 return d1 + d2;
  99.             case "-":
  100.                 return d2 - d1;
  101.             case "*":
  102.                 return d1 * d2;
  103.             case "/":
  104.                 if (d1 == 0) {
  105.                     throw new IllegalArgumentException(DIV_BY_ZERO);
  106.                 }
  107.                 return d2 / d1;
  108.             case "^":
  109.                 return pow(d2, d1);
  110.         }
  111.         throw new RuntimeException(OP_NOT_FOUND);
  112.     }
  113.  
  114.     // ------- Infix 2 Postfix ------------------------
  115.  
  116.     List<String> infix2Postfix(List<String> infix) {
  117.         String[] operators = {"+","-", "*", "/", "^", "(", ")"};
  118.         List<String> postFix = new ArrayList<String>();
  119.         Deque<String> que = new ArrayDeque<String>();
  120.         int count = 0;
  121.         boolean latestBracket = false;
  122.         for (int i = 0; i < infix.size(); i++) {
  123.             for (int j = 0; j < operators.length; j++) {
  124.                 if (!que.isEmpty() && !que.peek().contains("(")){
  125.                     latestBracket = false;
  126.                 } else if (!que.isEmpty()){
  127.                     latestBracket = true;
  128.                 }
  129.                 if (!infix.get(i).contains(operators[j])){
  130.                     count++;
  131.                 } else{
  132.                     if (latestBracket && !infix.get(i).contains("(") && !infix.get(i).contains(")")){
  133.                         que.push(infix.get(i));
  134.                         latestBracket = false;
  135.                         break;
  136.                     }
  137.                     if (infix.get(i).contains("(")){
  138.                         que.push(infix.get(i));
  139.                         latestBracket = true;
  140.                     } else if (infix.get(i).contains(")")) {
  141.                         int stackSize = que.size();
  142.                         for (int k = 0; k < stackSize; k++) {
  143.                             if (!que.peek().contains("(")){
  144.                                 postFix.add(que.pop());
  145.                             } else {
  146.                                 que.pop();
  147.                                 break;
  148.                             }
  149.                         }
  150.                     } else {
  151.                         if (que.isEmpty()){
  152.                             que.push(infix.get(i));
  153.                         } else if (getPrecedence(que.peek()) > getPrecedence(infix.get(i))){
  154.                             String popper = que.peek();
  155.                             postFix.add(que.pop());
  156.                             while (true){
  157.                                 if (!que.isEmpty() && que.peek().contains(popper)){
  158.                                     postFix.add(que.pop());
  159.                                 } else break;
  160.                             }
  161.                             que.push(infix.get(i));
  162.                         } else if (getPrecedence(que.peek()) == getPrecedence(infix.get(i))){
  163.                             if (getAssociativity(infix.get(i)) == Assoc.LEFT){
  164.                                 postFix.add(que.pop());
  165.                             }
  166.                             que.push(infix.get(i));
  167.                         } else if (getPrecedence(que.peek()) < getPrecedence(infix.get(i))){
  168.                             que.push(infix.get(i));
  169.                         }
  170.                     }
  171.  
  172.  
  173.                 }
  174.             }
  175.             if (count == operators.length){
  176.                 postFix.add(infix.get(i));
  177.             }
  178.             count = 0;
  179.         }
  180.         int queSize = que.size();
  181.         while(!que.isEmpty()){
  182.             postFix.add(que.pop());
  183.         }
  184.         return postFix;
  185.     }
  186.  
  187.     int getPrecedence(String op) {
  188.         if ("+-".contains(op)) {
  189.             return 2;
  190.         } else if ("*/".contains(op)) {
  191.             return 3;
  192.         } else if ("^".contains(op)) {
  193.             return 4;
  194.         } else {
  195.             throw new RuntimeException(OP_NOT_FOUND);
  196.         }
  197.     }
  198.  
  199.     Assoc getAssociativity(String op) {
  200.         if ("+-*/".contains(op)) {
  201.             return Assoc.LEFT;
  202.         } else if ("^".contains(op)) {
  203.             return Assoc.RIGHT;
  204.         } else {
  205.             throw new RuntimeException(OP_NOT_FOUND);
  206.         }
  207.     }
  208.  
  209.     enum Assoc {
  210.         LEFT,
  211.         RIGHT
  212.     }
  213.  
  214.     // ---------- Tokenize -----------------------
  215.  
  216.     // List String (not char) because numbers (with many chars)
  217.     List<String> tokenize(String expr) {
  218.        // TODO
  219.         List<String> tokens = new ArrayList<String>();
  220.         StringTokenizer test = new StringTokenizer(expr,"[\\+\\-*/\\^ ()]+", true );
  221.         while(test.hasMoreTokens()){
  222.             tokens.add(test.nextToken());
  223.         }
  224.         for (int i = 0; i < tokens.size(); i++) {
  225.             if (tokens.get(i).contains(" ")){
  226.                 tokens.remove(i);
  227.                 i = 0;
  228.             }
  229.         }
  230.         return tokens;
  231.     }
  232. }
  233.  
Advertisement
Add Comment
Please, Sign In to add comment