四则运算题目生成程序

这个作业属于哪个课程 计算机18级
这个作业要求在哪里 四则运算题目生成程序
这个作业的目标 学会工程化方法变成及markdown使用方法
学号 3180301230

题目要求

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

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

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

3)程序支持可以由用户自行选择加、减、乘、除运算

4)使用-n参数控制生成题目的个数,例如Myapp.exe -n 10,将生成10个题目

函数说明

分数结构体

typedef struct					                              //定义分数结构体
{
	int up, down;
}fraction;

找公约数

int gcd(int a, int b)							      //最大公约数
{
	if (b == 0) return a;                                                 //辗转相除法
	return gcd(b, a % b);
}

分数约分

void yuefen(int &a, int &b,int flag)					      //分数约分,并自动进行输出,用flag标志答案,答案不输出
{
	int d = gcd(abs(a), abs(b));
	a /= d;
	b /= d;
	if (flag == 0) {
		if (b == 1)printf("%d", a);
		else printf("%d/%d", a, b);
	}
}

加法

void add(int num,fraction fraans[],int ans[])					        //加法题目生成及运算
{
	int a, b, up1, down1, up2, down2,flag=0;
	for (int i = 0; i <=num / 2; i++)						//整数部分
	{	
		unsigned int times = (unsigned int)time(0);				//生成随机数
		srand(times * (i + 1));
		a = rand() % 10 + 1;
		b = rand() % 10 + 1;
		ans[i] = a + b;
		printf("%d.%d+%d\n", i+1, a, b);					//输出整数题目
	}
	for (int i = num/2+1; i < num; i++)						//分数部分
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		up1 = rand() % 10 + 1;
		down1 = rand() % 10 + 1;
		up2 = rand() % 10 + 1;
		down2 = rand() % 10 + 1;
		printf("%d.", i + 1);
		yuefen(up1, down1,flag);
		printf("+");
		yuefen(up2, down2,flag);
		printf("\n");								//将随机生成的分数进行约分后再输出
		fraans[i].up = up1 * down2 + up2 * down1;				
		fraans[i].down = down1 * down2;
		flag = 1;								//用flag标志答案,对答案不进行输出
		yuefen(fraans[i].up, fraans[i].down,flag);
		flag = 0;
	}
}

减法

void subtract(int num, fraction fraans[], int ans[])			//减法题目生成及运算
{
	int a, b, up1, down1, up2, down2,flag=0;
	for (int i = 0; i <= num / 2; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		a = rand() % 10 + 1;
		b = rand() % 10 + 1;
		ans[i] = a - b;
		printf("%d.%d-%d\n", i, a, b);
	}
	for (int i = num / 2 + 1; i < num; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		up1 = rand() % 10 + 1;
		down1 = rand() % 10 + 1;
		up2 = rand() % 10 + 1;
		down2 = rand() % 10 + 1;
		printf("%d.", i + 1);
		yuefen(up1, down1, flag);
		printf("-");
		yuefen(up2, down2, flag);
		printf("\n");
		fraans[i].up = up1 * down2 - up2 * down1;
		fraans[i].down = down1 * down2;
		flag = 1;
		yuefen(fraans[i].up, fraans[i].down, flag);
		flag = 0;
	}
}

乘法

void multiply(int num, fraction fraans[], int ans[])			//乘法题目生成及运算
{
	int a, b, up1, down1, up2, down2,flag = 0;
	for (int i = 0; i <= num / 2; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		a = rand() % 10 + 1;
		b = rand() % 10 + 1;
		ans[i] = a * b;
		printf("%d.%d*%d\n", i+1, a, b);
	}
	for (int i = num / 2 + 1; i < num; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		up1 = rand() % 10 + 1;
		down1 = rand() % 10 + 1;
		up2 = rand() % 10 + 1;
		down2 = rand() % 10 + 1;
		printf("%d.", i + 1);
		yuefen(up1, down1, flag);
		printf("*");
		yuefen(up2, down2, flag);
		printf("\n");
		fraans[i].up = up1 * up2;
		fraans[i].down = down1 * down2;
		flag = 1;
		yuefen(fraans[i].up, fraans[i].down, flag);
		flag = 0;
	}
}

