这个作业属于哪个课程 | 广工2023软件工程课程社区-CSDN社区云 |
---|---|
这个作业要求在哪里 | 结对编程:小学四则运算 |
这个作业的目标 | 自动生成四则运算及计算 |
其他参考文献 | csdn,掘金,gitcode |
目录
1.gitcode地址
2.PSP表格
*PSP2.1* | *Personal Software Process Stages* | *预估耗时(分钟)* | *实际耗时(分钟)* |
---|---|---|---|
Planning | 计划 | 40 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 600 | 1050 |
Development | 开发 | 100 | 120 |
· Analysis | · 需求分析 (包括学习新技术) | 100 | 50 |
· Design Spec | · 生成设计文档 | 30 | 10 |
· Design Review | · 设计复审 | 50 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
· Design | · 具体设计 | 50 | 50 |
· Coding | · 具体编码 | 360 | 600 |
· Code Review | · 代码复审 | 20 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 55 | 20 |
Reporting | 报告 | 60 | 30 |
· Test Repor | · 测试报告 | 20 | 20 |
· Size Measurement | · 计算工作量 | 20 | 60 |
sum | 总计 | 1360 | 1500 |
3.模块接口的设计
1.模块接口设计图
2.模块主要功能
函数名称 | 函数功能说明 |
---|---|
Node1 Calculator(Node1 a, Node1 b, int c) | 计算两个数得到结果 |
void Simplify(int fenzi, int fenmu, char string[]) | 分数化简 |
char* creatmath() | 生成运算式子 |
int level(char op) | 判断操作符的优先级 |
Status get_Answer(char result[], int y) | 计算答案 |
char* creatFormula(int y) | 写入文本文件 |
4.算法实现
程序通过定义分数型变量,通过运算数以及运算符两个结构体,以及由这些结构体构成的两个栈实现基本的要求,主要的函数实现有:
1.生成运算式子
creatmath():生成运算式子算法实现:通过使用三个随机变量随机控制括号的生成以及生成位置(不过有些地方括号生成的概率会相对较小)。同时通过调用creat_Num()生成运算数,运算数中包含整数和分数,同样也是通过控制随机变量确定获取到的是整数还是分数;并通过调用creatOperator()生成运算符,要注意调用这两个函数返回的都是字符指针型的变量,因此原函数主要是通过C库strcat()连接字符串去实现算法,同时在调用生成运算式子算法的时候,要注意中间与最后都不能产生负数。
2.分数简化
Simplify():分数简化算法实现:分数简化算法其中的重要一环就是求最大公因式gad()函数;
分数的简化也分为两个部分,一是分数的约分,二是假分数化成带分数,函数返回化简后的分数的一串字符串
3.结果计算
get_Answer(): 计算结果算法实现:计算结果主要得益于运算符优先级函数level()的判断,通过对运算数栈和运算符栈的入栈出栈,同时计算中间值(因为运行过程中不能产生负数),最后用answer1数组存储结果
5.模块流程图
6.性能分析
1.性能分析图
2.主要代码
1.生成运算式代码
//生成式子(三个运算符及以下,有概率出现括号)
char* creatmath() {
srand((unsigned)time(NULL) + rand());
char string[MAXSIZE] = {};
char* posture = string;
char c[MAXSIZE] = {};
int i = rand() % 3;
int j = 0, k = 0;
if (i != 0) {
j = rand() % 2;
if (j == 1) {
strcpy(c, "(");
strcat(string, c);
}
}
strcpy(c, creat_Num());
strcat(string, c);
strcpy(c, creatOperator());
strcat(string, c);
strcpy(c, creat_Num());
strcat(string, c);
if (i == 0) {
return string;
}
else {
if (j == 1) {
k = rand() % 2;
if (k == 1) {
strcpy(c, ")");
strcat(string, c);
j = 0;
}
}
strcpy(c, creatOperator());
strcat(string, c);
if (i == 2 && j == 0) {
k = rand() % 2;
if (k == 1) {
strcpy(c, "(");
strcat(string, c);
j = 1;
}
}
strcpy(c, creat_Num());
strcat(string, c);
if (i != 2) {
if (j == 1) {
strcpy(c, ")");
strcat(string, c);
j = 0;
}
return string;
}
if (i == 2) {
strcpy(c, creatOperator());
strcat(string, c);
strcpy(c, creat_Num());
strcat(string, c);
if (j == 1) {
strcpy(c, ")");
strcat(string, c);
j = 0;
}
return string;
}
}
}
2.计算答案代码
//计算答案
Status get_Answer(char result[], int y) {
SqStack1 S_num; //分数栈
SqStack2 S_operato; //运算符 栈
int i = 0, j = 0;
Linklist1 A, B;
Node1 C;
int D;
FILE* fp;
InitStack_Sq1(S_num);
InitStack_Sq2(S_operato);
fp = fopen("answer.txt", "a");
while (result[i] != '\0' || StackEmpty_Sq(S_operato) != OK)
{
if (result[i] >= '0' && result[i] <= '9')
{
j = j * 10 + result[i] - '0';
i++;
if (result[i] > '9' || result[i] < '0')
{
Push_SqStack1(S_num, j, 1);
j = 0;
}
}
else
{
if (check1(result[i], S_operato) == OK)
{
Push_SqStack2(S_operato, result[i]); //运算符 进栈
i++;
continue;
}
if (result[i] == ')' && Get_Top(S_operato) == '(')
{
Pop_SqStack2(S_operato);
i++;
continue;
}
if (check2(result[i], S_operato) == OK)
{
A = Pop_SqStack1(S_num);
B = Pop_SqStack1(S_num);
D = Pop_SqStack2(S_operato)->data;
C = Calculator(*A, *B, D); //计算中间值
Push_SqStack1(S_num, C.molecule, C.denominator); //中间值为正值,入栈
continue;
}
}
}
if (C.molecule < 0)
{
fclose(fp);
return -1; // 负数就返回 -1
}
char answer1[20] = {}; //用来存放答案
Simplify(C.molecule, C.denominator, answer1); //返回简化后的答案
count++;
fprintf(fp, "%d.%s\n", y, answer1);
fclose(fp);
return 1;
}
7.结果测试
命令行输入
生成式子
生成结果
8.总结
这次的作业对我来说有点难,再加上找不到人组队就自己做了,下次再让我选的话应该不会接着用c了呃呃。