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

目录

一.需求分析

二.功能设计

三.设计实现

四.算法详解

五.测试运行

六.不足与改进

七.项目总结

八.PSP展示

 代码仓库地址:https://dev.tencent.com/u/tangjy149/p/originTang/git

一、需求分析

1.输入参数n,随机产生n道加减乘除

2.数字在1-100,运算符3-5个

3.无负数和非整数

4.一个算式最少两种运算符

5.附带学号输出result.txt文件

 

二、功能设计

基本功能:四则运算,随机产生n道算式

扩展功能:能够计算括号

 

三、设计实现

1.项目目录

我希望通过四个类来实现所有功能

  • Main为主函数,负责作为输入和运行的入口
  • dateFile为辅助,用于进行文件创建和读写
  • random为辅助,用于产生随机的算式
  • caculate为核心,用于计算随机产生的算式并返回结果

2.整体思路:

1)先生成随机生成一个运算符和两个运算数的算式,进行结果运算,查看是否符号无负数和无小数的要求。在满足要求后,将该算式结果作为下一次生成算式的因子,用连接符再进一步连接,直到组成3-5个运算符的算式(随机生成的工作结束,输出一个字符串)

2)通过逆波兰表达式,对产生的字符串进行解析计算

 

四、算法详情

1.随机生成算式

static String[] symAll = { "+", "-", "*", "÷" };// 设置操作符的集合
	static String[] sym = { "+", "*" };// 连接两个简单等式时的操作符
	static int flag = 0;// 标记简单等式产生减号或加号的情况,由此确定是否生成括号
    int ifsame=0;//判断符号相同
    int answer=0;//判断为非负
	public static String make() {
		int x = (int)(Math.random()*101);
        int y = (int)(Math.random()*101);
        int z = (int)(Math.random()*4);
        if(z==1) {
        	if(x<y) {
        		int temp=x;
        		x=y;
        		y=temp;
        	}
        }
        if(z==3) {
        	y = (int) (Math.random() * 20) + 1;
			x = (int) (Math.random() * 6) * y;
        }
        String str = x + symAll[z] + y;
		if (symAll[z].equals("-") || symAll[z].equals("+")) {// 减号时使flag等于1
			flag = 1;

		}
		return str;
        

2.解答算式的算法

首先,将字符串通过substring进行逐个提取,每一个进行检验,从左到右将数字和符号分开

之后,设置两个栈,一个用于放置操作符,一个用于放置结果

Stack<String>symbolStack = new Stack<String>();//放置操作符的栈
		Stack<String>numberStack = new Stack<String>();//放置最后结果的栈
		Iterator<String>iter = list.iterator();
		while(iter.hasNext()) {
			String listItem = iter.next();//分开放置
			//检测是否为符号
			if(isSymbol(listItem)) {
				//当检测到),需要一直出栈,直到检测到(,该过程中还需要检测栈空
				if(")".equals(listItem)) {
					while (!(symbolStack.isEmpty() || "(".equals(symbolStack.peek()))){
						numberStack.push(symbolStack.pop());//操作符栈的栈顶元素进入结果栈
					}
					//当检测到(
					if(!symbolStack.isEmpty() && "(".equals(symbolStack.peek())) {
						symbolStack.pop();
					}else {
						throw new Exception("异常");
					}
				}
				//当检测到(,直接入栈
				else if("(".equals(listItem)) {
					symbolStack.push(listItem);
				}
				//当遇到除(、)之外的运算符,则对运算符优先级进行比较,高则入栈,反之出栈并进入结果栈
				else {
					while (!(symbolStack.isEmpty() || "(".equals(symbolStack.peek()))) {
						if(compareSymbol(listItem,symbolStack.peek())<1) {
							numberStack.push(symbolStack.pop());
						}else {
							break;
						}
					}
					symbolStack.push(listItem);
				}
			}
			//非操作符,入栈操作
			else {
				numberStack.push(listItem);
			}
		}

当检测到)时,则把操作符栈弹出,并且置入最后结果的栈中,直到遇到(停止

当检测到(时,直接进入操作符栈

当检测到其他操作符,与栈顶运算符比较,如果比栈顶等级高,则进入操作符栈

否则操作符栈弹出,并且置入结果栈,再重复以上操作

 

最后,将符号栈中的元素全部置入结果栈中。因为栈是先进后出,所以还需要逆序遍历之后,得到最后的后缀表达式

对后缀表达式求值

private static int finalCalculate(List<String> finalList) {
		Stack<Integer> answerStack = new Stack<Integer>();
		Iterator<String>iter = finalList.iterator();
		int x,y;
		while(iter.hasNext()) {
			String answerItem = iter.next();
			if(isSymbol(answerItem)) {
				x = answerStack.pop();
				y = answerStack.pop();
				answerStack.push(calculate(y,x,answerItem));
//				System.out.println(answerStack);
			}
			else {
				answerStack.push(Integer.parseInt(answerItem));
//				System.out.println(answerStack);
			}
		}
//		System.out.println(answerStack);
		return answerStack.pop();

五、测试运行

 

六、不足

1.最开始的时候写出两个运算符的算式时,没有想清楚后续,导致当时写的代码全部被推倒重做了

2.对于转为后缀表达式上,花了很多时间,才能勉强看懂

3.代码开始可以在eclipse上成功运行,但是在命令行中却没办法运行,这个问题一直没有得到解决。最后找了很久才发现是环境变量上有问题,这和自己不仔细很有关系

 

七.项目总结

1.项目实现上没有很好的连贯性,推倒重做了几次,因为需求分析时没有做细致,下次需要改善

2.项目整体上实现了基本功能和部分拓展功能。

3.项目比我想象中更难,花费的时间也是超多。Java语言方面运用不纯熟也是一个时间花费的点,这次项目也帮我巩固了复习了一遍java(甚至是预习)。

八、PSP展示

PSP任务内容计划时间(h)完成时间(h)
Planning计划0.50.5
Estimate预估0.50.5
Development开发7.214.75
Analysis需求分析0.250.5
Design Spec生成文档00
Design Review设计复审00
Coding Standard代码规范00.5
Design具体设计0.450.75
Coding具体编码510
Code Review代码复审11
Test测试0.52
Reporting报告12.5
Test Report测试报告0.51.5
Size Measurement计算工作量00
Postmortem & Process Improvement Plan事后总结0.51

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值