首页 > 其他 > 详细

2016012028+小学四则运算练习软件项目报告

时间:2018-03-24 20:25:52      阅读:272      评论:0      收藏:0      [点我收藏+]

任务1源码可直接克隆的仓库地址

 (HTTPS)https://git.coding.net/zhaoliguaner/Calculate.git  (SSH)git@git.coding.net:zhaoliguaner/Calculate.git


需求分析

使用JAVA编程语言,独立完成一个3到5个运算符的四则运算练习的命令行软件开发。

 


功能分析

一、基本功能

  • 程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。
  • 为了让小学生得到充分锻炼,每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,你所出的练习题在运算过程中不得出现负数与非整数,比如不能出 3÷5+2=2.6,2-5+10=7等算式。
  • 练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。
  • 当程序接收的参数为4时,以下为一个输出文件示例。

 

    技术分享图片

二、附加功能

  • 支持有括号的运算式,包括出题与求解正确答案。注意,算式中存在的括号必须大于2个,且不得超过运算符的个数。
  • 扩展程序功能支持真分数的出题与运算(只需要涵盖加减法即可),例如:1/6 + 1/8 + 2/3= 23/24。注意在实现本功能时,需支持运算时分数的自动化简,比如 1/2+1/6=2/3,而非4/6,且计算过程中与结果都须为真分数。

 


设计实现

设计了以下函数:    

 1. LinkedList<String> expression()  产生运算式

 2. int[ ] operator()  产生随机操作符

 3. int decide(int x,int y)  通过递归实现整除

 4. int transferToPostfix(LinkedList<String> list,int n,String[] ss)  将中缀表达式转化为后缀表达式

 5. int calculate(int n,String[] ss)  计算后缀表达式

 6. boolean isOperator(String oper)  进行操作符的判断

 7. int priority(String s)  进行操作符优先级排序

 8. int cal(int num1,int num2,String operator)  进行数字间的运算

 9. void printHeader() 将结果输出到文件

通过上述函数的使用,目前只完成了基本功能,对于增加括号和分数的功能尚未实现。

