四则运算

AHPU-软件工程导论-计算机18级 https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18
作业要求 https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/homework/11377
作业目标 能够熟练撰写博客
学 号 3180701236
一、题目要求

写一个能自动生成小学四则运算题目的程序,然后在此基础上扩展:

1)除了整数以外,还要支持真分数的四则运算,例如:1/6+1/8=7/24

2)程序要求能处理用户的输入,判断对错,累积分数

3)程序支持可以由用户自行选择加、减、乘、除运算
`
4)使用-n参数控制生成题目的个数,例如Myapp.exe -n 10,将生成10个题目

二、代码提交

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
using namespace std;

// 定义一个分式结构体
typedef struct{										
	int top; 
	int bottom;
} fraction;

int maxDivisor(int m, int n);
void reductionFraction(int &m, int &n);
void add(int num,fraction computerFracAns[],int computerIntAns[]);
void subtract(int num, fraction computerFracAns[], int computerIntAns[]);
void multiply(int num, fraction computerFracAns[], int computerIntAns[]);
void divide(int num, fraction computerFracAns[]);


int main(){ 
		// 分数情况下,计算机的答案以及用户的答案 
		fraction computerFracAns[1000], userFracAns[1000];
		// 整数情况下,计算机的答案以及用户的答案
		int computerIntAns[1000] = { 0 }, userIntAns[1000] = { 0 };
		int check;
		char c; 
		int num, score = 0;
		cout<<"四则运算题目生成程序"<<endl;
		cout<<"请选择:"<<endl;
		cout<<"1:加法"<<endl;
		cout<<"2:减法"<<endl; 
		cout<<"3:乘法"<<endl; 
		cout<<"4:除法"<<endl;  
		cin>>check;  // 选择运算方式 
		cout<<"请输入题目数量:";
		cin>>num;										
		switch (check){
			case 1:add(num, computerFracAns, computerIntAns); break;
			case 2:subtract(num, computerFracAns, computerIntAns); break;
			case 3:multiply(num, computerFracAns, computerIntAns); break;
			case 4:divide(num, computerFracAns); break;
		}
		if (check == 4){  // 题目是否为除法分类讨论,分别有不同的处理方案											
			for (int i = 0; i < num; i++){
				cout<<"第"<<i+1<<"道题的答案为:";
				if (computerFracAns[i].bottom == 1){
					cin>>userFracAns[i].top;
					userFracAns[i].bottom = 1;
				}
				else
					cin>>userFracAns[i].top>>c>>userFracAns[i].bottom;
			}
		}
		else{
			for (int i = 0; i <= num / 2; i++){
				cout<<"第"<<i+1<<"道题的答案为:";
				cin>>userIntAns[i];
			}
			for (int i = num / 2 + 1; i < num; i++){ 
				cout<<"第"<<i+1<<"道题的答案为:";
				if (computerFracAns[i].bottom == 1){
					cin>>userFracAns[i].top;
					userFracAns[i].bottom = 1;
				}
				else 
					cin>>userFracAns[i].top>>c>>userFracAns[i].bottom;
			}
		}
		
		// 比较运算结果,正确则得分加1 
		for (int i = 0; i <= num / 2; i++)		
			if (userIntAns[i] == computerIntAns[i])
				score++;
				
		for (int i = num / 2 + 1; i < num; i++)
			if (userFracAns[i].top == computerFracAns[i].top && userFracAns[i].bottom == computerFracAns[i].bottom)
				score++;
				
		cout<<"成绩为:"<<score<<endl;
	 return 0;
}


// 求最大公约数 
int maxDivisor(int m, int n){							
	if (n == 0) 
		return m;
	return 
		maxDivisor(n, m % n);
}

// 对分数进行约分,不输出参数 
void reductionFraction(int &m, int &n){					
	int p = maxDivisor(abs(m), abs(n));
	m /= p;
	n /= p;
}	

// 对分数进行约分,输出参数 
void reductionFractionOutput(int &m, int &n){					
	int p = maxDivisor(abs(m), abs(n));
	m /= p;
	n /= p;
	if (n == 1)
		cout<<m;
	else
		cout<<m<<"/"<<n;
}	

// 生成加法题目 
void add(int num,fraction computerFracAns[],int computerIntAns[]){					
	int m, n = 0; 
	int top1, bottom1 = 0;
	int top2, bottom2 = 0;
	// 一半题目为整数运算,一半题目为分数运算 
	for (int i = 0; i <=num / 2; i++){
		unsigned int times = (unsigned int)time(0);  // 使用time生成随机数 
		srand(times * (i + 1));
		m = rand() % 10 + 1;
		n = rand() % 10 + 1;
		computerIntAns[i] = m + n;
		cout<<m<<"+"<<n<<endl;  //输出整数题目
	}
	for (int i = num/2+1; i < num; i++){
		unsigned int times = (unsigned int)time(0);  // 使用time生成随机数
		srand(times * (i + 1));
		top1 = rand() % 10 + 1;
		bottom1 = rand() % 10 + 1;
		top2 = rand() % 10 + 1;
		bottom2 = rand() % 10 + 1;
		reductionFractionOutput(top1, bottom1);
		cout<<"+";
		reductionFractionOutput(top2, bottom2);
		cout<<endl;										
		computerFracAns[i].top = top1 * bottom2 + top2 * bottom1;				
		computerFracAns[i].bottom = bottom1 * bottom2;												
		reductionFraction(computerFracAns[i].top, computerFracAns[i].bottom);

	}
}

// 生成减法题目 
void subtract(int num, fraction computerFracAns[], int computerIntAns[]){
	int m, n = 0; 
	int top1, bottom1 = 0;
	int top2, bottom2 = 0;
	// 一半题目为整数运算,一半题目为分数运算 
	for (int i = 0; i <= num / 2; i++){
		unsigned int times = (unsigned int)time(0);  // 使用time生成随机数
		srand(times * (i + 1));
		m = rand() % 10 + 1;
		n = rand() % 10 + 1;
		computerIntAns[i] = m - n;
		cout<<m<<"-"<<n<<endl;
	}
	for (int i = num / 2 + 1; i < num; i++){
		unsigned int times = (unsigned int)time(0);  // 使用time生成随机数
		srand(times * (i + 1));
		top1 = rand() % 10 + 1;
		bottom1 = rand() % 10 + 1;
		top2 = rand() % 10 + 1;
		bottom2 = rand() % 10 + 1;
		reductionFractionOutput(top1, bottom1);
		cout<<"-";
		reductionFractionOutput(top2, bottom2);
		cout<<endl;
		computerFracAns[i].top = top1 * bottom2 - top2 * bottom1;
		computerFracAns[i].bottom = bottom1 * bottom2;
		reductionFraction(computerFracAns[i].top, computerFracAns[i].bottom);
	}
}

// 生成乘法题目 
void multiply(int num, fraction computerFracAns[], int computerIntAns[]){
	int m, n = 0; 
	int top1, bottom1 = 0;
	int top2, bottom2 = 0;
	// 一半题目为整数运算,一半题目为分数运算 
	for (int i = 0; i <= num / 2; i++){
		unsigned int times = (unsigned int)time(0);  // 使用time生成随机数
		srand(times * (i + 1));
		m = rand() % 10 + 1;
		n = rand() % 10 + 1;
		computerIntAns[i] = m * n;
		cout<<m<<"*"<<n<<endl;
	}
	for (int i = num / 2 + 1; i < num; i++){
		unsigned int times = (unsigned int)time(0);  // 使用time生成随机数
		srand(times * (i + 1));
		top1 = rand() % 10 + 1;
		bottom1 = rand() % 10 + 1;
		top2 = rand() % 10 + 1;
		bottom2 = rand() % 10 + 1;
		reductionFractionOutput(top1, bottom1);
		cout<<"*";
		reductionFractionOutput(top2, bottom2);
		cout<<endl;
		computerFracAns[i].top = top1 * top2;
		computerFracAns[i].bottom = bottom1 * bottom2;
		reductionFraction(computerFracAns[i].top, computerFracAns[i].bottom);
	}
}

// 生成除法题目 
void divide(int num, fraction computerFracAns[]){					
	int top1, bottom1 = 0;
	int top2, bottom2 = 0;
	// 在除法下,题目无需考虑整数情况,因为此情况下他就会有除法存在就是分数了 
	for (int i = 0; i < num; i++){
		unsigned int times = (unsigned int)time(0);  // 使用time生成随机数
		srand(times * (i + 1));
		top1 = rand() % 10 + 1;
		bottom1 = rand() % 10 + 1;
		top2 = rand() % 10 + 1;
		bottom2 = rand() % 10 + 1;
		reductionFractionOutput(top1, bottom1);
		cout<<"/";
		reductionFractionOutput(top2, bottom2);
		cout<<endl;
		computerFracAns[i].top = top1 * bottom2;
		computerFracAns[i].bottom = bottom1 * top2;
		reductionFraction(computerFracAns[i].top, computerFracAns[i].bottom);
	}
}

三、个人小结
1.psp表格

psp2.1 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 30 50
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 10 5
Development 开发 355 300
Analysis 需求分析(包括学习新技术) 20 25
Design Spec 生成设计文档 15 10
Design Review 设计复审 10 10
Coding Standard 代码规范 20 15
Design 具体设计 30 25
Coding 具体编码 180 150
Code Review 代码复审 15 10
Test 测试(自我测试,修改代码,提交修改) 10 15
Reporting 报告 20 15
Test Report 测试报告 15 10
Size Measurement 计算工作量 10 10
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 10 15

2.总结
这次的项目不能说是很完美的运行,由于基础较差,在经过很多天的学习,实验下,我仅仅只是完成了个大概。为了让代码更加美观好看,我将代码整体结构改正了一下,导致我们总体的程序出现了bug,例如整数有时会运行不出,但调试却没有问题。这是我的责任,同时对我来说这个项目并没有结束,之后我会仔细检查debug,让它更完美些。最后一次总结会议上我们在总结自己收获的同时,也互相反思自己在项目上出现了什么问题,有什么不足之处。我们的问题主要有:沟通不到位,由于第一次进行结对项目,难免会有些个人思想,在反思过程中,明显发现,函数中参数设置和定义有很大区别,这让我们得不去仔细对照查看代码含义。也告诉我在下次结对时,一定一定要在一开始就定好函数和参数的各类功能和类型,提高效率,节省时间。这次的结对对我们来说是一个很好的经历,弥足珍贵。

posted @ 2020-11-09 00:15  cydestiny  阅读(77)  评论(0编辑  收藏  举报