代码地址:https://coding.net/u/yukongping/p/work2/git/tree/master/
一、需求分析
(1)需求:设计编写一个程序关于四则运算练习的出题库
(2)分析:
·设计约束:
(1) 使用C语言编程;
(2)每个练习题至少要包含2种运算符;
(3)软件所出练习题在运算过程中没有负数与非整数的出现;
(4)运算数字限制在0~100之间,运算符在3至5个之间。
·功能性需求:
(1)程序可接收一个输入参数n,然后随机产生n道加减乘除(分别用+、-、*、÷运算符来表示)练习题
(2)练习题生成后,将学号与生成的n道练习题及其对应的正确的答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致
二、功能设计
(1)接收输入参数n并且屏幕出现n道四则运算题;数值范围在0-100之间;每个练习题至少要包含2种运算符;
(2)运算结果不得出现负数与非整数;
(3)将学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中。
三、设计实现
(一)整体思路:
1、首先由屏幕输入参数n,n代表四则运算的个数,然后由随机函数生成n道四则运算,显示出来。
2、每道四则运算的生成过程:
①每次生成四则运算表达式中一个数和一个运算符号→判断0和除号不能同时出现→判断第一个运算符和第二个运算符,确定优先级(5+6/2)和→进行计算。
②若运算符号为乘(或除)→根据上次f记录运算符作运算→上次为加,作加法;上次为减,作减法;上次为乘,作乘法,上次为除,作除法。
③若运算符号为加(或减)→根据上次f记录运算符作运算→上次为加,作加法;上次为减,作减法;上次为乘,先作乘法,再作加法;上次为除,先作除法在作加法。
④根据③确定的优先级计算得出结果。
四、算法详解
(1)一次读入一个数和一个运算符号,若当前运算符号是乘除,根据上次运算符号,做完运算,结果放入cf暂存;
if ( s[y] == '*' || s[y] == '/' )
{
if ( f == 0 )
{
cf *= x;
}else if ( f == 1 )
{
cf *= -x;
}else if ( f == 2 )
{
cf *= x;
}else {
cf /= x;
}
}
(2)若当前运算符号为加减,根据上次运算符号,先做完乘除,加到结果中,在作加减。
if ( f == 0 )
{
ans += x;
}else if ( f == 1 )
{
ans -= x;
}else if ( f == 2 )
{
cf *= x;
ans += cf;
cf = 1;
}else {
cf /= x;
ans += cf;
cf = 1;
}
五、测试运行
六、代码展示
随机函数:
srand( time( NULL ) ); /* 用系统当前时间设置rand()随机序列种子,保证每次运行随机序列不一样 */
存入文件:
FILE *fp = fopen( "./result.txt", "a+" );
if ( fp == 0 )
{
printf( "can't open file\n" );
return(0);
}
fseek( fp, 0, SEEK_END );
fputs( "2018103006\n", fp );
判断优先级:
if ( s[y] == '*' || s[y] == '/' )
{
if ( f == 0 )
{
cf *= x;
}else if ( f == 1 )
{
cf *= -x;
}else if ( f == 2 )
{
cf *= x;
}else {
cf /= x;
}
}else {
if ( f == 0 )
{
ans += x;
}else if ( f == 1 )
{
ans -= x;
}else if ( f == 2 )
{
cf *= x;
ans += cf;
cf = 1;
}else {
cf /= x;
ans += cf;
cf = 1;
}
}
f = y; /* 记录上一次运算符,比较。 */
}
z = rand() % 100 + 1;
if ( f == 0 )
{
ans += z;
}else if ( f == 1 )
{
ans -= z;
}else if ( f == 2 )
{
cf *= z;
ans += cf;
cf = 1;
}else {
cf /= z;
ans += cf;
cf = 1;
}
排除表达式中一种运算符:
/* flag 表示是否遇到了不相等的元素 */
for ( k = 2; k < n - 1; k++ )
{
if ( c[k] != c[1] ) /* 遇到了不等于x[0]的元素,设置 flag = 1,然后跳出循环 */
{
flag = 1; break;
}
}
if ( flag == 0 ) /* 输出判断结果 */
{
i--;
continue;
}
写入文件并且显示结果:
char now[3];
itoa( z, now, 10 );
strcat( d, now );
char res[30];
itoa( ans, res, 10 );
strcat( d, "=" );
strcat( d, res );
strcat( d, "\n" );
fwrite( d, strlen( d ), 1, fp );
cout << d;
fclose( fp );
七、总结
本来以为项目比较简单,感觉两三天可以做完,但是实际上花了一周时间在图书馆钻研。在敲代码的过程中遇到很多问题,一遇到问题就得停下来去找相应的解决方法,经常是代码写了又删,删了又写,效率比较低,以后一定要事先设计,想好整个流程再写代码。通过这次作业,我感受到了算法在项目中的重要性,算法是一个项目的灵魂。
虽然做的很疲惫却也很充实,让我感受到了全身心投入一件事情的快乐,专注与钻研,我喜欢这样的感觉。同时,也让我意识到自己的水平远比想象中的低,做一个四则运算就让我费了这么大的劲,说明我的水平真的还不够,我要好好努力。
八、展示PSP
psp | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
planning | 计划 | 30 | 20 |
Estimate | 估计这个任务需要多少的时间,并且规划大致工作步骤 | 30 | 20 |
Development | 开发 | ||
Analysis | 需求分析(包括学习新技术) | ||
Desgin Spec | 生成设计文档 | ||
Design | |||
– | – | ||
Review | 设计复审 (和同事审核设计文档) | ||
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | ||
Design | 具体设计 | ||
Coding | 具体编码 | ||
Code Review | 代码复审 | ||
Test | 测试(自我测试,修改代码,提交修改) | Reporting | |
Test Report | 测试报告 | ||
Size Measurement | 计算工作量 | ||
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 |