zoukankan      html  css  js  c++  java
  • java小型科学计算器

    /**
    * 1.先转换为逆波兰顺序
    * 数字直接存入list,符号压入栈中,但是如果栈底元素不大于该运算符的运算顺序,则将栈底pop,直到大于栈底运算符为止,再压入栈中,
    * 最后将运算符依次全部pop(以上pop出的运算符存入list)
    * 2.根据逆序算出结果
    * 从头到尾依次读取list的数据,将数字压入栈中,出现运算符后pop出两个数字进行运算,运算式为"后pop数 运算符 先pop数"
    * 运算完毕将结果再次压入栈中.结束后,将数字栈中的唯一一个数字pop出并将其返回.
    *
    *
    * 学习之处:
    * 1.String对象的比较不要用==,>,<.而是用equal()函数.
    * 2.使用HashMap<Object,Integer>()的定义可以给对象进行编号或加权.
    * 3.需要时要给读取的信息加上结尾标志,如读入String结尾的"#".
    * 4.取String的单个字母:String temps=String.valueOf(expression.charAt(i));
    * 5.检测数字:temps.matches("[0-9.]")
    **/
      1 public class Calculator {
      2     private String string;
      3     private MyStack<String> opratorStack = new MyStack();
      4     private MyStack<Double> numberStack = new MyStack();
      5     private ArrayList<String> rpnList = new ArrayList();
      6     private Map<String,Integer> priorityMap=new HashMap<String,Integer>();//用于存储操作符优先级的Map
      7     //初始化优先级约定(可根据计算的复杂程度扩展)
      8 
      9     public Calculator(String str)
     10     {
     11         priorityMap.put("+",0);
     12         priorityMap.put("-",0);
     13         priorityMap.put("*", 1);
     14         priorityMap.put("/", 1);
     15         priorityMap.put("(", 2);
     16         string = str+"#";
     17     }
     18     private int getPriority(String op)//得到一个操作符的优先级
     19     {
     20         return priorityMap.get(op);
     21     }
     22 
     23     private void toRpn() {
     24 
     25         String temp = "";
     26         for (int i = 0; i < string.length(); i++) {
     27             String ch = String.valueOf(string.charAt(i));
     28             if (ch.matches("[0-9.]"))
     29                 temp += ch;
     30 
     31             else { //如果操作数完整,现将其存入list中再进行后续操作
     32 
     33                 if(!temp.equals("")) {//防止加入进空格
     34                     rpnList.add(temp);
     35                     temp = "";
     36                 }
     37 
     38                 if (ch.equals("#")) { //读取结束时将运算符栈依次pop并添加到rpnList中
     39                     while (!opratorStack.isEmpty()) {
     40                         rpnList.add(opratorStack.pop());
     41                     }
     42                 } else if (ch.equals(")")) { //遇到右括号将左括号后的运算符全部pop
     43                     String op = opratorStack.pop();
     44                     while (!op .equals("(")) {
     45                         rpnList.add(op);
     46                         op = opratorStack.pop();
     47                     }
     48                 } else {
     49                     if (!opratorStack.isEmpty()) { //如果为普通的运算符
     50                         String endOprator = opratorStack.endValue();
     51 
     52                         while (!endOprator.equals( "(") && (getPriority(ch) < getPriority(endOprator)
     53                                 || getPriority(ch) == getPriority(endOprator))) {
     54                             rpnList.add(opratorStack.pop());//如果
     55                             if (!opratorStack.isEmpty()) {
     56                                 endOprator = opratorStack.endValue();
     57                             }else
     58                                 break;
     59 
     60                         }
     61 
     62                         opratorStack.push(ch);
     63                     }
     64                     else
     65                         opratorStack.push(ch);
     66                 }
     67             }
     68         }
     69     }
     70 
     71     public double calculate(String string){
     72         this.string = string+"#";
     73         return calculate();
     74     }
     75 
     76     public double calculate(){
     77         toRpn();//逆波兰序列转换
     78 
     79         //扫描String对象
     80         for(int i = 0; i < rpnList.size(); i++){
     81             String temp = rpnList.get(i);
     82             //匹配第一个字符,为数字的则将String对象转为Double并存入numberStack中
     83             if(String.valueOf(temp.charAt(0)).matches("[0-9]")){
     84                 numberStack.push(Double.valueOf(temp));
     85             } //匹配到运算符,调出最后两个numberStack中数字进行运算,并将得数压入栈中(栈次底数 操作符 栈最底数)
     86             else {
     87                 //Double n = opration(numberStack.pop(), numberStack.pop(), temp);
     88                 Double n = numberStack.pop();
     89                 numberStack.push(opration(numberStack.pop(), n , temp));
     90             }
     91         }
     92 
     93         rpnList = new ArrayList();//为下次运算做准备
     94         return numberStack.pop();
     95     }
     96 
     97     private Double opration(Double val1,Double val2,String oprator){
     98         if(oprator.equals("+"))
     99             val1 += val2;
    100         else if(oprator.equals("-"))
    101             val1 -= val2;
    102         else if(oprator.equals("*"))
    103             val1 *= val2;
    104         else
    105             val1 /= val2;
    106         return val1;
    107     }
    108 
    109     public static void main(String[] args) {
    110         String string1 = "12+2*37-(4*5+6)*7";
    111         Calculator calculator = new Calculator(string1);
    112 
    113         System.out.println(calculator.calculate());
    114         System.out.println(calculator.calculate("4.99+5.99+6.99*1.06"));
    115     }
    116 }

    运算结果:

    -96.0
    18.389400000000002

    Process finished with exit code 0

  • 相关阅读:
    集训笔记——dp继续
    集训笔记——各种dp(dp杂谈)
    集训笔记——dp
    洛谷P3197 [HNOI2008]越狱 题解
    集训笔记——杂题选讲(图论,dp)
    集训笔记——杂题选讲(带数学推导的递推、递归和dp,卡特兰数)
    滑动窗口+二分--P3957 跳房子
    差分+二分答案--P1083 借教室
    逆序对--P1966 火柴排队
    数位dp--P2657 [SCOI2009] windy 数
  • 原文地址:https://www.cnblogs.com/sunnysola/p/4836482.html
Copyright © 2011-2022 走看看