• 个人作业——四则运算


    需求分析:

    • 自然数:0, 1, 2, …。
    • 真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
    • 运算符:+, −, ×, ÷。
    • 括号:(, )。
    • 等号:=。
    • 分隔符:空格(用于四则运算符和等号前后)。
    • 算术表达式:
    • e := n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),
      其中e, e1和e2为表达式,n为自然数或真分数。
    • 四则运算题目:e = ,其中e为算术表达式。

    功能设计

    功能:
        1.生成随机数n
        2.生成随机运算符
        3.组成算数表达式
        4.计算题目结果并输出文档
        5.比较答案并给出错误题号
    要求:
        1.表达式不重复
        2.结果无负数
        3.结果最简,
        4.算符不超过三个
    

    程序设计

        随机数表示,统一使用分数形式
        类名:Num,参数类型:int,参数名:numerator(分子),denominator(分母)
    
    • 功能点1:生成随机数
    	随机数生成方法:
            //range为参数范围
            public Num createNum(int range)
    	随机数约分方法:
    	    public Num reduction(Num num)     
    
    • 功能点2:生成随机运算符
    	随机运算符生成方法:
    		public String createpOerator()
    
    • 功能点3:组成算数表达式
    	表达式表示:
    		类型:ArrayList
    	组成方法:
    		public ArrayList<Object> createArithmetic(int range)
    
    • 功能点4:计算表达式结果并输出文档
    	逆波兰式转换:
                //list为生成的算数表达式
    	    public ArrayList<Object> toRPN(ArrayList<Object> list)
    	逆波兰式计算
                //right为逆波兰式
    	    public Num countRPN(ArrayList<Object> right)
                //计算两个数
                private Num twoResult(String is, Num op1, Num op2)
    	文档输出:
                //list1为题目集合,list2为答案集合
    	    public void output(List<Object> list1, List<Object> list2)
    
    • 功能点5:比较答案并记录错误题号
    		public void compare()
    
    • 要求:
    	表达式不重复:
                //list为刚生成的表达式
    	    public boolean checkRPN(String list)
    	结果无负数:
                //result为生成表达式的答案
    	    public boolean checkAnswer(Num result)
    

    工具类:

        栈类:
    	类名:Stacks
    	参数:LinkedList list = new LinkedList();
    		  int top = -1;
    	方法:
    		public void push(Object value)
    		public Object pop()
    		public Object top()
    

    代码说明

        //递归寻找最大公约数
        public int getMaxDivisor(int numerator, int denominator) {
        	if (denominator == 0) {
    			return numerator;
    		} else {
    			return getMaxDivisor(denominator, numerator % denominator);
    		}
    	}
    
        //三个运算符带括号生成方式
        case 3:
            // 括号开始位置
    	    bracket_s = rand.nextInt(4);
        	// 括号结束位置
        	bracket_e = 0;
        	// 没有括号
        	if (bracket_s == 0) {
        		bracket_e = 0;
        	}
        	// 有括号
        	else {
        		bracket_e = bracket_s + rand.nextInt(2) + 1;
        		if (bracket_e >= 4) {
        			bracket_e = 4;
        		}
        	}
        	for (int i = 1; i <= 4; i++) {
                //list为算数表达式
        		if (i == bracket_s) {
        			list.add("(");
        		}
        		list.add(f1.createNum(range));
        		if (i == bracket_e) {
        			list.add(")");
        		}
        		list.add(f2.createoperator());
        	}
        	list.remove(list.size() - 1);
        	break;
    

    源代码已上传至Coding.net
    codingd地址
    https://coding.net/u/w2197525161/p/jisuan

    测试运行

    • 程序运行
    • 选择操作数1
    • 输入题目条件
    • 文档位置
    • 题目,答案与答题
    • 测试答题
    • 答案对照

    PSP表格

        因为是第一次使用PSP的方式统计程序开发时间,所以在估计时间与实际使用时间的统计上还有许多不清楚的地方。在没有刻意去计算时间的时候,常常忘记已经过了多久。
        多数时间花费在程序实际上,虽然有参考部分思路,但还是采用了自己的设计思路,所以没有附上引用的博客链接。主要引用的是求最大公约数的递归算法,手机UC浏览器查到的,只是一张图片,具体链接不明。
    

    心得

        这个程序是在比较完善的设计思路下完成的,从数字的存储方式,到表达式的存储类型,到每一个功能点的设计,函数的构建有比较清晰的思路。较为困难的地方是具体方法的实现,可能是由于都是自己拍脑袋设计的方法,没有很好的去借鉴别人的经验,所以费了不少时间。
        最后程序在表达式查重方面仅仅是使用了最简单的方法,由于是在想不出,在网上也找不到我认可的方式,所以暂时搁置。先发表一个版本以期后期完善。
  • 相关阅读:
    递推&&矩阵加速
    洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes
    总结一下当前阶段我认为比较常用的字符串操作
    关于递归与递推
    P1553 数字反转(升级版)
    关于C++读入数字按位取出与进制转换问题
    一本通题库 1058:求一元二次方程
    弄懂goroutine调度原理
    线程实现模型
    gin-jwt对API进行权限控制
  • 原文地址:https://www.cnblogs.com/blogWU/p/7531726.html
Copyright © 2020-2023  润新知