小学四则运算练习(JAVA编写)

源码在Github的仓库主页连接地址:https://github.com/rucr9/rucrjava

  看到这个题目,大概不少人会发出“切,这也太简单了吧!有必要小题大作?”的感叹!是的,仅仅做为一道数学运算是没难度,可是,如何实现智能出题并计算正确答案,为大脑减压呢?接下来,我将用java编写程序实现小学四则运算。git

 需求分析

  1.程序可接收一个输入参数n,而后随机产生n道加减乘除练习题;github

  2.每一个数字在 0 和 100 之间,运算符在3个到5个之间;正则表达式

  3.所出的练习题在运算过程当中不得出现负数与非整数;算法

  4.将练习题和计算结果一块儿输出到文件中;express

  5.当程序接收的参数为4时,如下为输出文件示例:浏览器

  

功能设计

  用户输入须要出题的数量n,而后随机产生n道加减乘除练习题,每一个数字在 0 和 100 之间,运算符在3个到5个之间,而且所出的练习题在运算过程当中不得出现负数与非整数;最后将练习题和运算结果输出到result.txt文件中。dom

设计实现

  1.类

  主类:Arithmetic,这个类主要是用户输入出题的数量,随机产生练习题,并调用Expression类中的方法计算结果,最后输出到result.txt文件中。学习

  运算类:Calculate,此类规定了运算符的优先级和计算规则。测试

  逆波兰式转换类:Expression,此类负责将中序表达式转换为右序表达式,并调用Calculate中的方法求值。

  栈类:Stack,此类定义栈方法。

  2.程序执行流程

测试运行

                                             

核心代码

  Arithmetic类

 1 public static ArrayList<String> ss = new ArrayList<String>();
 2 
 3     public static void main(String[] args) throws Exception {
 4 
 5             System.out.println("Input a number:");
 6             int count = new Scanner(System.in).nextInt();
 7             File file =new File("./result.txt");
 8             FileOutputStream fops=null ;
 9 
10             try {
11                 fops = new FileOutputStream(file);
12 
13             } catch (FileNotFoundException e) {
14                 e.printStackTrace();
15             }
16             PrintStream ps= new PrintStream(fops);
17             ps.println("201571030125");
18             boolean f = true;
19             for (int i=0;i<count;i++) {
20                 String data = Data();
21                 String input = data;
22                 ss.add(input);
23                 if (input.equals("q"))
24                     break;
25                 else {
26                     Expression express = new Expression(input);
27                     f = express.getResult();
28                     if(!f) i--;
29                     else ps.println(data + "=" + express.getExpresult());
30                 }
31             }
32     }
33 
34 
35     //随机产生算式
36     public static String Data()
37     {
38         Random rand =new Random();
39         ArrayList<Integer> numlist = new ArrayList<Integer>();
40         ArrayList<String> express = new ArrayList<String>();
41       //产生随机数
42         for(int i=0;i<5;i++)
43         {
44             numlist.add(rand.nextInt(100)+1);
45         }
46         //System.out.print(numlist);
47         String[] operator=new String[]{"+","-","*","/"};
48         int size=numlist.size();
49         String[] num=new String[size];
50         for(int i=0;i<numlist.size();i++){
51             num[i]=String.valueOf(numlist.get(i));
52         }
53         String exp="";
54         for(int j=0;j<num.length;j++)
55         {
56             express.add(num[j]);
57             express.add(operator[rand.nextInt(4)]);
58         }
59         //System.out.print(express);
60 
61         for(int i=0;i<express.size()-1;i++)
62             exp+=express.get(i);
63         return exp;
64     }

  Calulate类

 1 // 判断是否为操做符号
 2     public static boolean isOperator(String operator) {
 3         if (operator.equals("+") || operator.equals("-")
 4                 || operator.equals("*") || operator.equals("/")
 5                 || operator.equals("(") || operator.equals(")"))
 6             return true;
 7         else
 8             return false;
 9     }