除法

void divide(int num, fraction fraans[])					
{                                                                        //除法题目生成及运算
	int up1, down1, up2, down2, flag = 0;
	for (int i = 0; i < num; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		up1 = rand() % 10 + 1;
		down1 = rand() % 10 + 1;
		up2 = rand() % 10 + 1;
		down2 = rand() % 10 + 1;
		printf("%d.(", i + 1);
		yuefen(up1, down1, flag);
		printf(")/(");
		yuefen(up2, down2, flag);
		printf(")\n");
		fraans[i].up = up1 * down2;
		fraans[i].down = down1 * up2;
		flag = 1;
		yuefen(fraans[i].up, fraans[i].down, flag);
		flag = 0;
	}
}

主函数

int main()
{
	char f = 'Y';
	while(f!='N'&&f!='n')
	{
		fraction fraans[400], userfraans[400];
		int ans[100] = { 0 }, userans[100] = { 0 };
		int num, symbol, grade = 0;
		printf("四则运算题目生成程序\n");
		printf("请选择符号,1,2,3,4对应加减乘除:");
		scanf_s("%d", &symbol);			            //用symbol标志用户选择的符号,1234对应加减乘除;
		printf("请输入题目数量(最少为2,最大100):");
		scanf_s("%d", &num);
		switch (symbol)														//对应选择不同的算法
		{
		case 1:add(num, fraans, ans); break;
		case 2:subtract(num, fraans, ans); break;
		case 3:multiply(num, fraans, ans); break;
		case 4:divide(num, fraans); break;
		}
		if (symbol != 4)			            //当用户选择的运算不为除法时,分别对整数和分数答案进行保存
		{

			for (int i = 0; i <= num / 2; i++)
			{
				printf("第%d道题的答案为:", i + 1);
				scanf_s("%d", &userans[i]);
			}
			for (int i = num / 2 + 1; i < num; i++)
			{
				printf("第%d道题的答案为:", i + 1);
				if (fraans[i].down == 1)
				{
					scanf_s("%d", &userfraans[i].up);
					userfraans[i].down = 1;
				}
				else
				{
					scanf_s("%d/%d", &userfraans[i].up, &userfraans[i].down);
				}
			}
		}
		else						      //当用户选择为出发时,对用户输入的答案进行保存
		{
			for (int i = 0; i < num; i++)
			{
				printf("第%d道题的答案为:", i + 1);
				if (fraans[i].down == 1)
				{
					scanf_s("%d", &userfraans[i].up);
					userfraans[i].down = 1;
				}
				else
				{
					scanf_s("%d/%d", &userfraans[i].up, &userfraans[i].down);
				}
			}
		}
		for (int i = 0; i <= num / 2; i++)			//对用户输入的答案和答案进行对比,如果一致,得分+1
		{
			if (userans[i] == ans[i])grade++;
		}
		for (int i = num / 2 + 1; i < num; i++)
		{
			if (userfraans[i].up == fraans[i].up && userfraans[i].down == fraans[i].down)grade++;
		}
		printf("grade=%d\n", grade);
		printf("是否继续做题?(Y/N)");
		cin >> f;
		if (f == 'Y')system("cls");                              //清屏
		else return 0;
	}
}

运行截图

加法

减法

乘法

除法

小结

  代码不算太难,但是第一次完全根据任务计划的表来进行,还是有一些不一样的感觉的,虽然写代码前的准备时间比我以前写要多很多,但是经过仔细思量后写出来这个程序还是蛮轻松的,使用工程化的方法确实有利于工作学习的效率。
  另外我也通过此次机会,学习了markdown的使用方法,个人感觉还挺有趣的,而且非常简便,以后一定会多多利用。
