软件工程概论个人作业2

  老师有将上次的作业进行了功能上的升级,加入了新的功能,所以我就将我的作业设计再次展示。

  程序设计思路:上次的程序设计只是简单的两个数的四则运算,不需要对运算符的种类进行筛选,这次的作业我将上次的程序设计代码,进行了重新封装,设计了一个输入数据的方法,对不同的输入数据进行不同要求的生成式子,并对程序生成的式子进行判断是否符合标准。对符合要求的式子存放在string数组中,然后在数组中的式子输出到结果即可。

  程序源代码:

  1 package 四则运算;
  2 
  3 import java.util.Scanner;
  4 
  5 public class yunsuan {
  6 
  7     
  8     public static void main(String[] args) {
  9         // TODO Auto-generated method stub
 10         String array1[]=new String[1000];
 11         input(array1);
 12 
 13     }
 14     public static void input(String array1[]){
 15         int a,b,c,d,e,f;
 16         Scanner scanner=new Scanner(System.in);
 17         System.out.println("请输入生成题目的数量(少于1000道):");
 18         a=scanner.nextInt();
 19         System.out.println("请输入数字的范围(1-?):");
 20         b=scanner.nextInt();
 21         System.out.println("是否有乘除法(包含乘除法请输入1,不包含请输入0)");
 22         c=scanner.nextInt();
 23         System.out.println("是否有括号(最多可以支持十个数参与计算,包含括号请输入1,不包含请输入0)");
 24         d=scanner.nextInt();
 25         System.out.println("加减有无负数(有负数请输入1,没有负数请输入0)");
 26         e=scanner.nextInt();
 27         System.out.println("除法有无余数(有余数请输入1,没有余数请输入0)");
 28         f=scanner.nextInt();
 29         int m;
 30         boolean n,o,p;
 31         if(c==1)
 32             m=4;
 33         else m=2;
 34         if(d==1)
 35             n=true;
 36         else n=false;
 37         if(e==1)
 38             o=true;
 39         else o=false;
 40         if(f==1)
 41             p=true;
 42         else p=false;
 43         for(int i=0;i<a;i++){
 44             array1[i]=birth(b,m,n,o,p);
 45         }
 46         output(a,array1);
 47     }
 48 
 49     public static void output(int a,String []array1 ){
 50         for(int i=0;i<a;i++){
 51             System.out.println(array1[i]);
 52         }
 53     }
 54     public static String birth(int fanwei,int fuhao,boolean bra,boolean o,boolean p){
 55         int a=((int)(Math.random()*9))+2;
 56         int b,c;
 57         String str ="";
 58         for(int i=0;i<a;i++){
 59             b=(int)(Math.random()*fanwei)+1;
 60             c=(int)(Math.random()*fuhao);
 61             if(i==a-1)
 62                  str+=b+"=";
 63             else {
 64                 switch(c){
 65                 case 0: str+=b+"+";break;
 66                 case 1: str+=b+"-";break;
 67                 case 2: str+=b+"*";break;
 68                 case 3:    str+=b+"/";break;
 69                 }
 70                 
 71             }
 72             
 73         }
 74         if(bra&&((int)( Math.random()*100))>50){
 75             //在这里为express中插入一对括号
 76             
 77             int first = (int)(Math.random()*(a-1))+1;//括起来的第一个数
 78             int next = (int)(Math.random()*(a-1))+1;//括起来的最后一个数
 79             if(first > next){//如果第一个数比第二个数大,则交换两个数的值
 80                 first = first^next;
 81                 next = first^next;
 82                 first=first^next;
 83             }
 84             if(next-first >= 2){//如果next和first的差值小于2,则不执行以下步骤,因为括号中至少有两个数
 85                 //length记下表达式字符串的长度,j记下遍历字符串中数字的个数
 86                 int length = str.length(),j=0;
 87                 //用字符串建立一个动态字符串。
 88                 StringBuffer temp = new StringBuffer(str);
 89                 //开始循环遍历字符串
 90                 for(int i=0; i < length; i++){
 91                     char cc = temp.charAt(i);//取出下标为i的字符
 92                     if(first==1&&i==0)        //如果括号括起来的第一个数字为表达式中第一个操作数,在表达式最前面插入(
 93                         temp.insert(0, '(');
 94                     if(cc > '9' || cc < '0'){//如果当前字符是运算符字符
 95                         j++;                //表示刚刚遍历一个数字,所以j加一
 96                         if(j==first-1){        //如果j到达first的前一个位置,在当前字符的后面插入“(”
 97                             temp.insert(i+1, '(');i++;
 98                         }
 99                         if(j==next)            //如果j到达next的位置,在当前字符前面插入一个“)”
100                             temp.insert(i, ')');
101                     }
102                 }
103                 str = temp.toString();//将动态字符串转换为普通字符串
104             }
105         }
106         //加减有无负数
107         /*
108         if(!o){
109 
110             int length2 = str.length(),j=0,i;
111             int m=str.indexOf('-');
112             StringBuffer temp = new StringBuffer(str);
113             if(m>0){
114                 for( i=m-1; i>0; i--){
115                     char cc = temp.charAt(i);
116                     if(cc > '9' || cc < '0')
117                         break;
118                 }
119                 
120                 String hh=temp.substring(i+1, m-1);
121                 int x=Integer.valueOf(hh);
122                 
123                 for( i=m; i<length2; i++){
124                     char cc = temp.charAt(i);
125                     if(cc > '9' || cc < '0')
126                         break;
127                 }
128                 hh=temp.substring(m+1, i-1);
129                 int y=Integer.valueOf(hh);
130                 if(x-y<0){
131                     int v=x;
132                     x=y;
133                     y=v;
134                     }
135                     
136             }
137         
138         }
139         //除法有无余数
140         if(!p){
141             int length2 = str.length(),j=0,i;
142             int m=str.indexOf('/');
143             StringBuffer temp = new StringBuffer(str);
144             if(m>0){
145                 for( i=m-1; i>0; i--){
146                     char cc = temp.charAt(i);
147                     if(cc > '9' || cc < '0')
148                         break;
149                 }
150                 String hh=temp.substring(i+1, m-1);
151                 int x=Integer.valueOf(hh);
152                 for( i=m; i<length2; i++){
153                     char cc = temp.charAt(i);
154                     if(cc > '9' || cc < '0')
155                         break;
156                 }
157                 hh=temp.substring(m+1, i-1);
158                 int y=Integer.valueOf(hh);
159                 if(x%y!=0)
160                     birth( fanwei, fuhao, bra,o, p);
161                     
162             }
163         }
164         */
165         //余数的判断由于存在括号的原因无法使用。
166         
167         return str;
168     }
169 }

  字符串表达式求值:

  1 import java.util.Collections;
  2 import java.util.Stack;
  3 
  4 public class Calculator {
  5     private Stack<String> postfixStack  = new Stack<String>();//后缀式栈
  6     private Stack<Character> opStack  = new Stack<Character>();//运算符栈
  7     private int [] operatPriority  = new int[] {0,3,2,1,-1,1,0,2};//运用运算符ASCII码-40做索引的运算符优先级
  8     public static void main(String[] args) {
  9         System.out.println(5+12*(3+5)/7.0);
 10         Calculator cal  = new Calculator();
 11         String s = "5+12*(3+5)/7";
 12         double result  = cal.calculate(s);
 13         System.out.println(result);
 14     }
 15 
 16     /**
 17      * 按照给定的表达式计算
 18      * @param expression 要计算的表达式例如:5+12*(3+5)/7
 19      * @return
 20      */
 21     public double calculate(String expression) {
 22         Stack<String> resultStack  = new Stack<String>();
 23         prepare(expression);
 24         Collections.reverse(postfixStack);//将后缀式栈反转
 25         String firstValue  ,secondValue,currentValue;//参与计算的第一个值,第二个值和算术运算符
 26         while(!postfixStack.isEmpty()) {
 27             currentValue  = postfixStack.pop();
 28             if(!isOperator(currentValue.charAt(0))) {//如果不是运算符则存入操作数栈中
 29                 resultStack.push(currentValue);
 30             } else {//如果是运算符则从操作数栈中取两个值和该数值一起参与运算
 31                  secondValue  = resultStack.pop();
 32                  firstValue  = resultStack.pop();
 33                  String tempResult  = calculate(firstValue, secondValue, currentValue.charAt(0));
 34                  resultStack.push(tempResult);
 35             }
 36         }
 37         return Double.valueOf(resultStack.pop());
 38     }
 39     
 40     /**
 41      * 数据准备阶段将表达式转换成为后缀式栈
 42      * @param expression
 43      */
 44     private void prepare(String expression) {
 45         opStack.push(',');//运算符放入栈底元素逗号,此符号优先级最低
 46         char[] arr  = expression.toCharArray();
 47         int currentIndex  = 0;//当前字符的位置
 48         int count = 0;//上次算术运算符到本次算术运算符的字符的长度便于或者之间的数值
 49         char currentOp  ,peekOp;//当前操作符和栈顶操作符
 50         for(int i=0;i<arr.length;i++) {
 51             currentOp = arr[i];
 52             if(isOperator(currentOp)) {//如果当前字符是运算符
 53                 if(count > 0) {
 54                     postfixStack.push(new String(arr,currentIndex,count));//取两个运算符之间的数字
 55                 }
 56                 peekOp = opStack.peek();
 57                 if(currentOp == ')') {//遇到反括号则将运算符栈中的元素移除到后缀式栈中直到遇到左括号
 58                     while(opStack.peek() != '(') {
 59                         postfixStack.push(String.valueOf(opStack.pop()));
 60                     }
 61                     opStack.pop();
 62                 } else {
 63                     while(currentOp != '(' && peekOp != ',' && compare(currentOp,peekOp) ) {
 64                         postfixStack.push(String.valueOf(opStack.pop()));
 65                         peekOp = opStack.peek();
 66                     }
 67                     opStack.push(currentOp);
 68                 }
 69                 count = 0;
 70                 currentIndex = i+1;
 71             } else {
 72                 count++;
 73             }
 74         }
 75         if(count > 1 || (count == 1 && !isOperator(arr[currentIndex]))) {//最后一个字符不是括号或者其他运算符的则加入后缀式栈中
 76             postfixStack.push(new String(arr,currentIndex,count));
 77         } 
 78         
 79         while(opStack.peek() != ',') {
 80             postfixStack.push(String.valueOf( opStack.pop()));//将操作符栈中的剩余的元素添加到后缀式栈中
 81         }
 82     }
 83     
 84     /**
 85      * 判断是否为算术符号
 86      * @param c
 87      * @return
 88      */
 89     private boolean isOperator(char c) {
 90         return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' ||c == ')';
 91     }
 92     
 93     /**
 94      * 利用ASCII码-40做下标去算术符号优先级
 95      * @param cur
 96      * @param peek
 97      * @return
 98      */
 99     public  boolean compare(char cur,char peek) {// 如果是peek优先级高于cur,返回true,默认都是peek优先级要低
100         boolean result  = false;
101         if(operatPriority[(peek)-40] >= operatPriority[(cur) - 40]) {
102            result = true;
103         }
104         return result;
105     }
106     
107     /**
108      * 按照给定的算术运算符做计算
109      * @param firstValue
110      * @param secondValue
111      * @param currentOp
112      * @return
113      */
114     private String calculate(String firstValue,String secondValue,char currentOp) {
115         String result  = "";
116         switch(currentOp) {
117             case '+':
118                 result = String.valueOf(ArithHelper.add(firstValue, secondValue));
119                 break;
120             case '-':
121                 result = String.valueOf(ArithHelper.sub(firstValue, secondValue));
122                 break;
123             case '*':
124                 result = String.valueOf(ArithHelper.mul(firstValue, secondValue));
125                 break;
126             case '/':
127                 result = String.valueOf(ArithHelper.div(firstValue, secondValue));
128                 break;
129         }
130         return result;
131     }
132 }

  运行结果截图分析:

   周活动总结表

时间记录日志

  缺陷记录日志

原文地址:https://www.cnblogs.com/wangfengbin/p/6532817.html