结对编程Java实现四则运算(林伯浩 刘育明)
Posted liuyuming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结对编程Java实现四则运算(林伯浩 刘育明)相关的知识,希望对你有一定的参考价值。
GIthub项目地址:https://github.com/3116004696/ruanjiangongcheng/tree/master/Myapp
项目要求:
实现一个自动生成小学四则运算题目的命令行程序。
1. 使用 -n 参数控制生成题目的个数。(实现)
2. 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围。(未实现真分数运算)
3. 生成的题目中计算过程不能产生负数。(实现)
4. 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。(未实现)
5. 每道题目中出现的运算符个数不超过3个。(实现)
6. 程序一次运行生成的题目不能重复,生成的题目存入执行程序的当前目录下的Exercises.txt文件。(实现)
7. 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件。(实现)
8. 程序应能支持一万道题目的生成。(实现)
9. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计。(实现)
PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
· Estimate | · 估计这个任务需要多少时间 | 30 | 40 |
Development | 开发 | 1500 | 1600 |
· Analysis | · 需求分析 (包括学习新技术) | 300 | 400 |
· Design Spec | · 生成设计文档 | 60 | 60 |
· Design Review | · 设计复审 (和同事审核设计文档) | 60 | 60 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 40 |
· Design | · 具体设计 | 90 | 120 |
· Coding | · 具体编码 | 800 | 1000 |
· Code Review | · 代码复审 | 70 | 70 |
· Test | · 测试(自我测试,修改代码,提交修改) | 90 | 90 |
Reporting | 报告 | 130 | 130 |
· Test Report | · 测试报告 | 60 | 60 |
· Size Measurement | · 计算工作量 | 10 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 60 | 60 |
合计 | 1690 | 2150 |
解题思路
一开始对于式子的运算这一部分有点拿不准主意,不知道用生成树方法计算还是逆波兰表达式计算好,最后两人一番考虑后决定用逆波兰表达式解决式子的运算。在生成式子的这一部分采用控制符号位来限定随机生成的式子,含括号的式子采用手动添加的方式,既当运算符为两个和三个时随机挑几个式子手动为其加上括号。至于分数部分的算法至今还未想好如何解决。最后的作答部分用以前做的文件编辑器嵌套进去,省去了许多繁杂的工作,直接在文本编辑器里面作答,识别内容比对得到对错情况。
设计实现过程
首先,将需要控制的变量生成好,然后随机生成1~3个符号位,再随机生成数字,位数为符号位+1,然后将符号和数字放入一个数组表中,再利用逆波兰表达式计算结果。接着用文件输入输出流将式子和答案分别存入test.txt和answer.txt中,作答时将弹出一个文本编辑器,在里面作答完毕后可以统计对错情况并且在底部生成结果。
代码说明
主函数:
1 public class MainTest { 2 3 public static void main(String[] args) throws IOException { 4 // TODO 自动生成的方法存根 5 System.out.println("请输入生成题目数:-n"); 6 Scanner input = new Scanner(System.in); 7 int n = input.nextInt(); 8 System.out.println("请输入数值范围:-r"); 9 Scanner in = new Scanner(System.in); 10 int r =in.nextInt(); 11 Random rand = new Random(); 12 ArrayList<String> list = new ArrayList<String>(); 13 ArrayList<Integer> answerlist = new ArrayList<Integer>(); 14 char[] symbol =new char[]{‘+‘,‘-‘,‘*‘,‘÷‘}; 15 File test=new File(".\\test.txt"); 16 test.delete(); 17 test.createNewFile(); 18 File answer=new File(".\\answer.txt"); 19 test.delete(); 20 test.createNewFile();
随机生成一条式子:
1 int SymNum = rand.nextInt(3)+1; 2 int[] Num=new int[SymNum+1]; 3 String formula=new String(); 4 for(int j=0;j<SymNum+1;j++) { //随机生成数字及其范围 5 Num[j]=rand.nextInt(r)+1; 6 } 7 8 int whether=rand.nextInt(2); 9 int choice=rand.nextInt(2); 10 int k; 11 int tag=0; 12 int stop=0; 13 int stop1=0; 14 if(whether==0) { 15 if(SymNum==3&&choice==0) { //1 16 for(k=0;k<SymNum;k++) { //符号 17 int Sym =rand.nextInt(4); //随机生成符号 18 if(tag==0) { 19 formula+=‘(‘+String.valueOf(Num[k])+String.valueOf(symbol[Sym]); 20 } 21 else if(tag==1) { 22 formula+=String.valueOf(Num[k])+‘)‘+String.valueOf(symbol[Sym]); 23 } 24 else formula+=String.valueOf(Num[k])+String.valueOf(symbol[Sym]); 25 tag++; 26 } 27 formula+=String.valueOf(Num[SymNum]); 28 tag=0; 29 30 } 31 else if(SymNum==3&&choice==1) { //2 32 for(k=0;k<SymNum;k++) { 33 int Sym =rand.nextInt(4); 34 if(tag==1) { 35 formula+=‘(‘+String.valueOf(Num[k])+String.valueOf(symbol[Sym]); 36 } 37 else if(tag==2) { 38 formula+=String.valueOf(Num[k])+‘)‘+String.valueOf(symbol[Sym]); 39 } 40 else formula+=String.valueOf(Num[k])+String.valueOf(symbol[Sym]); 41 tag++; 42 } 43 formula+=String.valueOf(Num[SymNum]); 44 tag=0; 45 46 } 47 else if(SymNum==2&&choice==1) { //3 48 for(k=0;k<SymNum;k++) { 49 int Sym =rand.nextInt(4); 50 if(tag==0) { 51 formula+=‘(‘+String.valueOf(Num[k])+String.valueOf(symbol[Sym]); 52 } 53 else { 54 formula+=String.valueOf(Num[k])+‘)‘+String.valueOf(symbol[Sym]); 55 } 56 tag++; 57 } 58 formula+=String.valueOf(Num[SymNum]); 59 tag=0; 60 61 } 62 63 else{ 64 for(k=0;k<SymNum;k++) { 65 int Sym =rand.nextInt(4); 66 formula+=String.valueOf(Num[k])+String.valueOf(symbol[Sym]); 67 } 68 formula+=String.valueOf(Num[SymNum]); 69 } 70 } 71 72 73 if(whether==1) { 74 for(k=0;k<SymNum;k++) { 75 int Sym =rand.nextInt(4); 76 formula+=String.valueOf(Num[k])+String.valueOf(symbol[Sym]); 77 } 78 formula+=String.valueOf(Num[SymNum]); 79 } 80 81 if(list.contains(formula)) {//检查是否重复 82 int len=list.size(); 83 list.remove(len-1); 84 n=n+1; 85 continue; 86 } 87 list.add(formula);
逆波兰表达式计算结果:
1 //逆波兰表达式处理式子运算 2 Stack<Integer> savenumber = new Stack<Integer>(); // 保存数字 3 Stack<Character> savesymbol = new Stack<Character>(); // 保存操作符 4 int memory = 0; // 保存每一个数字 5 char[] cs = formula.toCharArray(); 6 for (int k1=0;k1<cs.length;k1++) { 7 char temp = cs[k1]; 8 //数字判断 9 if (Character.isDigit(cs[k1])) { 10 memory= 10*memory + Integer.parseInt(String.valueOf(cs[k1])); 11 } 12 //符号判断 13 else { 14 if (memory!= 0) { 15 savenumber.push(memory); 16 memory = 0; 17 } 18 if (temp==‘(‘) { 19 savesymbol.push(temp); 20 } else if (temp==‘)‘) { 21 22 //peek 不改变栈的值(不删除栈顶的值),pop会把栈顶的值删除。 23 24 while (savesymbol.peek()!=‘(‘) { // 括号里面运算完 25 int t = calculator(savenumber.pop(), savenumber.pop(), savesymbol.pop()); 26 savenumber.push(t); 27 } 28 savesymbol.pop(); 29 } else if (priority(temp) > 0) { 30 if (savesymbol.isEmpty()) { // 栈为空直接入栈 31 savesymbol.push(temp); 32 } else { 33 if (priority(savesymbol.peek())>= priority(temp)) { 34 int t = calculator(savenumber.pop(), savenumber.pop(), savesymbol.pop()); 35 savenumber.push(t); 36 } 37 savesymbol.push(temp); 38 } 39 } 40 } 41 } 42 if (memory!= 0) { 43 savenumber.push(memory); 44 } 45 while (!savesymbol.isEmpty()) { 46 int t = calculator(savenumber.pop(), savenumber.pop(), savesymbol.pop()); 47 if(t==10001) { 48 stop=1; 49 break; 50 } 51 savenumber.push(t); 52 } 53 if(!savenumber.isEmpty()&&savenumber.peek()<0) { //负数 54 n=n+1; 55 int len=list.size(); 56 list.remove(len-1); 57 continue; 58 } 59 else if(stop==1) { 60 n=n+1; 61 int len=list.size(); 62 list.remove(len-1); 63 continue; 64 } 65 else if(stop1==1) { 66 n=n+1; 67 int len=list.size(); 68 list.remove(len-1); 69 continue; 70 } 71 answerlist.add(savenumber.pop()); 72 }
生成test.txt和answer.txt文件:
1 BufferedWriter out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(test))); 2 int Titlenumber=1; 3 for (String tmp : list) { 4 out.write(Titlenumber+". "+tmp+"="); 5 out.newLine(); 6 Titlenumber++; 7 } 8 out.flush(); 9 out.close(); 10 11 BufferedWriter answerout=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(answer))); 12 BufferedReader fis=new BufferedReader(new FileReader(".\\test.txt")); 13 String testtmp; 14 for (int answertmp : answerlist) { 15 testtmp=fis.readLine(); 16 answerout.write(testtmp+answertmp); 17 answerout.newLine(); 18 } 19 answerout.flush(); 20 answerout.close();
作答界面实现函数:
1 public class Exercise extends JFrame implements ActionListener{ 2 JLabel welcome=new JLabel("Weclome Back!",JLabel.CENTER); 3 JLabel none1=new JLabel(" "); 4 JLabel none2=new JLabel(" "); 5 JTextArea write=new JTextArea(60,60); 6 JScrollPane sp=new JScrollPane(write); 7 JButton begin; 8 JButton check; 9 JButton confirm; 10 Color color=new Color(0,0,0); 11 Exercise(){ 12 setTitle("Exercise"); 13 setBounds(0,0,1400,900); 14 Dimension screen=Toolkit.getDefaultToolkit().getScreenSize(); 15 setLocation((screen.width-1400)/2,(screen.height-900)/2); 16 JPanel p=new JPanel(); 17 this.add(p); 18 p.setBackground(Color.DARK_GRAY); 19 p.setLayout(new BorderLayout()); 20 begin=new JButton("开始答题"); 21 check=new JButton("参考答案"); 22 confirm=new JButton("提交"); 23 JPanel p1=new JPanel(); 24 p1.setLayout(new GridLayout(1,3,200,0)); 25 p1.add(begin); 26 p1.add(confirm); 27 p1.add(check); 28 JMenuBar mb=new JMenuBar(); 29 setJMenuBar(mb); 30 JMenu m=new JMenu("开始"); 31 mb.add(m); 32 JMenuItem m1=new JMenuItem("新建"); 33 JMenuItem m2=new JMenuItem("保存"); 34 JMenuItem m3=new JMenuItem("打开"); 35 JMenuItem m4=new JMenuItem("退出"); 36 m.setFont(new Font("幼圆",Font.BOLD,35)); 37 m1.setFont(new Font("幼圆",Font.BOLD,25)); 38 m2.setFont(new Font("幼圆",Font.BOLD,25)); 39 m3.setFont(new Font("幼圆",Font.BOLD,25)); 40 m4.setFont(new Font("幼圆",Font.BOLD,25)); 41 m.add(m1); 42 m.add(m2); 43 m.add(m3); 44 m.add(m4); 45 JMenu help=new JMenu("帮助"); 46 help.setFont(new Font("幼圆",Font.BOLD,35)); 47 mb.add(help); 48 JMenu about=new JMenu("关于"); 49 about.setFont(new Font("幼圆",Font.BOLD,35)); 50 JMenu setting=new JMenu("设置"); 51 setting.setFont(new Font("幼圆",Font.BOLD,35)); 52 JMenuItem m5=new JMenuItem("字体颜色"); 53 JMenuItem m6=new JMenuItem("文本颜色"); 54 m5.setFont(new Font("幼圆",Font.BOLD,25)); 55 m6.setFont(new Font("幼圆",Font.BOLD,25)); 56 setting.add(m5); 57 setting.add(m6); 58 mb.add(about); 59 mb.add(setting); 60 JPopupMenu po=new JPopupMenu(); 61 write.add(po); 62 welcome.setFont(new Font("Script MT Bold",Font.BOLD,50)); 63 welcome.setForeground(Color.WHITE); 64 p.add(welcome,BorderLayout.NORTH); 65 p.add(sp,BorderLayout.CENTER); 66 p.add(none1,BorderLayout.WEST); 67 p.add(none2,BorderLayout.EAST); 68 p.add(p1,BorderLayout.SOUTH); 69 m1.addActionListener(this); 70 m2.addActionListener(this); 71 m3.addActionListener(this); 72 m4.addActionListener(this); 73 m5.addActionListener(this); 74 m6.addActionListener(this); 75 begin.addActionListener(this); 76 check.addActionListener(this); 77 confirm.addActionListener(this); 78 this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 79 this.setVisible(true); 80 } 81 public void actionPerformed(ActionEvent e){ 82 if(e.getActionCommand()=="清空") { 83 write.setText(""); 84 } 85 else if(e.getActionCommand()=="保存") { 86 FileDialog save=new FileDialog(this,"save",FileDialog.SAVE); 87 save.setVisible(true); 88 try { 89 String savefile=save.getDirectory()+save.getFile(); 90 BufferedReader in=new BufferedReader(new StringReader(write.getText())); 91 BufferedWriter fos=new BufferedWriter(new FileWriter(savefile)); 92 String str; 93 while((str=in.readLine())!=null) { 94 fos.write(str); 95 fos.newLine(); 96 } 97 fos.flush(); 98 fos.close(); 99 }catch(IOException ioe) { 100 System.out.println("ERROR"); 101 } 102 } 103 else if(e.getActionCommand()=="打开") { 104 FileDialog open=new FileDialog(this,"open",FileDialog.LOAD); 105 open.setVisible(true); 106 try { 107 String openfile=open.getDirectory()+open.getFile(); 108 BufferedReader fis=new BufferedReader(new FileReader(openfile)); 109 String s; 110 while((s=fis.readLine())!=null) { 111 write.append(s); 112 write.append(" "); 113 } 114 fis.close(); 115 }catch(IOException ioe) { 116 System.out.println("ERROR"); 117 } 118 } 119 else if(e.getActionCommand()=="退出") { 120 dispose();} 121 else if(e.getSource()==begin) {//答题 122 write.setText(""); 123 write.setFont(new Font("Tekton Pro",Font.BOLD,40)); 124 try { 125 BufferedReader fis=new BufferedReader(new FileReader(".\\test.txt")); 126 String s; 127 while((s=fis.readLine())!=null) { 128 write.append(s); 129 write.append(" "); 130 } 131 fis.close(); 132 }catch(IOException ioe) { 133 System.out.println("ERROR"); 134 } 135 } 136 else if(e.getSource()==check) { //参考答案 137 write.setFont(new Font("Tekton Pro",Font.BOLD,40)); 138 try { 139 BufferedReader fis=new BufferedReader(new FileReader(".\\answer.txt")); 140 String s; 141 while((s=fis.readLine())!=null) { 142 write.append(s); 143 write.append(" "); 144 } 145 fis.close(); 146 }catch(IOException ioe) { 147 System.out.println("ERROR"); 148 } 149 } 150 else if(e.getSource()==confirm) {//提交 151 try { 152 BufferedReader fis=new BufferedReader(new FileReader(".\\answer.txt")); 153 BufferedReader in=new BufferedReader(new StringReader(write.getText())); 154 String s; 155 String comp; 156 int correct=0; 157 int wrong=0; 158 int col=write.getLineCount()-1; 159 int testnum=1; 160 int i=0; 161 int j=0; 162 int[] correctnum=new int[col]; 163 int[] wrongnum=new int[col]; 164 while((s=fis.readLine())!=null&&(comp=in.readLine())!=null) { 165 if(s.equals(comp)) { 166 correctnum[i]=testnum; 167 correct++; 168 i++; 169 } 170 else { 171 wrongnum[j]=testnum; 172 wrong++; 173 j++; 174 } 175 testnum++; 176 } 177 write.append(" Correct: "+correct); 178 write.append(" ("); 179 for(int k=0;k<col;k++) { 180 if(correctnum[k]!=0) 181 write.append(" "+correctnum[k]+" "); 182 } 183 write.append(") "); 184 write.append("Wrong: "+wrong); 185 write.append(" ("); 186 for(int k=0;k<col;k++) { 187 if(wrongnum[k]!=0) 188 write.append(" "+wrongnum[k]+" "); 189 } 190 write.append(") "); 191 fis.close(); 192 in.close(); 193 }catch(IOException ioe) { 194 System.out.println("ERROR"); 195 } 196 } 197 else if(e.getActionCommand()=="字体颜色") { 198 color= JColorChooser.showDialog(this,"选择颜色",color); 199 if (color==null ) color=Color.BLACK; 200 write.setForeground(color); 201 } 202 else if(e.getActionCommand()=="文本颜色") { 203 color= JColorChooser.showDialog(this,"选择颜色",color); 204 if (color==null ) color=Color.WHITE; 205 write.setBackground(color); 206 } 207 } 208 }
测试运行
运行界面:
做题界面:
答案界面:
代码覆盖率:
项目小结
这次结对编程对我们收获很大,一开始做这个项目的时候讨论设计如何实现功能,在经过一番讨论后便很快总结出了设计过程,比一个人研究效率高了很多,其次,在一起打代码时,一个人打一个人看,有什么错的地方很快就能被指正,有些不懂的地方旁边的人也能快速提出意见,彼此互通有无,分享彼此的经验,也为枯燥的打代码时间充实了一些乐趣。最后,大家分工合作,执行效率远远高于独自完成,可能这就是所谓的1+1>2吧,这种方式很值得以后借鉴。
以上是关于结对编程Java实现四则运算(林伯浩 刘育明)的主要内容,如果未能解决你的问题,请参考以下文章
20165219 2017-2018-2《Java程序设计》结对编程一 第一周总结