psp 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 5 5
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 10 10
Development 开发 200 180
Analysis 需求分析(包括学习新技术) 20 40
Design Spec 生成设计文档 15 10
Design Review 设计复审 10 15
Coding Standard 代码规范 5 5
Design 具体设计 20 40
Coding 具体编码 200 180
Code Review 代码复审 20 15
Test 测试(自我测试,修改代码,提交修改) 60 60
Reporting 报告 5 5
Test Report 测试报告 5 5
Size Measurement 计算工作量 20 25
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 40 90

源码

#include <stdio.h>
#include<iostream>
#include <stdlib.h>
#include <time.h>
#include <string.h>
using namespace std;
typedef struct											//定义分数结构体
{
	int up, down;
}fraction;
int gcd(int a, int b)									//最大公约数
{
	if (b == 0) return a;
	return gcd(b, a % b);
}
void yuefen(int &a, int &b,int flag)					//分数约分,并自动进行输出,用flag标志答案,答案不输出
{
	int d = gcd(abs(a), abs(b));
	a /= d;
	b /= d;
	if (flag == 0) {
		if (b == 1)printf("%d", a);
		else printf("%d/%d", a, b);
	}
}	
void add(int num,fraction fraans[],int ans[])					//加法题目生成及运算
{
	int a, b, up1, down1, up2, down2,flag=0;
	for (int i = 0; i <=num / 2; i++)						//整数部分
	{	
		unsigned int times = (unsigned int)time(0);				//生成随机数
		srand(times * (i + 1));
		a = rand() % 10 + 1;
		b = rand() % 10 + 1;
		ans[i] = a + b;
		printf("%d.%d+%d\n", i+1, a, b);						//输出整数题目
	}
	for (int i = num/2+1; i < num; i++)						//分数部分
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		up1 = rand() % 10 + 1;
		down1 = rand() % 10 + 1;
		up2 = rand() % 10 + 1;
		down2 = rand() % 10 + 1;
		printf("%d.", i + 1);
		yuefen(up1, down1,flag);
		printf("+");
		yuefen(up2, down2,flag);
		printf("\n");											//将随机生成的分数进行约分后再输出
		fraans[i].up = up1 * down2 + up2 * down1;				
		fraans[i].down = down1 * down2;
		flag = 1;												//用flag标志答案,对答案不进行输出
		yuefen(fraans[i].up, fraans[i].down,flag);
		flag = 0;
	}
}

void subtract(int num, fraction fraans[], int ans[])			//减法题目生成及运算
{
	int a, b, up1, down1, up2, down2,flag=0;
	for (int i = 0; i <= num / 2; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		a = rand() % 10 + 1;
		b = rand() % 10 + 1;
		ans[i] = a - b;
		printf("%d.%d-%d\n", i, a, b);
	}
	for (int i = num / 2 + 1; i < num; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		up1 = rand() % 10 + 1;
		down1 = rand() % 10 + 1;
		up2 = rand() % 10 + 1;
		down2 = rand() % 10 + 1;
		printf("%d.", i + 1);
		yuefen(up1, down1, flag);
		printf("-");
		yuefen(up2, down2, flag);
		printf("\n");
		fraans[i].up = up1 * down2 - up2 * down1;
		fraans[i].down = down1 * down2;
		flag = 1;
		yuefen(fraans[i].up, fraans[i].down, flag);
		flag = 0;
	}
}

