结对项目

这个作业属于哪个课程 <网络1934-软件工程>
这个作业的要求在哪里 <作业要求>
这个作业的目标 实现一个自动生成小学四则运算题目的命令行程序

github链接

一、PSP表格

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

二、效能分析

效能测试代码:

package main

import "testing"

func BenchmarkGenerate(b *testing.B) {
	n = 10000
	r = 10

	for i := 0; i < b.N; i++ {
		generateProblems()
	}

}

func BenchmarkChekc(b *testing.B) {
	exercisefile = "exercisefile.txt"
	answerfile = "answerfile.txt"
	for i := 0; i < b.N; i++ {
		check()
	}
}

结对项目
结对项目
产生题目耗时(执行4次):生成10000道题目平均耗时不到1s
结对项目
阅卷模式耗时(执行1290次)

三、设计实现过程

核心思想:
算式计算:将运算式通过转化成逆波兰式来计算,双向链表代替栈来计算逆波兰式。
可以参考,里面波兰式讲的很全.
整数和真分数计算:用FAL分数结构来代替数值类型,整数也用FAL表示,支持加减乘除等分数类型的操作,需要加入真假分数的转换。
查重:时间原因,只是把结果重复的去掉。
异常:会出现除零,只能全局定义个bool来判断是否除零,处理结果跟查重一样,丢弃掉。
主要结构及其作用:
结对项目
结对项目
结对项目

结对项目
FAL和Sign都实现了Value接口的Len()类型
结对项目

四、代码说明

//计算结果
func (p *Problem) Cal() *FAL {
	var ll *list.List
	//cnt := 0
	ll = new(list.List)
	for ele := p.postfixExpress.Front(); ele != nil; ele = ele.Next() {
		//cnt++
		kv := ele.Value.(*Entry)
		if kv.kind == 1 {//kind=1,代表该元素不是运算符号
			ll.PushBack(kv)
		} else {
			//fmt.Println(ll.Len(), kv.value.(*Sign).s)
			ele1 := ll.Back()
			ll.Remove(ele1)
			ele2 := ll.Back()
			ll.Remove(ele2)
			kv1 := ele1.Value.(*Entry)
			kv2 := ele2.Value.(*Entry)
			fal1 := kv1.value.(*FAL)
			fal2 := kv2.value.(*FAL)
			sign := kv.value.(*Sign)
			//fmt.Println(fal1, fal2)
			switch sign.s {
			case '-':
				fal2 = Sub(fal2, fal1)
			case '+':
				fal2 = Add(fal2, fal1)
			case '×':
				fal2 = Mul(fal2, fal1)
			case '÷':
				fal2 = Div(fal2, fal1)
			}
			//将结果压入栈中
			ll.PushBack(&Entry{
				kind:  1,
				value: fal2,
			})
		}
	}
	//fmt.Println(cnt)
	return ll.Back().Value.(*Entry).value.(*FAL)
}
func main() {
	s := time.Now()
	rand.Seed(time.Now().UnixNano())
	len := len(os.Args)
	//必须输入两个参数-n -r或者-e -a
	if len < 5 {
		Usage()
	}
	ParseArgs()
	//生成题目
	if n > 0 {
		generateProblems()
	}
	//阅卷模式
	if exercisefile != "" && answerfile != "" {
		check()
	}
	fmt.Println(time.Since(s))
}

五、运行测试

生成1w道题目
结对项目

结对项目

阅卷模式
结对项目

结对项目

六、项目小结

四则运算这个项目细节需要考虑的比较多,将字符串类型的算式通过一些方法计算出结果,需要细心分析,我因为没有完成一个模块就进行一次测试,所以花费了较长时间去调试,吸取教训,下次不会了。

上一篇:RT-Thread—STM32—在线升级(Ymodem_OTA、HTTP_OTA)


下一篇:Java中的泛型生产者和消费者