• 第三次作业


    第二次作业:MathExam

    一、预估与实际

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 20 30
    • Estimate • 估计这个任务需要多少时间 240
    Development 开发 120 240
    • Analysis • 需求分析 (包括学习新技术) 60 60
    • Design Spec • 生成设计文档 60 60
    • Design Review • 设计复审 10 10
    • Coding Standard • 代码规范 (为目前的开发制定合适的规范) 10 10
    • Design • 具体设计 20 20
    • Coding • 具体编码 60 120
    • Code Review • 代码复审 40 60
    • Test • 测试(自我测试,修改代码,提交修改) 15 20
    Reporting 报告 60 80
    • Test Repor • 测试报告 20 20
    • Size Measurement • 计算工作量 10 10
    • Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 20 20
    合计 760

    二、需求分析

    经过分析,我认为,这个程序应当:

    • 运算中可以添加括号,改变基础的四则运算的顺序。(运算符在2~4个且至少两个不同的运算符)未实现
    • 不能出现小数,题目中出现的数字和答案结果都必须是整数
    • 减法运算的结果不能有负数,除法运算除数不能为0,且所有的数字不能是余数,且保留小学一二年级的运算的出题功能。

    三、设计

    1. 设计思路

    首先考虑题目的要求:

    • 输入格式:程序需从命令行中接收两个参数 年级 和 题目数量,分别用 -n 和 -grade 表示
    • 输出格式:把题目和标准答案写入out.txt文件,输出的格式要求:
      (1)每道题目占一行
      (2)每道题的格式
      • 题号:数字 + 一对英文括号
      • 题目:数字、符号之间空一格
      • 题号与题目之间也需要加一空格,行末不需要加空格

    2. 实现方案

    • 准备工作:学会逆波兰表达式,考虑题目的输出,括号的优先级
    • 技术关键点:先要掌握逆波兰表达式的含义,以及为什么要使用逆波兰表达式,为什么不能使用符合平时我们更适应的中缀表达式。
      运算表达式的种类:
    • 1.中缀表达式 a + b,运算符号在两个运算对象的中间。
    • 2.前缀表达式+ - a * b c d,运算符在运算对象前面,又称为波兰表达式。
    • 3.后缀表达式 a b c * - d +,运算符在运算对象后面,又称为逆波兰表达式。
      后缀表达式的优点:
    • 1.相较于前缀表达式更易于转换,最左边一定为数字。
    • 2.更符合计算机的计算方式。计算机通过从左至右读取后缀表达式,就可以将遇到的运算对象压入栈,在遇到运算符时就弹出两个运算对象,完成计算,再将结果压入栈。最后留在栈中的就是计算结果。
      中缀表达式转换为后缀表达式的方法:例:a + b * c - (d + e)
    • 1.按照运算符的优先级对所有的运算单位加括号。((a + (b * c)) - (d + e))
    • 2.转换中缀与后缀表达式后缀:把运算符号移动到对应的括号后面。((a (b c) * ) + (d e) + ) -
    • 3.把括号去掉,得到后缀表达式a b c * + d e + -
      首先确定四则运算的加减乘除的优先级。得到后缀表达式后,通过匹配字符,创建两个栈:输出栈和符号栈,如果匹配到的字符是数字的话,直接压入输出栈,如果匹配到运算符号,则压入符号栈,如果当前元素的优先级小于等于栈顶元素的优先级,出栈并顺序输出运算符。若当前元素的优先级大于栈顶元素的优先级,则直接入栈。

    四、编码

    1. 关键代码

    private static void problems(int n, int grade) {
    	String[] fuhao = { " + ", " - ", " * ", " / " };
    	String fengge = "
    ";
    	Random rand = new Random();
    	String a = "";
    	int S_num1 = (rand.nextInt(101));
    	int i = 0;
    	String S_wenti = S_num1 + "";
    
    	if (grade == 1) {
    		for (i = 1; i <= n; i++) {
    			int operator = (int) (Math.random() * 2);
    			if (operator == 0) {
    				int num1 = (int) (Math.random() * 10);
    				int num2 = (int) (Math.random() * 10);
    				result = num1 + num2;
    
    				wenti.append("(" + i + ") " + num1 + " + " + num2 + "
    ");
    				daan.append("(" + i + ") " + num1 + " + " + num2 + " = " + result + "
    ");
    			} else if (operator == 1) {
    				int x = (int) (Math.random() * 10);
    				int y = (int) (Math.random() * 10);
    				result = x - y;
    
    				wenti.append("(" + i + ") " + x + " - " + y + "
    ");
    				daan.append("(" + i + ") " + x + " - " + y + " = " + result + "
    ");
    			}
    		}
    		System.out.println(wenti);
    		System.out.println(daan);
    
    	}
    
    	else if (grade == 2) {
    		for (i = 1; i <= n; i++) {
    			int operator = (int) (Math.random() * 2);
    			if (operator == 0) {
    				int num1 = (int) (Math.random() * 10);
    				int num2 = (int) (Math.random() * 10);
    				result = num1 * num2;
    
    				wenti.append("(" + (i + 1) + ") " + num1 + " * " + num2 + "
    ");
    				daan.append("(" + (i + 1) + ") " + num1 + " * " + num2 + " = " + result + "
    ");
    			} else if (operator == 1) {
    				int x = (int) (Math.random() * 10);
    				int y = (int) (Math.random() * 10);
    				if (y == 0) {
    					System.out.println("除數不能为零");
    				}
    				if (x % y == 0) {
    					result = x / y;
    					wenti.append("(" + i + ") " + x + " / " + y + "
    ");
    					daan.append("(" + i + ") " + x + " / " + y + " = " + result + "
    ");
    
    				}
    				if (x % y != 0) {
    					result = x / y;
    					wenti.append("(" + i + ") " + x + " / " + y + "
    ");
    					daan.append("(" + i + ") " + x + " / " + y + " = " + result + "..." + (x % y) + "
    ");
    				}
    			}
    		}
    		System.out.println(wenti);
    		System.out.println(daan);
    	}
    
    	if (grade == 3) {
    		outLoop:for (i = 1; i <= n; i++) {
    			int OPNum = (rand.nextInt(3) + 2);
    			int S_num2 = (rand.nextInt(100) + 1);
    			S_wenti = S_num2 + "";
    			for (int j = 1; j <= OPNum; j++) {
    				int S_num = S_num2;
    				S_num2 = (rand.nextInt(1000) + 1);
    				int op = (rand.nextInt(4));
    				if (op == 0) {
    					if (S_num + S_num2 > 1000) {
    						j--;
    						continue;
    					}
    				} else if (op == 1) {
    					if (S_num - S_num2 < 0) {
    						j--;
    						continue;
    					}
    			} else if (op == 2) {
    					if (S_num1 * S_num2 > 10000) {
    						j--;
    						continue;
    					}
    				} else if (op == 3) {
    					if (S_num1 % S_num2 != 0 || S_num2 == 0) {
    						j--;
    						continue;
    					}
    				}
    				a = S_wenti + S_num1 + fuhao[op] + S_num2;
    				S_wenti += fuhao[op] + S_num2;
    				if (Integer.parseInt(answers(S_wenti))<0 || Integer.parseInt(answers(S_wenti))>100000) {
    					i--;
    					continue outLoop;
    				}
    			}
    			
    			wenti.append("(" + i + ") " + S_wenti + "
    ");
    			
    			daan.append("(" + i + ") " + S_wenti + " = " + answers(S_wenti) + "
    ");
    			//S_num1 = (rand.nextInt(1001));
    			//S_wenti = S_num1 + "";
    		}
    		System.out.println(wenti);
    		System.out.println(daan);
    	}
    
    }
    
    public static String answers(String S_wenti) {
    	Stack<String> number1 = new Stack<String>();
    	Stack<String> op_Stack = new Stack<String>();
    	String stc = S_wenti.replace(" ", "");
    	String number = "";
    	for (int i = 0; i < stc.length(); i++) {
    		char c = stc.charAt(i);
    		if (c >= '0' && c <= '9') {
    			number += c + "";
    			if (i + 1 >= stc.length()) {
    				number1.push(number);
    				number = "";
    			}
    		} 
    		else {
    			if (!number.isEmpty()) {
    				number1.push(number);
    				number = "";
    			}
    			
    			if (!op_Stack.empty() && comparePriority(c + "", op_Stack.peek()) < 1 ) {
    				while (!op_Stack.empty() && comparePriority(c + "", op_Stack.peek()) < 1) {
    
    					int a = Integer.parseInt(number1.pop());
    					int b = Integer.parseInt(number1.pop());
    					int d;
    					String stackTop = op_Stack.peek();
    					if (stackTop.equals("+")) {
    						d = b + a;
    					} else if (stackTop.equals("-")) {
    						d = b - a;
    					} else if (stackTop.equals("*")) {
    						d = b * a;
    					} else {
    						d = b / a;
    					}
    					number1.push(d + "");
    					stackTop = op_Stack.pop();
    				}
    
    				op_Stack.push(c + "");
    			}
    			else
    				op_Stack.push(c+"");
    		}
    
    	}
    
    	while (!op_Stack.empty()) {
    		String stackTop = op_Stack.pop();
    		int a = Integer.parseInt(number1.pop());
    		int b = Integer.parseInt(number1.pop());
    		int d;
    		if (stackTop.equals("+")) {
    			d = b + a;
    		} else if (stackTop.equals("-")) {
    			d = b - a;
    		} else if (stackTop.equals("*")) {
    			d = b * a;
    		} else {
    			d = b / a;
    		}
    		number1.push(d + "");
    	}
    
    	return number1.peek();
    }
    
    private static int comparePriority(String a, String b) {
    	if (a.equals(b)) {
    		return 0;
    	} else if (adv(a) > adv(b)) {
    		return 1;
    	} else if (adv(a) < adv(b)) {
    		return -1;
    	} else {
    		return 0;
    	}
    }
    
    private static int adv(String op) {
    	if (op.equals("*") || op.equals("/")) {
    		return 2;
    	} else if (op.equals("+") || op.equals("-")) {
    		return 1;
    
    	}
    	// if(op.equals("(")){
    	// return 0;
    	// }
    	return 0;
    
    }
    

    五、测试

    第一组:10 3
    输出结果:(1) 14 * 314 - 33
    (2) 49 + 7 + 130 - 17 + 208
    (3) 41 + 640 - 408
    (4) 73 + 581 * 109
    (5) 90 + 142 * 255 + 119 + 373
    (6) 54 - 19 + 449 * 123
    (7) 65 - 43 + 682 + 168 - 12
    (8) 29 + 361 + 122
    (9) 90 + 342 * 281 + 373 + 264
    (10) 6 + 734 + 309

    (1) 14 * 314 - 33 = 4363
    (2) 49 + 7 + 130 - 17 + 208 = 377
    (3) 41 + 640 - 408 = 273
    (4) 73 + 581 * 109 = 63402
    (5) 90 + 142 * 255 + 119 + 373 = 36792
    (6) 54 - 19 + 449 * 123 = 55262
    (7) 65 - 43 + 682 + 168 - 12 = 860
    (8) 29 + 361 + 122 = 512
    (9) 90 + 342 * 281 + 373 + 264 = 96829
    (10) 6 + 734 + 309 = 1049

    六、总结

    本次作业的主要问题是没有认真学懂后缀表达式,出错的地方还有*/和后面的×÷没有匹配,所以找了很久问题都没有发现

  • 相关阅读:
    input file 上传图片并显示
    关于npm ---- npm 命令行运行多个命令
    webpack4.x 配置
    React的生命周期
    HTML5 meta 属性整理
    css 命名规范
    html5 标签 meter 和 progress
    .NET Linq TO XML 操作XML
    .NET 字符串指定规则添加换行
    Linux Centos上部署ASP.NET网站
  • 原文地址:https://www.cnblogs.com/L960416/p/9673775.html
Copyright © 2020-2023  润新知