• 现代软件工程课程作业 第一章第1题


    有两个实体类:一个是逆波兰表达式类,一个是真分数类,还有一个工具类,生成随机数和栈深度复制

    生成四则运算式通过先生成逆波兰表达式再转换为中序表达式来完成,计算通过直接计算逆波兰表达式的值,这就产生了三个功能需要实现:生成逆波兰表达式、转为中序表达式、计算。

    真分数实现了生成,化简,加减乘除功能,可以加入四则运算式运算。

    支持可变运算式长度

    这里只粘逆波兰表达式代码吧

      1 package cn.edu.tju.showmethecode.calculate;
      2 
      3 import java.util.Stack;
      4 
      5 import sun.rmi.runtime.Log;
      6 
      7 
      8 public class RPNExpression {
      9     
     10     private Stack<Object> RPNExp = new Stack<Object>();    //逆波兰表达式
     11     private int length;            //运算数个数
     12     private String value;        //表达式的值
     13     
     14     public RPNExpression() {
     15         this(4);
     16     }
     17     
     18     public RPNExpression(int length) {
     19         if(length<2)
     20             throw new IllegalArgumentException("长度设置过短!");
     21         
     22         this.length = length;
     23         generateRPNExp(length);
     24         calcValue();
     25     }
     26     
     27     private void generateRPNExp(int length) {
     28         int symbolCount = 0;
     29         int operatorCount = 0;
     30         while(operatorCount + symbolCount < length * 2 - 1){
     31             
     32             if(operatorCount-1 > symbolCount && operatorCount < length){
     33                 if(Utils.getRandomBoolean()){        //true生成运算符,false操作数
     34                     this.RPNExp.push(generateSymbol());
     35                     symbolCount ++;
     36                 }else{
     37                     this.RPNExp.push(Utils.getRandomBoolean() ? generateNumeric() : generateProperFraction());
     38                     operatorCount ++;
     39                 }
     40             }else if(operatorCount-1 <= symbolCount && operatorCount < length) {                                    //true生成整数,false生成分数
     41                 this.RPNExp.push(Utils.getRandomBoolean() ? generateNumeric() : generateProperFraction());
     42                 operatorCount ++;
     43             }else if(operatorCount-1 > symbolCount && operatorCount >=length) {
     44                 this.RPNExp.push(generateSymbol());
     45                 symbolCount ++;
     46             }
     47         }
     48     }
     49     
     50     private int generateNumeric() {
     51         return Utils.getRandomInteger(1, 100);
     52     }
     53     
     54     private char generateSymbol() {
     55         char[] symbol = {'+','−','×','÷'};
     56         return symbol[Utils.getRandomInteger(0, 4)];
     57     }
     58     
     59     private ProperFraction generateProperFraction() {
     60         int denominator = Utils.getRandomInteger(2, 10);
     61         int numerator = Utils.getRandomInteger(1, denominator);
     62         return new ProperFraction(numerator, denominator);
     63     }
     64     /*
     65      * get逆波兰表达式
     66      */
     67     public static String generateArithmetic(int length){
     68         return (new RPNExpression(length)).convertToSeqExp();
     69     }
     70     
     71     private void calcValue(){
     72         Stack<Object> RPNStack = Utils.cloneStack(this.RPNExp);
     73         Stack<Object> numStack = new Stack<Object>();            //数字栈 
     74         
     75         while(!RPNStack.empty()){
     76             if(RPNStack.peek() instanceof Integer || RPNStack.peek() instanceof ProperFraction){
     77                 numStack.push(RPNStack.pop());
     78             }else if(RPNStack.peek() instanceof Character){
     79                 Object rightOperator = numStack.pop();
     80                 Object leftOperator = numStack.pop();
     81                 if(rightOperator instanceof Integer)
     82                     rightOperator = new ProperFraction((Integer) rightOperator, 1);
     83                 if(leftOperator instanceof Integer)
     84                     leftOperator = new ProperFraction((Integer) leftOperator, 1);
     85                     
     86                 switch ((Character) RPNStack.pop()) {
     87                 case '+':
     88                     numStack.push(((ProperFraction)leftOperator).add((ProperFraction)rightOperator));
     89                     break;
     90                 case '−':
     91                     numStack.push(((ProperFraction)leftOperator).minus((ProperFraction)rightOperator));
     92                     break;
     93                 case '×':
     94                     numStack.push(((ProperFraction)leftOperator).multiply((ProperFraction)rightOperator));
     95                     break;
     96                 case '÷':
     97                     numStack.push(((ProperFraction)leftOperator).devide((ProperFraction)rightOperator));
     98                     break;
     99                 default:
    100 //                    throw new Exception("");
    101                     break;
    102                 }
    103             }
    104         }
    105         
    106         this.value = ((ProperFraction) numStack.pop()).toString();
    107     }
    108     
    109     private String convertToSeqExp() {
    110         System.out.println(this.RPNExp.toString());
    111         Stack<Object> RPNStack = Utils.cloneStack(this.RPNExp);
    112         Stack<String> tempExpStack = new Stack<String>();        //临时表达式栈
    113         
    114         while(!RPNStack.empty()){
    115             if(RPNStack.peek() instanceof Integer || RPNStack.peek() instanceof ProperFraction){
    116                 tempExpStack.push(RPNStack.pop().toString());
    117             }else if(RPNStack.peek() instanceof Character){
    118                 String rightOperator = tempExpStack.pop();
    119                 String leftOperator = tempExpStack.pop();
    120                 
    121                 if("×÷−".contains(RPNStack.peek().toString())){
    122                     if(isNeedBrackets((Character) RPNStack.peek(), rightOperator, true)){
    123                         rightOperator = "( " + rightOperator + " )";
    124                     }
    125                     if(isNeedBrackets((Character) RPNStack.peek(), leftOperator, false)){
    126                         leftOperator = "( " + leftOperator + " )";
    127                     }
    128                 }
    129                 
    130                 tempExpStack.push(leftOperator + " " + RPNStack.pop().toString() + " " + rightOperator);
    131             }
    132         }
    133         
    134         return tempExpStack.pop();
    135     } 
    136     
    137     /*
    138      * 判断一个临时表达式是否需要加括号,
    139      * 有三种情况:
    140      * 1. 当前符号是 ×÷,临时表达式符号是 +−
    141      * 2. 当前符号是 −,临时表达式是右操作数,且符号为 +−
    142      * 3. 当前符号是 ÷,临时表达式是右操作数,且符号为 ×÷
    143      */
    144     private boolean isNeedBrackets(Character currentSymbol, String tempExp, boolean rightOrNot) {
    145         //判断括号外是什么符号
    146         String priority = symbolOutsideOfBranckets(tempExp);
    147         
    148         if("+−".equals(priority) && "×÷".contains(currentSymbol.toString())) {
    149             return true;
    150         }
    151         if("×÷".equals(priority) && rightOrNot && "÷".equals(currentSymbol.toString())) {
    152             return true;
    153         }
    154         if("+−".equals(priority) && rightOrNot && "−".equals(currentSymbol.toString())) {
    155             return true;
    156         }
    157             
    158         return false;
    159     }
    160     
    161     /*
    162      * 判断临时操作数最外层的符号是什么,×÷ 或 +− 后者无符号
    163      * count是括号的左括号的数量
    164      */
    165     private String symbolOutsideOfBranckets(String tempExp) {
    166         if(!tempExp.contains(" ")){
    167             return "nothing";                
    168         }
    169         
    170         String[] elements = tempExp.split(" ");
    171         int count = 0;
    172         
    173         for(int i=0; i<elements.length; i++){
    174             if(count == 0 && "+−".contains(elements[i])) {
    175                 return "+−";
    176             }else if("(".equals(elements[i])) {
    177                 count ++;
    178             }else if(")".equals(elements[i])) {
    179                 count --;
    180             }
    181         }
    182         return "×÷";
    183     }
    184     
    185     public int getLength() {
    186         return this.length;
    187     }
    188     
    189     public String getSeqExp() {
    190         return convertToSeqExp();
    191     }
    192     
    193     public String getValue() {
    194         return this.value;
    195     }
    196     
    197     public String toString() {
    198         Stack<Object> RPNStack = Utils.cloneStack(this.RPNExp);
    199         StringBuilder sb = new StringBuilder();
    200         while(!RPNStack.empty())
    201             sb.append(RPNStack.pop().toString()).append(" ");
    202         return sb.toString();
    203     }
    204 }
    RPNExpression

    于阜甲

  • 相关阅读:
    Java基础学习总结(41)——JPA常用注解
    Java基础学习总结(41)——JPA常用注解
    【云速建站】视频播放专题
    一招教你如何修复MySQL slave中继日志损坏问题
    【nodejs原理&源码赏析(3)】欣赏手术级的原型链加工艺术
    【云速建站】后台数据批量导入导出
    【云速建站】会员注册弹窗添加及设置
    【nodejs原理&源码赏析(2)】KOA中间件的基本运作原理
    【nodejs原理&源码赏析(1)】Express中间件系统的基本实现
    补习系列(5)-springboot- restful应用
  • 原文地址:https://www.cnblogs.com/smtc/p/5863011.html
Copyright © 2020-2023  润新知