结对编程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.1Personal 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("\n");
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("\n");
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("\n");
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("\n\nCorrect: "+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(")\n");
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(")\n\n");
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 }

 

 

测试运行

运行界面:

 

 

做题界面:

 

 

 

答案界面:

 

 

查看10000道题目

查看10000道答案

代码覆盖率:

 

 

项目小结

     这次结对编程对我们收获很大,一开始做这个项目的时候讨论设计如何实现功能,在经过一番讨论后便很快总结出了设计过程,比一个人研究效率高了很多,其次,在一起打代码时,一个人打一个人看,有什么错的地方很快就能被指正,有些不懂的地方旁边的人也能快速提出意见,彼此互通有无,分享彼此的经验,也为枯燥的打代码时间充实了一些乐趣。最后,大家分工合作,执行效率远远高于独自完成,可能这就是所谓的1+1>2吧,这种方式很值得以后借鉴。

 

    

转载于:https://www.cnblogs.com/liuyuming/p/9732916.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值