2016012065小学四则运算练习软件报告

Coding.net原码仓库地址(已经更新为最新):

https://git.coding.net/bigben123/abc.git

 

一、需求分析 

 1.程序在接受一个输入数n后,随机生成n道不同的四则运算题目(分别使用符号+-*÷来表示),并且要求在运算过程中不存在小数与分数

 2.练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致 

二、设计实现

该程序的主要难点在于如何避免出现小数与分数。我通过在创建运算式生成的过程中判断是否出现小数与分数来区分生成的运算题是否合格,将不合格 的淘汰掉,以此来实现程序功能。

三、算法详解

Main中,实现整个程序的逻辑架构,实现与用户的交互,并调用lib类中的方法实现目标功能。

Main

 1 import java.util.Scanner;
 2 import java.io.IOException;
 3 
 4 
 5 public class Main {
 6     public static void main(String args[]){
 7         Scanner input = new Scanner(System.in); 
 8         int n = input.nextInt();
 9         String[] list = new String[10];
10         
11         for(int i=0; i<n; i++){
12             list[i] = Lib.makeAndCalQuestion();
13         }
14         try{
15             Lib.print(list, n);
16         }
17         catch(IOException ioe) {
18             ioe.printStackTrace();
19         }
20     }
21 }

Lib中方法的主要思路
1.生成并计算一个算式,所有操作符和操作数随机生成
2.在生成过程中,用cnt表示已生成算式中操作符的个数,cnt==0时,预生成第一位数字,之后操作符和操作数结对生成
3.在生成算式的同时,对算式进行计算,如若出现负数或者小数,则重置cnt为0,放弃当前生成的算式,重新生成,直到生成一个合法的算式

代码如下,我把具体的注释都写在里面了,就不过多说了。

Lib

 

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class Lib {
    
    
    
     static public String makeAndCalQuestion(){
            char[] oc = new char[10];
            char[] op = {'+', '-', '*', '÷'};
            int[] num = new int[10];
            int cnt = 0, p1 = -1, p2 = -1;
            String question = "";
            int num0;
            while(cnt<5){   //用于对操作符的计数,五个操作符时跳出
                if(cnt == 0){
                    p1 = -1;
                    p2 = -1;
                    num0 = (int)(Math.random()*10+1); //生成第一个操作数
                    question = "" + num0;
                    num[++p1] = num0;
                }
                char fuhao = op[(int)(Math.random()*3+0.5)];   //生成对应的操作符和操作数
                int shuzi = (int)(Math.random()*10)+1;
                question = question + fuhao + shuzi;
                cnt++;
                //System.out.println(cnt + " " + question);
                if(fuhao=='+' || fuhao=='-'){                 //判断操作符优先级(种类)
                    if(p2 == -1){                             //第一个操作符,直接入字符栈
                        oc[++p2] = fuhao;
                        num[++p1] = shuzi;
                    }
                    else{
                        while(p2 != -1){                      //中序表达式的计算方法
                            int num2 = num[p1--];
                            int num1 = num[p1--];
                            if(oc[p2] == '*'){                //判断栈顶操作符,并直接计算
                                p2--;
                                num[++p1] = num1 * num2;
                            }
                            else if(oc[p2]=='÷'){
                                p2--;
                                num[++p1] = num1 / num2;
                                if(num1 % num2 != 0) cnt = 0;   //不能整除时,置cnt为0,放弃此次生成算式,重新生成
                            }
                            else if(oc[p2]=='+'){
                                p2--;
                                num[++p1] = num1 + num2;
                            }
                            else if(oc[p2]=='-'){
                                p2--;
                                num[++p1] = num1 - num2;
                                if(num1 - num2 < 0) cnt = 0;   //出现负数,cnt为0,放弃此次生成算式,重新生成
                            }
                        }
                        oc[++p2] = fuhao;
                        num[++p1] = shuzi;
                    }
                }
                else if(fuhao=='*' || fuhao=='÷'){        //特判字符优先级
                    if(p2== -1) {
                        oc[++p2] = fuhao;
                        num[++p1] = shuzi;
                    }
                    else{
                        if(oc[p2] == '*'){
                            int num2 = num[p1--];
                            int num1 = num[p1--];
                            p2--;
                            num[++p1] = num1 * num2;
                        }
                        else if(oc[p2] == '÷'){
                            int num2 = num[p1--];
                            int num1 = num[p1--];
                            p2--;
                            num[++p1] = num1 / num2;
                            if(num1 % num2 != 0) cnt = 0;   //不能整除,cnt为0,放弃此次生成算式,重新生成
                        }
                        oc[++p2] = fuhao;
                        num[++p1] = shuzi;
                    }
                }

                if(cnt == 5){                               //操作符已达要求
                    while(p2 != -1){                        //将字符栈中剩余操作全部计算
                        int num2 = num[p1--];
                        int num1 = num[p1--];
                        if(oc[p2] == '*'){
                            p2--;
                            num[++p1] = num1 * num2;
                        }
                        else if(oc[p2]=='÷'){
                            p2--;
                            num[++p1] = num1 / num2;
                            if(num1 % num2 != 0) cnt = 0;   //不能整除,cnt为0,放弃此次生成算式,重新生成
                        }
                        else if(oc[p2]=='+'){
                            p2--;
                            num[++p1] = num1 + num2;
                        }
                        else if(oc[p2]=='-'){
                            p2--;
                            num[++p1] = num1 - num2;
                            if(num1 - num2 < 0) cnt = 0;  // cnt
                        }
                    }
                }
            }

            question = question + '=' + num[0];   //所有计算结束,运算合法,字符串拼接答案
            return question;                      //将算式返回。
     }
     static void print(String[] question, int n)throws IOException
     {
        FileOutputStream fs = new FileOutputStream(new File("result.txt"));
        PrintStream p = new PrintStream(fs);
        p.println("2016012065");
        for(int i=0; i<n; i++)
            p.println(question[i]);
        p.close();
    }

}

 

四、结果展示

基本实现了基础功能。

五、总结

 这次动手实践让我感触良多,最明显的就是我渐渐地将一些以前学的东西在忘记了,而且动手能力十分菜。这个按理说应该是不怎么难的程序耗费了我大量的时间与精力,也暴露出了我的Java知识十分不牢固,应该在今天晚上开始抽空看一些Java的相关博客,开始亡羊补牢。

其次,在开始盲目的写代码前有一次对整体项目的规划与思考是很有必要的,它可以帮我们节约很多时间,也可以让我们了解自己在开发过程中哪些地方耗时超出了预期,以此来发现自己的不足。

六、PSP展示

PSP2.1

任务内容

计划共完成需要的时间(min)

实际完成需要的时间(min)

Planning

计划

 

 

Estimate

估计这个任务需要多少时间,并规划大致工作步骤

450

750

      Development

开发

 

 

Analysis

需求分析 (包括学习新技术)

30

30

Design Spec

 生成设计文档

 

 

 Design Review

 设计复审 (和同事审核设计文档)

 

 

Coding Standard

代码规范 (为目前的开发制定合适的规范)

 

 

Design

具体设计

 

 

 Coding

具体编码

300

480

Code Review

代码复审

 

 

Test

 测试(自我测试,修改代码,提交修改)

90

120

Reporting

报告

 

 

 Test Report

测试报告

 

 

·Size Measurement

计算工作量

 

 

Postmortem & Process Improvement Plan

 事后总结, 并提出过程改进计划

30

60

posted @ 2018-03-25 21:46  圣光背叛了我五次  阅读(121)  评论(1编辑  收藏  举报