结对编程作业(JAVA实现)
github地址:https://github.com/IMFatDragon/sizeyunsuan.git
完成者:
周惠龙 3117004638
陈浩峰 3117004603
- 使用 -n 参数控制生成题目的个数,例如 SiZeYunSuan.exe -n 10 将生成10个题目。(完成)
- 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如SiZeYunSuan.exe -r 10 将生成10以内(不包括10)的四则运算题目。(完成)
- 生成的题目中计算过程不能产生负数,即算术表达式中如果存在形如e1 − e2的子表达式,必须e1 ≥ e2。(完成)
- 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。(完成)
- 每道题目中出现的运算符个数不超过3个。(完成)
- 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。(完成)
- 生成的题目存入执行程序的当前目录下的Exercises.txt文件,格式如下:(完成)
- 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:(完成)
- 程序应能支持一万道题目的生成(完成)
- 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:(未完成)
- 表达式生成模块:表达式包括运算符部分(加减乘除)、数字部分(自然数,真分数,带分数)、括号部分。数值部分利用random对象的nextInt方法随机从1开始生成,其中分子随机数的数值范围是比分母小1,保证生成的数字不出现假分数的情况;运算符的个数是利用函数随机生成1-3之间的自然数,加减乘除的符号也是利用随机数1-4来生成;符号部分利用next Boolean方法根据true或者false来决定括号的生成,该过程中利用一个变量来标记括号范围。
- 表达式运算模块:上述模块生成的表达式只是初步的表达式,运算功能是利用后缀表达式来实现的,生成后缀表达式后再将表达式的所有数值转化为分数形式,统一方便计算。为保证该过程中不出现负数运算,凡是进行减法运算的操作,都会对运算结果进行检验,一旦出现负数则丢弃当前表达式,直到再次生成的表达式符合要求,同时在此过程进行表达式的重复判断,将每一个当前非负表达式与已生成表达式进行查重检验,满足条件则加入Arraylist中,同时保存运算结果。
- 查重检验:将后缀表达式转换为查重表达式,查重表达式的结果为运算符在先,后面跟着该运算符的操作数,例如(1+2)*3-4,后缀表达式为:12+3*4-,按照查重表达式的结构为:+12*3-4,查重过程中只需要判断查重表达式是否一致,或者在查重表达式中第一个字符'+'或'*'的情况下后续的两个操作数交换位置后是否一致即可。也就是说+12*3-4与+21*3-4的表达式是一致的。举个表达式不重复的例子:1+2+3和3+2+1,查重表达式分别为+12+3和+32+1,查重表达式不相同,即使交换'+'后面的两个操作数也无法一致,故这两个表达式不重复。
- 运算结果检验模块:将最终符合要求的表达式存入当前目录下的Question.txt文件,正确答案保存在Answer.txt文件中,并对运算结果进行检。
![](https://img2018.cnblogs.com/blog/1673905/201910/1673905-20191017010715078-641074953.jpg)
![](https://img2018.cnblogs.com/blog/1673905/201910/1673905-20191017005013098-627980932.png)
1 package Calculation; 2 3 import java.util.ArrayList; 4 import java.util.Random; 5 import java.util.Scanner; 6 7 8 public class Ran_Expression { //随机生成初步的表达式 9 10 11 12 public static char[] ysf={'+','-','*','÷'}; 13 public static String exp_str;//四则运算表达式 14 15 //获取输入 16 public static String getScanner(){ 17 Scanner scan=new Scanner(System.in); 18 String input=scan.nextLine(); 19 scan.close(); 20 return input; 21 } 22 23 24 //随机获取运算符+ - * ÷ 25 public static char getysf(){ 26 Random ran=new Random(); 27 int ysfNum=ran.nextInt(4); 28 return ysf[ysfNum]; 29 } 30 31 /** 32 * 获取操作数 33 * @param range 数值范围 34 * @return 35 */ 36 public static String getNumber(int range){ 37 Random ran=new Random(); 38 int index=ran.nextInt(3); 39 String num=""; 40 41 /** 42 * 随机获取数字,0获取自然数,1获取真分数,2获取带分数 43 */ 44 if(index==0){//自然数 45 Random ran0=new Random(); 46 num=ran0.nextInt(range-1)+1+""; 47 } 48 if(index==1){//真分数 49 Random ran1=new Random(); 50 int fenmu=ran1.nextInt(range-2)+2;//分母[2,range) 51 int fenzi=ran1.nextInt(fenmu-1)+1;//分子 52 num=fenzi+"/"+fenmu+""; 53 } 54 if(index==2){//带分数 55 Random ran2=new Random(); 56 int leftNum=ran2.nextInt(range-1)+1;//左整数部分 57 int rightFM=ran2.nextInt(range-2)+2;//右真分数部分-分母[2,range) 58 int rightFZ=ran2.nextInt(rightFM-1)+1;//右真分数部分-分子 59 num=leftNum+"'"+rightFZ+"/"+rightFM+""; 60 } 61 return num; 62 } 63 64 /** 65 * 去表达式最前和最后的括号 66 * @param str表达式 67 * @return 68 */ 69 public static String deleteKuoHao(String str){ 70 if((str.substring(0, 1).equals("(")) && (str.substring(str.length()-1).equals(")"))){ 71 str=str.substring(1, str.length()-1); 72 } 73 return str; 74 } 75 76 77 //生成四则运算表达式 78 //range题目中操作数的范围 79 public static ArrayList<String> creatAc(int range){ 80 Random ran4=new Random(); 81 ArrayList<String> list=new ArrayList<String>();//存放每个表达式中的运算符和操作数 82 boolean zuoKuoHao=false;//左括号 83 boolean youKuoHao=false;//右括号 84 boolean tem=false; 85 int ysfNum=ran4.nextInt(3)+1;//每个表达式运算符个数1-3个 86 exp_str=""; 87 88 //------------开始生成-------------- 89 for(int j=0;j<ysfNum;j++){ 90 91 //决定是否加入左括号 92 if(!zuoKuoHao && ran4.nextBoolean()){ 93 exp_str+="("; 94 list.add("("); 95 zuoKuoHao=true; 96 } 97 String sz1=getNumber(range); 98 exp_str+=sz1; 99 list.add(sz1); 100 //决定是否加入右括号 101 if(zuoKuoHao && !youKuoHao && tem){ 102 if(ran4.nextBoolean()){ 103 exp_str+=")"; 104 list.add(")"); 105 youKuoHao=true; 106 } 107 } 108 char char1=getysf(); 109 exp_str+=char1; 110 list.add(char1+""); 111 if(zuoKuoHao){ 112 tem=true; 113 } 114 } 115 String sz2=getNumber(range); 116 exp_str+=sz2; 117 list.add(sz2); 118 if(zuoKuoHao && !youKuoHao){ 119 exp_str+=")"; 120 list.add(")"); 121 } 122 exp_str=deleteKuoHao(exp_str);//去掉开头和结尾均为括号 123 //------------结束生成-------------- 124 125 System.out.println("生成中,请稍等:"+exp_str); 126 return list; 127 128 } 129 130 131 132 }
1 package Calculation; 2 3 import java.util.ArrayList; 4 import java.util.Stack; 5 6 7 public class After_Expression { //生成后缀表达式 8 /** 9 * 将中序表达式转换成后序表达式 10 * @param str 生成的中序表达式 11 */ 12 public static Stack<String> toAfter_Expression(ArrayList<String> list){ 13 Stack<String> stack=new Stack<String>();//栈 14 Stack<String> right=new Stack<String>();//右序表达式 15 String ysf;//运算符 16 17 for(int i=0;i<list.size();i++){ 18 String ch=list.get(i); 19 if(isysf(ch)){//当前字符为运算符 20 if(stack.empty()==true || ch=="("){//栈为空或者为(直接入栈 21 stack.push(ch); 22 }else{//非栈空、非左括号 23 if(ch==")"){//如果为) 24 while(true){//将(后的运算符出栈并加到后续表达式中 25 if((!stack.empty()) && (!stack.peek().equals("("))){ 26 ysf=stack.pop(); 27 right.push(ysf); 28 }else{ 29 if(!stack.empty())//如果栈顶元素为( 30 stack.pop(); 31 break; 32 } 33 } 34 }else{//非栈空、非左括号、非右括号 35 while(true){//栈不为空,优先级低 36 if(!stack.empty() && priority(ch,stack.peek())){ 37 ysf=stack.pop()+""; 38 if(!ysf.equals("(")){ 39 right.push(ysf); 40 } 41 }else{ 42 break; 43 } 44 } 45 stack.push(ch+""); 46 } 47 } 48 49 }else{ 50 right.push(ch+"");//操作数 51 } 52 } 53 while(!stack.empty()){ 54 ysf=stack.pop()+""; 55 if(!ysf.equals("(")) 56 right.push(ysf); 57 } 58 return right; 59 } 60 61 62 // 判断是否为运算符 63 public static boolean isysf(String ch){ 64 if((ch.equals("+"))||(ch.equals("-"))||(ch.equals("*"))||(ch.equals("÷"))||(ch.equals("("))||(ch.equals(")"))) 65 return true; 66 else 67 return false; 68 } 69 70 /** 71 * 设置运算符的优先级别 72 * @param ysfout当前中序表达式字符 73 * @param ysfin栈中字符 74 * @return 75 */ 76 public static boolean priority(String ysfout, String ysfin) { 77 int m = -1, n = -1; 78 String a_ysf[][] = { { "+", "-", "*", "÷", "(", ")" }, 79 { "+", "-", "*", "÷", "(", ")" } }; 80 int first[][] = { { 1, 1, 2, 2, 2, 0 }, { 1, 1, 2, 2, 2, 0 }, 81 { 1, 1, 1, 1, 2, 0 }, { 1, 1, 1, 1, 2, 0 }, 82 { 2, 2, 2, 2, 2, 0 }, { 2, 2, 2, 2, 2, 2 } }; 83 for (int i = 0; i < 6; i++) { 84 if (ysfin.equalsIgnoreCase(a_ysf[0][i])) 85 m = i; 86 } 87 for (int i = 0; i < 6; i++) { 88 if (ysfout.equalsIgnoreCase(a_ysf[1][i])) 89 n = i; 90 } 91 if (m == -1 && n == -1) 92 return false; 93 else if (m == -1 && n != -1) 94 return false; 95 else if (m != -1 && n == -1) 96 return true; 97 else if (first[m][n] == 1) { 98 return true; 99 } else 100 return false; 101 } 102 103 }
1 package Calculation; 2 3 import java.util.Stack; 4 5 public class CaoZuoShu_handle { 6 7 8 //该类将后续表达式stack转化为有分子分母的后续表达式 9 //存于Calcul_Expression对象的calculatorStack中 10 11 Stack<Calcul_Expression> posfixStack; 12 13 public CaoZuoShu_handle(Stack<String> stack) { 14 Stack<Calcul_Expression> stack1 = new Stack<>();//中间栈 15 Stack<Calcul_Expression> stack2 = new Stack<>();//中间栈 16 while(!stack.isEmpty()){ 17 String string = stack.pop(); 18 //运算符直接进栈 19 if(string.equals("+")||string.equals("-")||string.equals("*")||string.equals("÷")){ 20 Calcul_Expression calcul_exp = new Calcul_Expression(true,string); 21 stack1.push(calcul_exp); 22 } 23 else if(!string.contains("/")){ 24 string = string + "/1"; 25 Calcul_Expression node = new Calcul_Expression(false,string); 26 stack1.push(node); 27 } 28 else { 29 Calcul_Expression calculator = new Calcul_Expression(false,string); 30 stack1.push(calculator); 31 } 32 } 33 for(Calcul_Expression c:stack1){ 34 stack2.push(c); 35 } 36 this.posfixStack = stack2; 37 38 } 39 40 41 }
1 package Calculation; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 import java.util.Stack; 6 7 public class Calcul_Expression { //计算表达式 8 9 10 11 private static final int String = 0; 12 Integer fenzi;//分子 13 Integer fenmu;//分母 14 boolean isysf; 15 String ysf; 16 Calcul_Expression lChild; 17 Calcul_Expression rChild; 18 19 20 //运算符构造方法 21 public Calcul_Expression(boolean isysf,Integer num,Integer den) { 22 this.isysf = isysf; 23 this.fenmu = den; 24 this.fenzi = num; 25 26 } 27 28 public Calcul_Expression(boolean isysf,String stackElement) { 29 if(isysf == true){//为运算符 30 this.isysf = true; 31 this.ysf = stackElement; 32 } 33 else if (isysf == false && stackElement.contains("'")){//为带分数 34 String[] split1 = stackElement.split("'"); 35 String[] split2 = split1[1].split("\\/"); 36 this.fenzi = Integer.parseInt(split1[0])*Integer.parseInt(split2[1]) 37 + Integer.parseInt(split2[0]); 38 this.fenmu = Integer.parseInt(split2[1]); 39 } 40 else if(isysf == false && (!stackElement.contains("'"))){//为分数 41 String[] s = stackElement.split("\\/"); 42 this.fenzi = Integer.parseInt(s[0]); 43 this.fenmu = Integer.parseInt(s[1]); 44 } 45 } 46 47 48 49 public Calcul_Expression() { 50 } 51 52 //根据后缀表达式(分子分母形式)计算 53 //返回运算结果存于stack2中 54 public Stack<Calcul_Expression> calculate(Stack<Calcul_Expression> stackOld){ 55 Stack<Calcul_Expression> stack=(Stack<Calcul_Expression>) stackOld.clone(); 56 Stack<Calcul_Expression> stack2 = new Stack<>(); 57 Calcul_Expression calculator; 58 while(!stack.isEmpty()){ 59 if(!(calculator = stack.pop()).isysf){//操作数直接入栈 60 stack2.push(calculator); 61 } 62 else if(calculator.isysf){//若为运算符 63 64 //每次去除栈顶两个元素 65 Calcul_Expression calculator1 = stack2.pop(); 66 Calcul_Expression calculator2 = stack2.pop(); 67 68 switch (calculator.ysf) { 69 case "+": 70 stack2.push(calculator.add(calculator2, calculator1)); 71 break; 72 73 case "-": 74 Calcul_Expression res=calculator.sub(calculator2, calculator1); 75 if(res.fenzi>0){ 76 stack2.push(res); 77 }else{ 78 res.ysf="#"; 79 stack2.push(res); 80 return stack2; 81 } 82 stack2.push(calculator.sub(calculator2, calculator1)); 83 break; 84 85 case "*": 86 stack2.push(calculator.mul(calculator2, calculator1)); 87 break; 88 89 case "÷": 90 stack2.push(calculator.div(calculator2, calculator1)); 91 break; 92 93 default: 94 break; 95 } 96 97 } 98 } 99 return stack2; 100 } 101 102 //加法 103 public Calcul_Expression add(Calcul_Expression calculator1,Calcul_Expression calculator2) { 104 Integer num = calculator1.fenzi*calculator2.fenmu + 105 calculator2.fenzi*calculator1.fenmu; 106 Integer den = calculator1.fenmu*calculator2.fenmu; 107 int g = gcd(num, den); 108 Calcul_Expression calculator = new Calcul_Expression(false, num/g, den/g); 109 return calculator; 110 } 111 112 //减法 113 public Calcul_Expression sub(Calcul_Expression calculator1,Calcul_Expression calculator2) { 114 Integer num = calculator1.fenzi*calculator2.fenmu - 115 calculator2.fenzi*calculator1.fenmu; 116 Integer den = calculator1.fenmu*calculator2.fenmu; 117 int g = gcd(num, den); 118 Calcul_Expression calculator = new Calcul_Expression(false, num/g, den/g); 119 return calculator; 120 } 121 122 //乘法 123 public Calcul_Expression mul(Calcul_Expression calculator1,Calcul_Expression calculator2) { 124 Integer num = calculator1.fenzi*calculator2.fenzi; 125 Integer den = calculator1.fenmu*calculator2.fenmu; 126 int g = gcd(num, den); 127 Calcul_Expression calculator = new Calcul_Expression(false, num/g, den/g); 128 return calculator; 129 } 130 131 //除法 132 public Calcul_Expression div(Calcul_Expression calculator1,Calcul_Expression calculator2) { 133 Integer num = calculator1.fenzi*calculator2.fenmu; 134 Integer den = calculator1.fenmu*calculator2.fenzi; 135 int g = gcd(num, den); 136 Calcul_Expression calculator = new Calcul_Expression(false, num/g, den/g); 137 return calculator; 138 } 139 140 //最大公约数 141 public int gcd(int a, int b){ 142 int m = Math.max(Math.abs(a), Math.abs(b)); 143 int n = Math.min(Math.abs(a), Math.abs(b)); 144 int r; 145 while(n!=0){ 146 r = m % n; 147 m = n; 148 n = r; 149 } 150 return m; 151 } 152 153 //比较两个分数数大小 154 /** 155 * 156 * @return f1 > f2 返回 2 157 * f1 = f2返回1 158 * f1 < f2返回-1 159 * 其他 返回0 160 */ 161 public int compareFraction(Calcul_Expression f1,Calcul_Expression f2) { 162 Calcul_Expression node = new Calcul_Expression(); 163 164 if (f1.isysf||f2.isysf) { 165 System.out.println("请输入数字进行比较!"); 166 return 0; 167 } 168 Calcul_Expression compare = node.sub(f1, f2);//f1 - f2 结果为Calcul_Expression类型 169 int result = compare.fenzi/compare.fenmu;//f1 - f2的结果 170 if (result == 0) { 171 return 1; 172 } 173 else if (result > 0) { 174 return 2; 175 } 176 else if (result < 0) { 177 return -1; 178 } 179 180 return 0; 181 } 182 183 /** 184 * 185 * @param o1 186 * @param o2 187 * @return o1 > o2 return 2 188 * o1 = o2 return 1 189 * o1 < o2 return -1 190 * 其他 return 0 191 */ 192 public int compareysf(Calcul_Expression o1,Calcul_Expression o2) { 193 if (!o1.isysf||!o2.isysf) { 194 System.out.println("请输入正确运算符!"); 195 return 0; 196 } 197 HashMap<String, Integer> priMap = new HashMap<>(); 198 priMap.put("+", 0); 199 priMap.put("-", 0); 200 priMap.put("*", 1); 201 priMap.put("÷", 1); 202 203 if (priMap.get(o1.ysf) > priMap.get(o2.ysf)) { 204 //o1 高于 o2 205 return 2; 206 } 207 else if (priMap.get(o1.ysf) == priMap.get(o2.ysf)) { 208 //o1 低于o2 209 return 1; 210 } 211 else if (priMap.get(o1.ysf) < priMap.get(o2.ysf)) { 212 //o1等于o2 213 return 1; 214 } 215 return 0; 216 } 217 218 //假分数转带分数输出 219 public ArrayList<String> imTomix(ArrayList<Calcul_Expression> answerList) { 220 ArrayList<String> arrayList = new ArrayList<>(); 221 for (int i = 0; i < answerList.size(); i++) { 222 if (answerList.get(i).isysf) { 223 System.out.println("这个结果算错了!"); 224 } 225 else if (answerList.get(i).fenmu == 1){//分母为1,分数= 分子的值 226 arrayList.add(answerList.get(i).fenzi + ""); 227 } 228 else if ((answerList.get(i).fenzi == 0) ||(answerList.get(i).fenzi == 0)) {//若分子为0,则分数为0 229 arrayList.add(answerList.get(i).fenzi + ""); 230 } 231 else if (answerList.get(i).fenzi == answerList.get(i).fenmu) {//分子等于分母,answer=1 232 arrayList.add(1+""); 233 } 234 else if (answerList.get(i).fenzi%answerList.get(i).fenmu == 0) {//分子能整除分母 235 arrayList.add(answerList.get(i).fenzi/answerList.get(i).fenmu + ""); 236 } 237 else if((answerList.get(i).fenmu!=0)&&answerList.get(i).fenzi/answerList.get(i).fenmu> 1) {//假分数,转带分数 238 arrayList.add(answerList.get(i).fenzi/answerList.get(i).fenmu + "'" 239 + answerList.get(i).fenzi%answerList.get(i).fenmu + "/" + answerList.get(i).fenmu); 240 } 241 else { 242 arrayList.add(answerList.get(i).fenzi + "/" + answerList.get(i).fenmu + ""); 243 } 244 } 245 return arrayList; 246 } 247 248 249 250 251 }
1 package Calculation; 2 3 import java.util.ArrayList; 4 import java.util.Stack; 5 6 /** 7 * 构造方法:生成查重表达式 8 * @author LHY 9 * 10 */ 11 public class Repeat { 12 /** 13 * @param profixStack 后缀表达式栈 14 */ 15 public Stack<Calcul_Expression> checkRepeat(Stack<Calcul_Expression> profixStack) { 16 // TODO Auto-generated constructor stub 17 Stack<Calcul_Expression> numberStack = new Stack<>(); //构造一个中间栈,存放数字 18 Stack<Calcul_Expression> checkStack = new Stack<>(); //存放查重表达式栈 19 20 // System.out.println(1); 21 Calcul_Expression bookNode = new Calcul_Expression(true, 0,0); 22 // System.out.println(2); 23 Calcul_Expression node1 = new Calcul_Expression(); 24 Calcul_Expression node2 = new Calcul_Expression(); 25 while(!profixStack.isEmpty()){//扫描后缀表达式栈直至其为空 26 Calcul_Expression proStack_top = profixStack.pop();//开始扫描第一个 27 if (!proStack_top.isysf&&!(proStack_top.fenzi==0&&proStack_top.fenmu==0)) {//若后缀表达式栈顶元素为数字。若非#则进numberStack 28 numberStack.push(proStack_top); 29 // System.out.println(proStack_top); 30 } 31 // else if (proStack_top.isOperator&&proStack_top.numerator==0&&proStack_top.denominator==0) { 32 // numberStack.pop(); 33 // } 34 else if (proStack_top.isysf) {//后缀表达式栈顶为运算符,则进checkStack,再pop两个数字,并把#压进数字 35 checkStack.push(proStack_top); 36 if (numberStack.size() > 1) { 37 if (!(node1=numberStack.pop()).isysf&&!(node1.fenzi==0)&&!(node1.fenmu==0)) {//非# 38 checkStack.push(node1); 39 } 40 if (!(node2=numberStack.pop()).isysf&&!(node2.fenzi==0)&&!(node2.fenmu==0)) { 41 checkStack.push(node2); 42 } 43 } 44 numberStack.push(bookNode); 45 } 46 47 }//end while 48 System.out.println("size"+checkStack.size()); 49 for(Calcul_Expression node:checkStack){ 50 if (node.isysf) { 51 System.out.print(node.ysf + " "); 52 }else if(!node.isysf){ 53 System.out.print(node.fenzi + "/" + node.fenmu + " "); 54 } 55 } 56 return checkStack; 57 58 } 59 60 public boolean IsRepeat(Stack<Calcul_Expression> exp1,Stack<Calcul_Expression> exp2){ 61 Repeat repeat=new Repeat(); 62 //转成查重表达式 63 ArrayList<Calcul_Expression> temp=new ArrayList<Calcul_Expression>();//中间存放栈1 64 Calcul_Expression tempNode=new Calcul_Expression();//中间交换结点 65 Stack<Calcul_Expression> checkRepeat1=repeat.checkRepeat(exp1); 66 Stack<Calcul_Expression> checkRepeat2=repeat.checkRepeat(exp2); 67 Stack<Calcul_Expression> newStack=new Stack<Calcul_Expression>();//交换后的新栈 68 int lengthRe1=checkRepeat1.size(); 69 int lengthRe2=checkRepeat2.size(); 70 System.out.println(1); 71 if(lengthRe1!=lengthRe2) return false;//若长度不相等,则表达式一定不同 72 System.out.println(2); 73 for(Calcul_Expression n:checkRepeat1){ 74 temp.add(n); 75 } 76 if (this.isEqual(checkRepeat1, checkRepeat2)) {//完全一样则返回true 77 return true; 78 } 79 80 if(temp.get(0).ysf.equals("+")||temp.get(0).ysf.equals("*")){//只有加或乘的情况才可能出现 交换左右操作数当做重复的表达式 81 tempNode=temp.get(1); 82 temp.set(1, temp.get(2)); 83 temp.set(2, tempNode); 84 } 85 for(Calcul_Expression p:temp){ 86 newStack.push(p); 87 } 88 if(this.isEqual(newStack, checkRepeat2)) return true;//若交换后也相等则重复 89 System.out.println(3); 90 return false; 91 } 92 93 public boolean isEqual(Stack<Calcul_Expression> stack1,Stack<Calcul_Expression> stack2) { 94 Stack<Calcul_Expression> s1 = new Stack<>(); 95 Stack<Calcul_Expression> s2 = new Stack<>(); 96 97 Calcul_Expression s1_top; 98 Calcul_Expression s2_top; 99 for(Calcul_Expression node1:stack1){ 100 s1.push(node1); 101 } 102 for(Calcul_Expression node2:stack2){ 103 s2.push(node2); 104 } 105 106 while (!s1.isEmpty()&&!s2.isEmpty()) { 107 s1_top = s1.pop(); 108 s2_top = s2.pop(); 109 if (s1_top.isysf) {//若s1栈顶为运算符 110 if (s2_top.isysf&&(!s2_top.ysf.equals(s1_top.ysf))) {//s2都为运算符但s1不等于s2 111 return false; 112 } 113 else if (!s2_top.isysf) {//s1为运算符,s2非运算符 114 return false; 115 } 116 } 117 else if (!s1_top.isysf) {//若s1操作数 118 if (s2_top.isysf) {//s2为运算符 119 return false; 120 } 121 else if (!s2_top.isysf&&(s2_top.compareFraction(s1_top, s2_top)!=1)) {//s2为操作数但不等于s1 122 return false; 123 } 124 } 125 126 } 127 return true; 128 } 129 }
int count=0; ArrayList<String> finalExp=new ArrayList<>();//最终所有表达式 ArrayList<Calcul_Expression> finalRes=new ArrayList<>();//最终所有结果(假分数) ArrayList<String> realRes =new ArrayList<>();//最终所有结果(真分数) ArrayList<Stack<Calcul_Expression>> checkArray=new ArrayList<>();//查重存放数组 Repeat repeat=new Repeat(); do { boolean flag=false; Stack<String> ac=new Stack<String>(); ac=After_Expression.toAfter_Expression(Ran_Expression.creatAc(range));//没带分母的后缀表达式 CaoZuoShu_handle handle=new CaoZuoShu_handle(ac);//带分母的后缀表达式 Calcul_Expression node=new Calcul_Expression(); Stack<Calcul_Expression> stack=new Stack<Calcul_Expression>(); stack=node.calculate(handle.posfixStack);//计算结果 if(stack.peek().ysf!="#"&&count==0){//非负,第一个表达式 checkArray.add(handle.posfixStack); finalExp.add(Ran_Expression.exp_str); finalRes.add(stack.peek()); count++; } if(stack.peek().ysf!="#"&&count>0){//非负,第二个表达式开始 for(Stack<Calcul_Expression> p:checkArray){ if(repeat.isEqual(p, handle.posfixStack)){ flag=true; } } if(!flag){ checkArray.add(handle.posfixStack); finalExp.add(Ran_Expression.exp_str); finalRes.add(stack.peek()); count++; } } } while (count!=number); Calcul_Expression transNode=new Calcul_Expression(); realRes=transNode.imTomix(finalRes); for (int i = 0; i < finalExp.size(); i++) { System.out.println("第"+i+"题:"+finalExp.get(i)); } for (int i = 0; i < realRes.size(); i++) { System.out.println("第"+i+"题答案:"+realRes.get(i)); } System.out.println("答案真正长度"+finalRes.size());
package Calculation; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import javax.imageio.spi.RegisterableService; public class FileRW { /** * 将题目和答案写出在txt文件中 * @param expList 题目集合 * @param answerList 答案集合 * @return true 成功 * false 失败 */ public boolean fileWrite(ArrayList<String> expList,ArrayList<Calcul_Expression> answerList) { ArrayList<String> outList = new ArrayList<>(); if (expList.size()!=answerList.size()) { System.out.println("答案与题目数目不匹配!"); return false; } for (int i = 0; i < expList.size(); i++) { System.out.println(); outList.add(expList.get(i) + " = " +answerList.get(i).fenzi + "/"+ answerList.get(i).fenmu); } //开始写入文件 try { BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt")); for(String s:outList){ bw.write(s); bw.newLine(); bw.flush(); } bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return true; } /** * 把题目写出到文件 * @param expList * @return */ public File writeQ(ArrayList<String> expList) { int count = 1; File file = new File("Question.txt"); try { FileWriter fWriter = new FileWriter(file); BufferedWriter bw = new BufferedWriter(fWriter); for(String s:expList){ bw.write( count++ + "." +s); bw.newLine(); bw.flush(); } bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return file; } /** * 把答案写出到文件 * @param answerList * @return * @throws IOException */ public File writeA(ArrayList<String> answerList) throws IOException { int count = 1; File file = new File("Answer.txt"); FileWriter fWriter = new FileWriter(file); try { BufferedWriter bw = new BufferedWriter(fWriter); for(String s:answerList){ bw.write( count++ + "." +s); bw.newLine(); bw.flush(); } bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return file; } /** * * @param answerFile 待检测文件 * @param answerList 正确答案文件 * @return */ public File checkAnswer(File answerFile,File answerList) { try { BufferedReader rightReader = new BufferedReader(new FileReader(answerList)); BufferedReader anserReader = new BufferedReader(new FileReader(answerFile)); String rightString = null; String answerString = null; int right = 0; int wrong = 0; int line = 1; String Rnumber=""; String Wnumber=""; //比较对错 while((rightString=rightReader.readLine())!=null&&(answerString=anserReader.readLine())!=null){ if(rightString.equals(answerString)){ right ++; if (Rnumber.equals("")) { Rnumber = Rnumber +line; } else{ Rnumber = Rnumber + ","+line; } } else { System.out.println(rightString); System.out.println(answerString); wrong++; if (Wnumber.equals("")) { Wnumber = Wnumber +line; }else{ Wnumber = Wnumber + "," +line; } } line++; } //写入到answerfile中 BufferedWriter bw = new BufferedWriter(new FileWriter(answerFile, true)); bw.newLine(); bw.write("right: "+ right + " " + "("+ Rnumber +")" + ";"); bw.newLine(); bw.write("wrong: "+ wrong + " " + "("+ Wnumber + ")"+ ";"); bw.flush(); bw.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return answerFile; } }
![](https://img2018.cnblogs.com/blog/1673905/201910/1673905-20191017012239822-15236300.png)
代码覆盖率:
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
45 |
47 |
· Estimate |
· 估计这个任务需要多少时间 |
45 |
47 |
Development |
开发 |
1405 |
1492 |
· Analysis |
· 需求分析 (包括学习新技术) |
80 |
95 |
· Design Spec |
· 生成设计文档 |
40 |
36 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
45 |
55 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
35 |
30 |
· Design |
· 具体设计 |
120 |
107 |
· Coding |
· 具体编码 |
960 |
1050 |
· Code Review |
· 代码复审 |
50 |
35 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
75 |
84 |
Reporting |
报告 |
180 |
235 |
· Test Report |
· 测试报告 |
120 |
180 |
· Size Measurement |
· 计算工作量 |
20 |
20 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
40 |
35 |
合计 |
|
1630 |
1774 |
这次结对编程项目相比上次的个人项目,整体的完成过程要更为复杂一些,也更加耗时间。做个人项目的时候,可以自己按照自己整体的代码构架和实现思路去走,在类的创建和实现上,也比较自由。而本次结对编程,就要求我们在团队协作这一块上一定要做得好,两个人一起实现同一个项目并不是一件简单的事情。我们在一开始对项目设计的讨论中,由于没有很明确地达成一致的思路,可以说只是商定了一个大概的框架,所以真正在分工实现项目的过程中,难免出现了一些问题,在最后联结双方的项目工程时发现无法完全契合双方的各种实现类。于是,在经过第二轮的讨论交流和实践修改后,才得以完成本次结对编程项目,这让我们都意识到小组交流和相互更新进度这些合作事宜的重要性。这次项目也让我们两个人从中学到了很多,明确了彼此的一些知识盲区,相信有了结对编程的经验后,在后续的团队编程项目中我们会做得更好。