显示部分代码

         /**
	 * 产生运算符,个数及种类,并限制种类大于2。此处采用递归
	 * @return int[] ope 返回生成的运算符
	 */
	 private static int[] operator() {
		 Random random = new Random();
		 boolean flag = false;
		 int n=random.nextInt(3)+3;  //3-5个运算符,运算符个数
		 ope=new int[n];
		 for (int j=0;j<n;j++)  ope[j]=random.nextInt(4);  //随机选择某个运算符
		 for (int j = 1; j < n; j++) {               //控制运算符种类
			if(ope[0]!=ope[j]) flag = true;
		 }
		 if (!flag)  {
		   operator();
		 }
		 return ope;
	     }
	    

  

	  /**
	  * 中缀表达式转化为后缀表达式
	  * @param LinkedList<String> list
	  * @param int n
	  * @param String[] ss
          * @return int m 
	  */
          
  private static int transferToPostfix(LinkedList<String> list,int n,String[] ss){
        Iterator<String> it=list.iterator();
        while (it.hasNext()) {
            String s = it.next();
            if (isOperator(s)) {
                if (operators.isEmpty()) {
                    operators.push(s);
                }
                else {
                    //如果读入的操作符为非")"且优先级比栈顶元素的优先级高或一样,则将操作符压入栈
                    if (priority(operators.peek())<priority(s)&&!s.equals(")")) {
                        operators.push(s);
                    }
                    else if(!s.equals(")")&&priority(operators.peek())>=priority(s)){
                        while (operators.size()!=0&&priority(operators.peek())>=priority(s)&&!operators.peek().equals("(")) {
                            if (!operators.peek().equals("(")) {
                                String operator=operators.pop();
                                sb.append(operator).append(" ");                           
                                output.push(operator);
                            }
                        }
                        operators.push(s);
                    }
                    //如果读入的操作符是")",则弹出从栈顶开始第一个"("及其之前的所有操作符
                    else if (s.equals(")")) {
                        while (!operators.peek().equals("(")) {
                            String operator=operators.pop();
                            sb.append(operator).append(" ");
                            output.push(operator);
                        }
                        //弹出"("
                        operators.pop();
                    }
                }
            }
            //读入的为非操作符
            else {
                sb.append(s).append(" ");          	
                output.push(s);
            }
        }
        if (!operators.isEmpty()) {
            Iterator<String> iterator=operators.iterator();
            while (iterator.hasNext()) {
                String operator=iterator.next();
                sb.append(operator).append(" ");
                output.push(operator);
                iterator.remove();
            }
        }
        int m = calculate(n,ss);
        sb.delete(0,sb.length());
        return  m ;
    }

 

          /**
	  * 计算后缀表达式并输出到文件
	  * @param int n
	  * @param String[] ss
          * @return int n 
	  */	  
	  private static int calculate(int n,String[] ss){
	        LinkedList<String> mList=new LinkedList<>();
	        String[] postStr=sb.toString().split(" ");
	        for (String s:postStr) {
	            if (isOperator(s)){
	                if (!mList.isEmpty()){
	                    int num1=Integer.valueOf(mList.pop());
	                    int num2=Integer.valueOf(mList.pop());
	                    if (s.equals("/")&&(num1==0||num1>num2)){
	                        n--;
	                        return n;
	                    }
	                    if(s.equals("-")&&num2%num1!=0){
	                    	n--;
	                    	return n;
	                    }
	                    int newNum=cal(num2,num1,s);
	                    mList.push(String.valueOf(newNum));
	                }
	            }
	            else {
	                //数字则压入栈中
	                mList.push(s);
	            }
	        }
	        String content = "";
	        if (!mList.isEmpty()){
	        	for (int j = 0; j < ss.length; j++) {
	        		content+=ss[j];
				}
	        	  content+="="+mList.pop()+"\r\n";
	        }
	        
	        if(!file.exists()) file = new File("result.txt");	        
	    	try {
				FileOutputStream fos = new FileOutputStream(file,true);//建立文件流,用以输出计算式	       
				fos.write(content.getBytes());
				fos.flush();
				fos.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
	        return n;
	    }

  主函数:

 public static void main(String[] args) {
	        Scanner scanner=new Scanner(System.in);
	        int num;
	        num = scanner.nextInt();
	        int n=0;
	        printHeader();
	        while (n<num) {
	        	LinkedList<String> list=new LinkedList<>();
	        	list=new CalCu().expression();
	        	Iterator<String> it=list.iterator();
	        	StringBuilder sd=new StringBuilder();
	            while (it.hasNext()) {               
	               sd.append(it.next()).append(" ");
	            }
	            String[] ss=sd.toString().split(" ");
	            n = transferToPostfix(list,n,ss);
	            n++;
			}
	        System.out.println("输出成功");
	        scanner.close();
	    }

  


测试运行

技术分享图片

 

技术分享图片

 


 

项目总结

       在分析了模块化的定义(模块化程序设计即模块化设计,属于计算机编程,简单地说就是程序的编写不是开始就逐条录入计算机语句和指令,而是首先用主程序、子程序、子过程等框架把软件的主要结构和流程描述出来,并定义和调试好各个框架之间的输入、输出链接关系。)之后,我在写代码的过程中,推开之前逐条去写代码的习惯,采用了一种新的方法,定义了一些子方法,并在主程序或子程序中去调用,运用这样的编程方法,觉得代码思路清晰了很多。


PSP展示

PSP

任务内容

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

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

Planning

计划

8

6

·        Estimate

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

8

6

Development

开发

198

481

·        Analysis

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

30

120

·        Design Spec

·         生成设计文档

5

5

·        Design Review

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

5

3

·        Coding Standard

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

3

3

·        Design

·         具体设计

15

40

·        Coding

·         具体编码

80

120

·        Code Review

·         代码复审

20

40

·        Test

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

40

150

Reporting

报告

9

6

·         Test Report

·         测试报告

3

2

·         Size Measurement

·         计算工作量

2

1

·         Postmortem & Process Improvement Plan

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

3

3


后记:自己之前也有敲代码,但是那些代码都比较固定,在算法上几乎没有难度,而这次的四则运算,在算法方面的要求比之前要高,所以,对我还是一个蛮大的挑战,在起初看完题目要求后,真的是觉得无从下手。在敲代码的过程中也不怎么顺,很多java的类、方法自己知道的也不多,都是在这过程当中学习的;还有相关算法(调度场算法),文件流的输出这些也是认真读了博客学习的。将代码写好测试无误后,发现还需要在命令行窗口进行编译运行,这也不同于之前的在IDE中进行编译运行,怎么办呢?再学呗。最后,又学习了git的相关知识,将项目传到encoding.net上面,并作了博客记录,整个工作才算完成。通过这次作业,我确实收获了很多,完成之后,感觉十分欣慰,因为我知道自己收获满满。而且,我发现自己现在养成了想要去记录博客的好习惯,很开心,技术和习惯上的双丰收。所以,想要感谢老师,感谢这道题,也感谢自己,谢谢。

2016012028+小学四则运算练习软件项目报告

原文:https://www.cnblogs.com/zhaollguaner/p/8612230.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!