void multiply(int num, fraction fraans[], int ans[])			//乘法题目生成及运算
{
	int a, b, up1, down1, up2, down2,flag = 0;
	for (int i = 0; i <= num / 2; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		a = rand() % 10 + 1;
		b = rand() % 10 + 1;
		ans[i] = a * b;
		printf("%d.%d*%d\n", i+1, a, b);
	}
	for (int i = num / 2 + 1; i < num; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		up1 = rand() % 10 + 1;
		down1 = rand() % 10 + 1;
		up2 = rand() % 10 + 1;
		down2 = rand() % 10 + 1;
		printf("%d.", i + 1);
		yuefen(up1, down1, flag);
		printf("*");
		yuefen(up2, down2, flag);
		printf("\n");
		fraans[i].up = up1 * up2;
		fraans[i].down = down1 * down2;
		flag = 1;
		yuefen(fraans[i].up, fraans[i].down, flag);
		flag = 0;
	}
}

void divide(int num, fraction fraans[])						//除法题目生成及运算
{
	int up1, down1, up2, down2, flag = 0;
	for (int i = 0; i < num; i++)
	{
		unsigned int times = (unsigned int)time(0);
		srand(times * (i + 1));
		up1 = rand() % 10 + 1;
		down1 = rand() % 10 + 1;
		up2 = rand() % 10 + 1;
		down2 = rand() % 10 + 1;
		printf("%d. ", i + 1);
		yuefen(up1, down1, flag);
		printf(" / ");
		yuefen(up2, down2, flag);
		printf(" \n");
		fraans[i].up = up1 * down2;
		fraans[i].down = down1 * up2;
		flag = 1;
		yuefen(fraans[i].up, fraans[i].down, flag);
		flag = 0;
	}
}

int main()
{
	char f = 'Y';
	while(f!='N'&&f!='n')
	{
		fraction fraans[400], userfraans[400];
		int ans[100] = { 0 }, userans[100] = { 0 };
		int num, symbol, grade = 0;
		printf("四则运算题目生成程序\n");
		printf("请选择符号,1,2,3,4对应加减乘除:");
		scanf_s("%d", &symbol);												//用symbol标志用户选择的符号,1234对应加减乘除;
		printf("请输入题目数量(最少为2,最大100):");
		scanf_s("%d", &num);
		switch (symbol)														//对应选择不同的算法
		{
		case 1:add(num, fraans, ans); break;
		case 2:subtract(num, fraans, ans); break;
		case 3:multiply(num, fraans, ans); break;
		case 4:divide(num, fraans); break;
		}
		if (symbol != 4)													//当用户选择的运算不为除法时,分别对整数和分数答案进行保存
		{

			for (int i = 0; i <= num / 2; i++)
			{
				printf("第%d道题的答案为:", i + 1);
				scanf_s("%d", &userans[i]);
			}
			for (int i = num / 2 + 1; i < num; i++)
			{
				printf("第%d道题的答案为:", i + 1);
				if (fraans[i].down == 1)
				{
					scanf_s("%d", &userfraans[i].up);
					userfraans[i].down = 1;
				}
				else
				{
					scanf_s("%d/%d", &userfraans[i].up, &userfraans[i].down);
				}
			}
		}
		else																//当用户选择为出发时,对用户输入的答案进行保存
		{
			for (int i = 0; i < num; i++)
			{
				printf("第%d道题的答案为:", i + 1);
				if (fraans[i].down == 1)
				{
					scanf_s("%d", &userfraans[i].up);
					userfraans[i].down = 1;
				}
				else
				{
					scanf_s("%d/%d", &userfraans[i].up, &userfraans[i].down);
				}
			}
		}
		for (int i = 0; i <= num / 2; i++)									//对用户输入的答案和答案进行对比,如果一致,得分+1
		{
			if (userans[i] == ans[i])grade++;
		}
		for (int i = num / 2 + 1; i < num; i++)
		{
			if (userfraans[i].up == fraans[i].up && userfraans[i].down == fraans[i].down)grade++;
		}
		printf("grade=%d\n", grade);
		printf("是否继续做题?(Y/N)");
		cin >> f;
		if (f != 'N' && f != 'n')system("cls");
		else return 0;
	}
}
posted @ 2020-11-03 20:20  计算机181胡佛  阅读(185)  评论(0编辑  收藏  举报