您的位置:首页 > 其它

高级软件工程第二次作业--四则运算生成器

2017-09-27 20:37 411 查看

1 项目 GitHub 地址

https://github.com/shuangshuanggit

2 预估耗时与实际耗时

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

3 解题思路

为了稍微好上手,还是选择了最熟悉的C语言。

1.根据要求,随机生成四则运算的长度(操作符个数小于10),n=rand()%10+1,生成操作数个数;

2.操作数随机生成,保存在整形数组a
中,其中a[2i]时保存的1~100的数字,rand()%100+1,所以后面不会再考虑除数是否为0;

3.把分数也看成除法,所以整个式子就是整数的加减乘除,在这里,把a[2i+1]里面的数看成操作符,rand()%4-4,随机生成的-4、-3、-2、-1分别代表“+”、“-”、“*”、“/”;

4.能够保存用户的输入,并判断对错,我的想法是把最后结果转化为字符串,用户的输入也用字符串保存(如果输入为整数则只与最后结果‘/’之前的字符串进行比较),进行字符串匹配,判断是否正确;

5.计算正确率,只需要用一个count来记录即可,最后count*100/n,然后用%.2f表示即可;

6.其中关键就是如何计算这个四则运算式,在我考虑了乱七八糟的很长时间后,室友提醒我用逆波兰式,然后就百度,看了一位博主的分析,原理分析很细致,然后就顺着这个思路来往下继续写。主要是将结果保存在另外一个整型数组中,得到最终结果后,转化为字符串。

总结一下,大致为: 随机运算符个数、随机操作数、随机运算符保存在数组中-->然后转化为后缀表达式-->计算后缀表达式-->与输入的结果进行匹配

4设计实现和代码说明

有4个被调函数,生成表达数create()函数,转换后缀表达式trans()函数、后缀表达数计算calculate()函数、最大公约数gcd()函数(用于分数化简)。

4.1 随机运算符个数、操作符、运算符的生成

C语言中有生成随机数的函数,因为对每句代码如何写还是不知道,所以每写一句就会百度一下,过程中才知道应该使用srand()函数,然后写在主函数中:

void int main()
{
int n,i,c;
printf("请输入需要生成的四则运算式的个数:");
scanf("%d",&c);
for(i=0;i<n;i++)
{
srand( (unsigned int)time( NULL ) ); //初始化随机数
n=rand()%10+1;//随机生成表达式长度,有1~10个操作符
//生成运算表达式等等操作
}
//其他操作
}


4.2生成运算表达式

随机生成四则运算表达式create()函数:

//计算后缀表达式,并将结果转化为字符串
void calculate(int n,int b[],char rs1[])
{
int    i=0,t,top=0;
int stack[2*(n-1)]={0};
int r[3]={0,-1,1};//保存最后结果,初始情况下,分子为0,分母为,1

//rs1保存最后正确结果的分子
char rs2[2*(n-1)]={' '};//最后结果的分母用字符串表示
t=b[i];i++;
while(i<=2*(n-1))
{
switch(t)
{
case -4:r[0]=r[0]+stack[top]*r[2];top--;break;//+
case -3:r[0]=stack[top]*r[2]-r[0];top--;break;//-
case -2:r[0]=r[0]*stack[top];top--;break;//*
case -1:r[2]=r[2]*stack[top];top--;break;
default: top++;stack[top]=t;
}
t=b[i++];
}
//化简最终结果
r[0]=r[0]/gcd(r[0],r[2]);
r[2]=r[2]/gcd(r[0],r[2]);
//将整形转化成字符串
itoa(r[0],rs1,10);
itoa(r[2],rs2,10);
strcat(rs1,"/");//字符串拼接
strcat(rs1,rs2);

}


calculate()函数

4.5求最大公约数

为了化简最后的分数,所以写了一个求最大公约数的函数。

5.运行结果

运行结果如图:因为之前没有报错,然后就一直在写,只是写的被调函数trans()的测试程序发现闪退,找不到原因,然后想起来用VS测试,但是发现现在来不及了。所以整个代码现在是,没有错,但是跑不出结果的状态,等后面再补充!!!

6.项目小结

虽然是个很小的项目,再看了其他同学的博客后,很多都说很简单,最开始没有形成具体的思路,所以一下子上手总是卡壳。最开始想的是生成的运算符就用字符串保存,后面自己进行不下去了。后面想着看一下其他同学的代码,从他们规范的定义到用重载,这些或许在老师看来很简单的东西,我一下子都有点懵,现在想想,一个星期这么长时间,自己静下心来,足以把这个东西搞明白,但是我没有想其他同学那样,遇到问题,能静下心来一点一点分析,最后自己把知识点琢磨透彻。于是就按照自己特别low的想法来一步一步写,最后的最后还是出现很多问题,这个程序思路很简单,代码量也很小,但是就是出现没有错误,运行不出来的情况,然后我才想起来没有做测试,于是就单独对每个被调函数测试,发现是转化为后缀表达式trans()函数有问题。后面计算函数依然是这样。慢慢体会到测试的重要性,并且也明白,在编程阶段,不能确保当前代码正确的实现功能的时候,千万不能继续往下赶。还有就是同样时间,自己却没有做出来,学习方法和学习策略确实有问题,下来会和同学多交流,也会继续把这个代码结果跑出来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: