这是软件工程课程布置的第一次作业,内容如下:
1、写一个能自动生成小学生四则运算题目的命令行“软件”,分别满足下面的各种需求,下面这些需求都可以用命令行参数的形式来指定:
a)除了整数以外,还要支持真分数的四则运算。(例如:1/6+1/8=7/24)
b)让程序能接受用户输入答案,并判断对错,最后给出总共对/错的数量。
c)逐步扩展功能和可以支持的表达式类型,最后希望能支持下面类型的题目(最多10个运算符,括号的数量不限制):25-3*4-2/2=89=? 1/2+1/3-1/4=? (5-4)*(2+28)=?
d)一次可以批量出100道以上的题目,保存在文本文件中,并且保证题目不能重复,(1+2)和(2+1)是重复的题目,怎么保证题目不被重复呢,请看详细题目要求?
如果不考虑a、b、c、d这四个要求,这个程序非常简单。利用C++来完成这个题目,只需要通过两个函数:srand()和rand(),就可以生成各种不同的随机数,利用这些随机数就可以组合成许多不同的四则运算题目。
要求a:
根据a中条件,我们除了需要生成随机的整数之外,还需要生成真分数。若把1/6或1/8这样的分数看作一个整体,那么它包含三个部分:分子、分数线和分母。很容易想到,通过rand()能生成不同的随机数,用这些随机数作为真分数的分子和分母。唯一要值得注意的是,真分数相比整数有了两个限定条件,a)是分子必须小于分母;b)分母和分子都不为零。
这个两个条件并不难以满足,以生成分子和分母都在10以内的真分数为例:
rand()%11能生成0-10的随机数,那么只用修改一下,使得原始代码变为rand()%10+1,即可生成1-10的随机数
为了使分子能小于分母,首先令分子A=rand()%9+1(生成0-9的随机数);那么分母B就可以写成B=A+rand()%(10-A)+1,这样就能保证分子永远小于分母了。
要求b:
b中要求能让用户输入答案并判断答案对错。这一步其实理论上也不难,设置一个记录分数的变量 int score = 0;让计算机先计算出算式的答案,再让用户输入,如果正确则使score++;这样就能统计出正确答案的数量。
要求c:
要求C中要使生成的表达式更长,拥有更多运算符和括号。和前面所说的一样,所有数字和运算符都可以利用rand()函数来进行添加,但由于所生成的表达式长度不确定且符号不确定,需要先将表达式用string类来表示,利用栈的思想来求值,具体算法如下:
1、生成操作数栈(OPND)用于存储表达式中的字符、数字或运算结果等;生成运算符栈(OPTR)用于寄存运算符。
2、表达式是否结束?是的,OPND栈底元素就是运算结果;否则,当前的输入是字符吗?是的,字符进栈OPND;否则,将该运算符和栈OPTR的栈顶元素进行比较:
A.如果OPTR栈顶元素优先级别低,则将该元素进栈OPTR;
B.如果优先级别相等,则OPTR出栈一次;
C.如果OPTR栈顶元素优先级别高,则OPTR出栈一次,OPND出栈两次,然后进行运算,将结果进栈OPND;
3、读入下一个字符,跳到(1)。
要求d:
为了能将生成的表达式输入打txt文件中,需要用到stream类,ofstream能将数据从内存写入硬盘,具体的用法为:ofstream 对象("文件名.txt");……;对象<<写入内容参数。要像不生成重复的表达式,可以利用string类去储存每次一生成的表达式,再生成的新表达式与原有进行比较,若重复则直接跳过后续操作。