软件工程概论个人作业2
Posted 风飘万点江满月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程概论个人作业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 }
运行结果截图分析:
周活动总结表
时间记录日志
缺陷记录日志
以上是关于软件工程概论个人作业2的主要内容,如果未能解决你的问题,请参考以下文章