现代软件工程课程作业 第一章第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

 

于阜甲

posted @ 2016-09-11 22:26  TalkIsCheap_5  阅读(213)  评论(0编辑  收藏  举报