10  // 设置操做符号的优先级别
11     public static int priority(String operator) {
12         if (operator.equals("+") || operator.equals("-"))
13             return 1;
14         else if (operator.equals("*") || operator.equals("/"))
15             return 2;
16         else
17             return 0;
18     }
19  // 作2值之间的计算
20     public static String twoResult(String operator, String a, String b) {
21         try {
22             String op = operator;
23             String rs = new String();
24             double x = Double.parseDouble(b);
25             double y = Double.parseDouble(a);
26             boolean f = true;
27 
28             double z = 0.0;
29             if (op.equals("+"))
30                 z = x + y;
31             else if (op.equals("-"))
32                 z = x - y;
33             else if (op.equals("*"))
34                 z = x * y;
35             else if (op.equals("/"))
36             {
37                 if(y==0) {
38                     y=1;
39                     z=999999;
40                 }
41                 z = x / y;
42                 if(z*y!=x) z=999999;
43             }
44             else
45                 z = 999999;
46             if(z<0) z=999999;
47             if(z!=(int)z) z=999999;
48             return String.valueOf(z);
49         } catch (NumberFormatException e) {
50             System.out.println("input has something wrong!");
51             return "Error";
52         }
53     }

  逆波兰式转换方法

 1  private void toRight() {
 2         Stack aStack = new Stack();
 3         String operator;
 4         int position = 0;
 5         while (true) {
 6             if (Calculate.isOperator((String) expression.get(position))) {
 7                 if (aStack.top == -1
 8                         || ((String) expression.get(position)).equals("(")) {
 9                     aStack.push(expression.get(position));
10                 } else {
11                     if (((String) expression.get(position)).equals(")")) {
12                         while(true){
13                             if (aStack.top != -1&&!((String) aStack.top()).equals("(")) {
14                                 operator = (String) aStack.pop();
15                                 right.add(operator);
16                             }else{
17                                 if(aStack.top != -1)
18                                     aStack.pop();
19                                 break;
20                             }
21                         }
22                     } else {
23                         while(true){
24                             if (aStack.top != -1&& Calculate.priority((String) expression
25                                     .get(position)) <= Calculate
26                                     .priority((String) aStack.top())
27                                     ) {
28                                 operator = (String) aStack.pop();
29                                 if (!operator.equals("("))
30                                     right.add(operator);
31                             }else{
32                                 break;
33                             }
34 
35                         }
36                         aStack.push(expression.get(position));
37                     }
38                 }
39             } else
40                 right.add(expression.get(position));
41             position++;
42             if (position >= expression.size())
43                 break;
44         }
45         while (aStack.top != -1) {
46             operator = (String) aStack.pop();
47             if(!operator.equals("("))
48                 right.add(operator);
49         }
50     }

  逆波兰式求值方法

 1 boolean getResult() {
 2 
 3 
 4         this.toRight();
 5 
 6         Stack aStack = new Stack();
 7         String op1, op2, is = null;
 8         String temp="";
 9         Iterator it = right.iterator();
10         while (it.hasNext()) {
11             is = (String) it.next();
12             if (Calculate.isOperator(is)) {
13                 op1 = (String) aStack.pop();
14                 op2 = (String) aStack.pop();
15                 temp = Calculate.twoResult(is, op1, op2);
16                 double td = Double.parseDouble(temp.trim());
17                 if(td==999999.0){
18                     return false;
19 
20                 }
21                 aStack.push(temp);
22             } else
23                 aStack.push(is);
24         }
25         expresult = (String) aStack.pop();
26 
27         it = expression.iterator();
28         while (it.hasNext()) {
29             String tempstr = (String) it.next();
30             System.out.print(tempstr);
31 
32         }
33         System.out.println("=" + expresult);
34         return true;
35 
36     }

总结

  此项目看似简单,但实际上要考虑的问题有不少,好比如何产生随机数,随机数和运算符如何结合,用什么结构存储数据,使用什么方法计算表达式(正则表达式,逆波兰式等等),如何去除不符合要求的运算式,如何处理异常等等。

  起初看到题目时,感受这不就是加减乘除运算嘛,有什么难的。可是,当具体设计的时候发现困难重重,必须思路清晰,逻辑缜密,写代码时才不会东一下西一下,最后一团乱,连本身都搞不明白本身在干吗了,因此,拿到任何一个题目时都不要急于写代码,作好需求分析、设计实现等前期工做是很是重要的。

  最后,提醒各位园友养成编辑过程当中随时保存博客的习惯,以防手一抖、头脑一发昏刷新网页或者关闭浏览器,这可真的是前功尽弃啊!痛到欲哭无泪。。。本人就是犯了这样的错误,致使重写博客!!!

存在的问题

  1.最后的计算结果都带有小数点;

  2.java自带了栈类,我在这里从新定义有些多余;

  3.产生的练习题都是5个运算数。

  本项目参考逆波兰式算法http://blog.csdn.net/yunxiang/article/details/1918717,并根据需求和本身的理解进行改进而成,若有好的建议,请多多指教!我将很是感谢!

PSP

PSP2.1 任务内容 计划完成须要的时间(min) 实际完成须要的时间(min)
Planning 计划  15  20
Estimate  估计这个任务须要多少时间,并规划大体工做步骤   20  25
Development 开发  120 180
Analysis  需求分析 (包括学习新技术) 15  10
Design Spec 生成设计文档   10  8
Design Review  设计复审 (和同事审核设计文档)   15 20
Coding Standard 代码规范 (为目前的开发制定合适的规范)   20  25
Design 具体设计  30 35
Coding 具体编码  180  240
Code Review 代码复审  15  20
Test 测试(自我测试,修改代码,提交修改)  20  25
Reporting 报告  20  22
Test Report 测试报告  5  5
Size Measurement 计算工做量  5  10
Postmortem & Process Improvement Plan 过后总结 ,并提出过程改进计划  8  10
相关文章
相关标签/搜索