四则运算表达式
1.Github项目地址:https://github.com/Liang9028/myapp
梁鸿健 3118005007 李玉 3118005006
2.预估PSP
|
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
|
Planning |
计划 |
30 |
|
|
· Estimate |
· 估计这个任务需要多少时间 |
1200 |
|
|
Development |
开发 |
600 |
|
|
· Analysis |
· 需求分析 (包括学习新技术) |
60 |
|
|
· Design Spec |
· 生成设计文档 |
20 |
|
|
· Design Review |
· 设计复审 (和同事审核设计文档) |
20 |
|
|
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
60 |
|
|
· Design |
· 具体设计 |
120 |
|
|
· Coding |
· 具体编码 |
60 |
|
|
· Code Review |
· 代码复审 |
60 |
|
|
· Test |
· 测试(自我测试,修改代码,提交修改) |
60 |
|
|
Reporting |
报告 |
30 |
|
|
· Test Report |
· 测试报告 |
30 |
|
|
· Size Measurement |
· 计算工作量 |
20 |
|
|
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
30 |
|
|
合计 |
|
1200 |
|
3.设计实现过程

3.设计实现过程
4.关键代码说明
运算
public class Fraction { public boolean isNumber(String a) {//判断一个String是否是纯数字 if(a==null) return false; return a.matches("(-|\\+)?\\d+"); } public String produce(){//产生一个分数 int i=(int)(Math.random()*100)+1; int j=(int)(Math.random()*100)+1; if(i%j==0) return String.valueOf(i/j); int n=i/j; String fenshu=n+"'"+(i-n*j)+"/"+j; return simplify(fenshu); } public String simplify(String a) {//化简 if(isNumber(a)) return a; int i,j,n; n=Integer.parseInt(a.split("\\'")[0]);//取整数 String b[]=a.split("\\'")[1].split("\\/"); //先将n'x/y以'分隔为两部分后部分再以“/”为分隔,将"x/y"分隔为 a[0]="x" a[1]="y" i=Integer.parseInt(b[0]); //将一个可以转化为整形的字符串装换成整形 j=Integer.parseInt(b[1]); if(i==0||j==0) return String.valueOf(n); if(i<0&&j<0) i=Math.abs(i); j=Math.abs(j); if(i<0||j<0) { i=-Math.abs(i); j=Math.abs(j); for( ;i<0;n--) { i=i+j; } } if(i==0||j==0) return String.valueOf(n); int d=divisor(i,j); n=n+i/j; return n+"'"+(i/d-i/j*j/d)+"/"+(j/d); } public int divisor(int x,int y) {//求两个数的最大公约数 int i,j; if(x<=y) i=x; else i=y; for(j=0;j==0;i--) { if(x%i==0&&y%i==0) j=1; } return i+1; } public String add(Object c,Object d) {//Object加法 int s1=0,s2=0; if(c instanceof Integer) s1=1; if(d instanceof Integer) s2=1; switch(s1+s2*10) { case 10: return add(c.toString(),(int)d); case 1: return add(d.toString(),(int)c); case 11: return add((int)c,(int)d); case 0: return add(c.toString(),d.toString()); } return null; } public String add(String c,String d) {//分数加法 if(isNumber(c)||isNumber(simplify(c))) return add(d,Integer.parseInt(simplify(c))); if(isNumber(d)||isNumber(simplify(d))) return add(c,Integer.parseInt(simplify(d))); int s1,s2,s3,s4,n1,n2; n1=Integer.parseInt(c.split("\\'")[0]); n2=Integer.parseInt(d.split("\\'")[0]); String a[]=c.split("\\'")[1].split("\\/"); String b[]=d.split("\\'")[1].split("\\/"); s1=Integer.parseInt(a[0]); s2=Integer.parseInt(a[1]); s3=Integer.parseInt(b[0]); s4=Integer.parseInt(b[1]); return simplify(0+"'"+((n1*s2+s1)*s4+(n2*s4+s3)*s2)+"/"+(s2*s4)); } public String add(String c,int d) {//混合加法 if(isNumber(c)||isNumber(simplify(c))) return add(Integer.parseInt(simplify(c)),d); int s1,s2,n; n=Integer.parseInt(c.split("\\'")[0]); String a[]=c.split("\\'")[1].split("\\/"); s1=Integer.parseInt(a[0]); s2=Integer.parseInt(a[1]); return simplify(0+"'"+((n*s2+s1)+d*s2)+"/"+s2); } public String add(int c,int d) {//整数加法 return String.valueOf(c+d); } public String minus(Object c,Object d) {// int s1=0,s2=0; if(c instanceof Integer) s1=1; if(d instanceof Integer) s2=1; switch(s1+s2*10) { case 10: return minus(c.toString(),(int)d); case 1: return minus((int)c,d.toString() ); case 11: return minus((int)c,(int)d); case 0: return minus(c.toString(),d.toString()); } return null; } public String minus(String c,int d) {//分数减法 if(isNumber(c)||isNumber(simplify(c))) return minus(Integer.parseInt(simplify(c)),d); int s1,s2,n; n=Integer.parseInt(c.split("\\'")[0]); String a[]=c.split("\\'")[1].split("\\/"); s1=Integer.parseInt(a[0]); s2=Integer.parseInt(a[1]); return simplify(0+"'"+((n*s2+s1)-d*s2)+"/"+s2); } public String minus(int c,String d) {//分数减法 if(isNumber(d)||isNumber(simplify(d))) return minus(c,Integer.parseInt(simplify(d))); int s1,s2,n; n=Integer.parseInt(d.split("\\'")[0]); String a[]=d.split("\\'")[1].split("\\/"); s1=Integer.parseInt(a[0]); s2=Integer.parseInt(a[1]); return simplify(0+"'"+(c*s2-(n*s2+s1))+"/"+s2); } public String minus(String c,String d) {//分数减法 if(isNumber(c)||isNumber(simplify(c))) return minus(Integer.parseInt(simplify(c)),d); if(isNumber(d)||isNumber(simplify(d))) return minus(c,Integer.parseInt(simplify(d))); int s1,s2,s3,s4,n1,n2; n1=Integer.parseInt(c.split("\\'")[0]); n2=Integer.parseInt(d.split("\\'")[0]); String a[]=c.split("\\'")[1].split("\\/"); String b[]=d.split("\\'")[1].split("\\/"); s1=Integer.parseInt(a[0]); s2=Integer.parseInt(a[1]); s3=Integer.parseInt(b[0]); s4=Integer.parseInt(b[1]); return simplify(0+"'"+((n1*s2+s1)*s4-(n2*s4+s3)*s2)+"/"+(s2*s4)); } public String minus(int c,int d) {//分数减法 return String.valueOf(c-d); } public String multiply(Object c,Object d) {//分数乘法 int s1=0,s2=0; if(c instanceof Integer) s1=1; if(d instanceof Integer) s2=1; switch(s1+s2*10) { case 10: return multiply(c.toString(),(int)d); case 1: return multiply(d.toString(),(int)c); case 11: return multiply((int)c,(int)d); case 0: return multiply(c.toString(),d.toString()); } return null; } public String multiply(String c,String d) {//分数乘法 if(isNumber(c)||isNumber(simplify(c))) return multiply(d,Integer.parseInt(simplify(c))); if(isNumber(d)||isNumber(simplify(d))) return multiply(c,Integer.parseInt(simplify(d))); int s1,s2,s3,s4,n1,n2; n1=Integer.parseInt(c.split("\\'")[0]); n2=Integer.parseInt(d.split("\\'")[0]); String a[]=c.split("\\'")[1].split("\\/"); String b[]=d.split("\\'")[1].split("\\/"); s1=Integer.parseInt(a[0]); s2=Integer.parseInt(a[1]); s3=Integer.parseInt(b[0]); s4=Integer.parseInt(b[1]); return simplify(0+"'"+((n1*s2+s1)*(n2*s4+s3))+"/"+(s2*s4)); } public String multiply(String c,int d) {//混合乘法 if(isNumber(c)||isNumber(simplify(c))) return multiply(Integer.parseInt(simplify(c)),d); int s1,s2,n1; n1=Integer.parseInt(c.split("\\'")[0]); String a[]=c.split("\\'")[1].split("\\/"); s1=Integer.parseInt(a[0]); s2=Integer.parseInt(a[1]); return simplify(0+"'"+((n1*s2+s1)*d*s2)+"/"+(s2*s2)); } public String multiply(int c,int d) {//整数乘法 return String.valueOf(c*d); } public String divide(Object c,Object d) {//除法 int s1=0,s2=0; if(c instanceof Integer) s1=1; if(d instanceof Integer) s2=1; switch(s1+s2*10) { case 10: return divide(c.toString(),(int)d); case 1: return divide((int)c,d.toString()); case 11: return divide((int)c,(int)d); case 0: return divide(c.toString(),d.toString()); } return null; } public String divide(String c,String d) {//分数除法 if(isNumber(c)||isNumber(simplify(c))) return divide(Integer.parseInt(simplify(c)),d); if(isNumber(d)||isNumber(simplify(d))) return divide(c,Integer.parseInt(simplify(d))); int s1,s2,n2; n2=Integer.parseInt(d.split("\\'")[0]); String b[]=d.split("\\'")[1].split("\\/"); s1=Integer.parseInt(b[0]); s2=Integer.parseInt(b[1]); if(n2<0) return multiply(c,0+"'"+s2+"/"+(n2*s2-s1)); return multiply(c,0+"'"+s2+"/"+(s1+n2*s2)); } public String divide(String c,int d) {//分数除法 if(isNumber(c)||isNumber(simplify(c))) return divide(Integer.parseInt(simplify(c)),d); return multiply(c,0+"'"+1+"/"+d); } public String divide(int c,String d) {//分数除法 if(isNumber(d)||isNumber(simplify(d))) return divide(c,Integer.parseInt(simplify(d))); int s1,s2,n2; n2=Integer.parseInt(d.split("\\'")[0]); String b[]=d.split("\\'")[1].split("\\/"); s1=Integer.parseInt(b[0]); s2=Integer.parseInt(b[1]); if(n2<0) return multiply(0+"'"+s2+"/"+(n2*s2-s1),c); return multiply(0+"'"+s2+"/"+(n2*s2+s1),c); } public String divide(int c,int d) {//分数除法 if(c%d==0) return String.valueOf(c/d); return simplify(0+"'"+c+"/"+d); } public static void main(String[] args) { } }
写txt
import java.io.*; public class Write { public static void writefile (String a,String b ){ try{ String content = a; File file =new File(b); if(!file.exists()){ file.createNewFile(); } //使用true,即进行append file FileWriter fileWritter = new FileWriter(file.getName(),true); fileWritter.write(content+"\r\n"); fileWritter.close(); }catch(IOException e){ e.printStackTrace(); } } public static void main(String[] args) { } }
对比答案
import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.*; import java.util.ArrayList; public class Read { public static void writefile (String a,String b ){ try{ String content = a; File file =new File(b); if(!file.exists()){ file.createNewFile(); } //使用true,即进行append file FileWriter fileWritter = new FileWriter(file.getName(),true); fileWritter.write(content+"\r\n"); fileWritter.close(); }catch(IOException e){ e.printStackTrace(); } } // 校对答案与答卷 传入两个文档的文件名 public static void proofread (String x,String y){ try { File file1=new File(x); FileReader fileReader1 =new FileReader(file1); BufferedReader reader1 =new BufferedReader(fileReader1); File file2=new File(y); FileReader fileReader2 =new FileReader(file2); BufferedReader reader2 =new BufferedReader(fileReader2); //用缓冲区来获得更高的效率 String line1=null; String line2=null; String str="Grade.txt"; int rightN=0;int wrongN=0; ArrayList<String>rightList=new ArrayList<String>(); ArrayList<String>wrongList=new ArrayList<String>();//用ArrayList接收正确与错误序号 while (((line1=reader1.readLine())!=null)&&(line2=reader2.readLine())!=null) { String[] result1 = line1.split("\\."); //将序号与答案分开 String[] result2 = line2.split("\\."); //将序号与答卷分开 if (result1[1].equals(result2[1])) { rightN++; rightList.add(result1[0]); } else { wrongN++; wrongList.add(result1[0]); } } String str1 = "Correct:" + rightN + "("; String str2 = "Wrong:" + wrongN + "("; for (int i = 0; i <= rightList.size() - 1; i++) { if (i == rightList.size() - 1) str1 = str1 + rightList.get(i) + ")"; else str1 = str1 + rightList.get(i) + ","; } for (int i = 0; i <= wrongList.size() - 1; i++) { if (i == wrongList.size() - 1) str2 = str2 + wrongList.get(i) + ")"; else str2 = str2 + wrongList.get(i) + ","; } writefile(str1 + "\n" + str2, str); reader1.close(); reader2.close(); } catch (Exception ex){ ex.printStackTrace(); } } public static void main(String[] args) { String a="Answers.txt"; String b="Answers2.txt"; proofread(a,b); } }
5.测试






生成10000道



6.实际PSP
|
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
|
Planning |
计划 |
30 |
30 |
|
· Estimate |
· 估计这个任务需要多少时间 |
1200 |
1545 |
|
Development |
开发 |
600 |
720 |
|
· Analysis |
· 需求分析 (包括学习新技术) |
60 |
90 |
|
· Design Spec |
· 生成设计文档 |
20 |
20 |
|
· Design Review |
· 设计复审 (和同事审核设计文档) |
20 |
30 |
|
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
60 |
45 |
|
· Design |
· 具体设计 |
120 |
300 |
|
· Coding |
· 具体编码 |
60 |
60 |
|
· Code Review |
· 代码复审 |
60 |
30 |
|
· Test |
· 测试(自我测试,修改代码,提交修改) |
60 |
120 |
|
Reporting |
报告 |
30 |
10 |
|
· Test Report |
· 测试报告 |
30 |
20 |
|
· Size Measurement |
· 计算工作量 |
20 |
10 |
|
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
30 |
60 |
|
合计 |
|
1200 |
1545 |
7.项目小结:
没有实现结果非负,也没有实现查重,在分数混合情况下,重复概率很小,也没有实现图形化界面。
李玉:刚开始看到项目觉得不难,但是上手后才发现有诸多细节需要注意,有很多小功能的实现还是不简单。关于效能分析及图形化界面方面的知识我仍在努力学习,还不足以实现,以后继续努力。线上和队友沟通的效果还行,也有积极讨论项目。对JAVA知识学习更加深刻,学会解决了异常的Bug。总而言之,这次项目收获很多。
对队友的评价:健哥工作认真负责,勤劳能干。解决了最为复杂的计算和分数部分。经常主动找我沟通,交流起来很愉悦。
梁鸿健:虽然勉强完成了,但是做的很糟糕。计算部分很多冗余代码。好在队友给力把io做完了。这次经历虽然不是完美,但是积累了经验。认识到合作应该分工明确并且经常交流。还有就是有些东西虽然很难,但是迈出了第一步就会慢慢摸到路。
对队友的评价:玉哥工作效率高,总是能提供一些灵感,同时也向他学习到一些我不熟悉的io操作。