四则运算3(结对开发)

本次的程序在上一次程序基础上进行了修改和完善。

结对伙伴

      刘元柱

      博客名:紫叶之风

链接:http://www.cnblogs.com/qwer112/

结对开发的一瞬间:

四则运算3(结对开发)_第1张图片

 

程序思路:

           基本思想与上次相同,只不过是在产生随机数的时候添加了可能产生分数,还有添加了关于分数的相关设定,如真分数,化简,关于分数的四则运算代码等。

       注意:程序对答案的判断只精确到小数点两位,且两位之后的不用四舍五入。负数开关生效的条件是算式中存在加减,同理余数开关生效的条件是算式中存在乘除。

       因为要求是加减有无负数,乘除有无余数,至少我是这么理解的。

程序源代码:

#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
#include<windows.h>
#include<time.h>
#include<iomanip>
#include <cstdlib>
#define Size 100
using namespace std;

//全局变量
int MulDivControl = 0;            //乘除法开关(0.乘除法 1.不包含乘除法)
int MaxNum = 100;                 //数字的最大值
int MinNum = 1;                   //数字的最小值

//真分数的数据结构
typedef struct Fraction
{
	int fenzi;      //表示真分数中的分子
	int fenmu;      //表示真分数中的分母
	float result;   //表示真分数的值(分子/分母)

}Fraction;

//重写函数
void gotoxy(int x, int y)    //x为列坐标,y为行坐标
{
	COORD pos = { x, y };    //设定坐标
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);    //函数句柄
	SetConsoleCursorPosition(hOut, pos);
}

/* Colors defined for SetColor(int) */
enum {
	BLACK = 0,
	DARK_BLUE = 1,
	DARK_GREEN = 2,
	TEAL = 3,
	DARK_RED = 4,
	DARK_PURPLE = 5,
	GOLD = 6,
	GREY = 7,
	DARK_WHITE = 8,
	BLUE = 9,
	GREEN = 10,
	CYAN = 11,
	RED = 12,
	PURPLE = 13,
	YELLOW = 14,
	WHITE = 15
};
//设置文本色与背景色
void SetColor(const int foreground, const int background) {

	int Color = foreground + (background * 16);
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hConsole, Color);

	return;
}

//随机生成范围内的一个整数
int CreateInt()
{
	if (MaxNum < MinNum)   //最大值最小值不合法
	{
		cout << "指定的数值范围不合法!!!";
		exit(0);
	}
	int num = (rand() % (MaxNum - MinNum + 1)) + MinNum; //生成一个>=MinNum,<=MaxNum的整数

	return num;
}

//随机生成范围内一个真分数
Fraction CreateFraction()
{
	Fraction fenshu;
	int l;

	fenshu.fenmu = CreateInt();  //分母随机生成
	fenshu.fenzi = CreateInt();  //分子随机生成

	//产生合法真分数
	while (true)
	{
		if (fenshu.fenmu < fenshu.fenzi)   //若分母小于分子,两者交换
		{
			l = fenshu.fenmu;
			fenshu.fenmu = fenshu.fenzi;
			fenshu.fenzi = l;
		}
		if (fenshu.fenmu != fenshu.fenzi && fenshu.fenmu !=0)            //若分母不等于分子且分母不为零,跳出循环
			break;

		//否则
		fenshu.fenmu = CreateInt();  //分母随机生成
		fenshu.fenzi = CreateInt();  //分子随机生成

	}

	fenshu.result = fenshu.fenzi / (float)fenshu.fenmu;  //计算真分数的结果
	for (int i = 2; i < fenshu.fenzi; i++)
	{
		int j = fenshu.fenzi%i;
		int k = fenshu.fenmu%i;
		if (j == 0 && k == 0)
		{
			fenshu.fenzi = fenshu.fenzi / i;
			fenshu.fenmu = fenshu.fenmu / i;
		}
	}

	return fenshu;   //返回合法真分数

}

//随机生成运算符0-3(+-*/)
int CreateOperator()
{
	int oper;
	if (MulDivControl == 0)    //允许有乘除法
	{
		oper = rand() % 4;
		return oper;
	}
	if (MulDivControl == 1)   //不允许有乘除法
	{
		oper = rand() % 2;
		return oper;
	}

	cout << "乘除法开关指定错误!!!";
	exit(0);
}

//生成算式
bool CreateEquation(int BracketControl, int AddSubControl_negative, int MulDivControl_remainder, string &equation_end, float &result_end)
{
	int num = 0;      //记录算式中数字个数
	int i, j, k;        //做随机种子
	float result;   //记录算式结果
	int oper_num = 0; //算式中操作数的个数(随机生成)
	Fraction opr1, opr2;  //记录生成的操作数
	string equation = "";     //记录中间算式
	equation_end = ""; //记录整个算式
	bool AddSub = false, MulDiv = false;  //记录算式中是否含有加减乘除
	int option = 2; //乘除设定
	stringstream ss;  //缓冲区
	bool oneNumSingal = false;  //记录是否为但操作数
	//bool fractionSingal = false;//记录是否为分数

	oper_num = rand() % 10 + 1;   //随机产生算式中操作数的个数(2-10)

	//算式中可以出现括号*******************************************************
	if (BracketControl == 0)
	{
		//生成一个基本算式****************************

		i = rand() % 2;   //生成随机数0/1,分别代表生成的基本算式第一个操作数为整数/真分数
		if (i == 0)  //第一个操作数是整数
		{
			opr1.result = CreateInt();
			ss << opr1.result;
			equation_end += ss.str();
			ss.str("");
		}
		else         //第一个操作数是真分数
		{
			opr1 = CreateFraction();
			ss << opr1.fenzi;
			equation_end += ss.str();
			ss.str("");
			equation_end += "/";
			ss << opr1.fenmu;
			equation_end += ss.str();
			ss.str("");
		}

		//同理生成第二个操作数
		i = rand() % 2;   //生成随机数0/1,分别代表生成的基本算式第二个操作数为整数/真分数
		if (i == 0)  //第二个操作数是整数
		{
			opr2.result = CreateInt();
			ss << opr2.result;
			equation += ss.str();
			ss.str("");
		}
		else         //第二个操作数是真分数
		{
			opr2 = CreateFraction();
			ss << opr2.fenzi;
			equation += ss.str();
			ss.str("");
			equation += "/";
			ss << opr2.fenmu;
			equation += ss.str();
			ss.str("");
			
		}
		num += 2;
		j = CreateOperator();
		//根据运算符计算基本算式的结果,设置equation_end,result_end
		if (j == 0)
		{
			equation_end += " + ";
			result_end = opr1.result + opr2.result;
			AddSub = true;
		}
		else if (j == 1)
		{
			equation_end += " - ";
			result_end = opr1.result - opr2.result;
			AddSub = true;
		}
		else if (j == 2)
		{
			equation_end += " × ";
			result_end = opr1.result * opr2.result;
			MulDiv = true;
		}
		else if (j == 3)
		{
			if (opr2.result == 0) //除零操作
				return false;

			equation_end += " ÷ ";
			result_end = opr1.result / opr2.result;
			MulDiv = true;
		}
		else
		{
			cout << "error!";
			exit(0);
		}

		equation_end += equation;


		//基本算式生成完毕************************

		//由基本算式生成最终算式******************
		while (num < oper_num - 1)
		{
			equation = "";

			i = rand() % 2;
			if (i == 0)         //生成随机操作数
			{
				j = rand() % 2;

				if (j == 0)  //操作数是整数
				{
					opr1.result = CreateInt();
					result = opr1.result;
					ss << opr1.result;
					equation += ss.str();
					ss.str("");
					num++;
				}
				else         //操作数是真分数
				{
					opr1 = CreateFraction();
					result = opr1.result;
					ss << opr1.fenzi;
					equation += ss.str();
					ss.str("");
					equation += "/";
					ss << opr1.fenmu;
					equation += ss.str();
					ss.str("");
					num++;
				}
				oneNumSingal = true;
			}
			if (i == 1)        //生成随机算式
			{
				j = rand() % 2;   //生成随机数0/1,分别代表生成的基本算式第一个操作数为整数/真分数
				if (j == 0)  //第一个操作数是整数
				{
					opr1.result = CreateInt();
					ss << opr1.result;
					equation += ss.str();
					ss.str("");
				}
				else         //第一个操作数是真分数
				{
					opr1 = CreateFraction();
					ss << opr1.fenzi;
					equation += ss.str();
					ss.str("");
					equation += "/";
					ss << opr1.fenmu;
					equation += ss.str();
					ss.str("");
				}

				//同理生成第二个操作数
				j = rand() % 2;   //生成随机数0/1,分别代表生成的基本算式第二个操作数为整数/真分数
				if (j == 0)  //第二个操作数是整数
				{
					opr2.result = CreateInt();
					ss << opr2.result;
				}
				else         //第二个操作数是真分数
				{
					opr2 = CreateFraction();
					ss << opr2.fenzi;
					ss << "/";
					ss << opr2.fenmu;
				}
				num += 2;
				j = CreateOperator();
				//根据运算符计算基本算式的结果,设置equation,result
				if (j == 0)
				{
					equation += " + ";
					result = opr1.result + opr2.result;
					AddSub = true;
				}
				else if (j == 1)
				{
					equation += " - ";
					result = opr1.result - opr2.result;
					AddSub = true;
				}
				else if (j == 2)
				{
					equation += " × ";
					result = opr1.result * opr2.result;
					MulDiv = true;
				}
				else if (j == 3)
				{
					if (opr2.result == 0) //除零操作
						return false;

					equation += " ÷ ";
					result = opr1.result / opr2.result;
					MulDiv = true;
				}
				else
				{
					cout << "error!";
					exit(0);
				}

				equation += ss.str();
				ss.str("");
			}
			//结合
			j = CreateOperator();
			if (j == 0)
			{
				equation_end = equation_end + " + " + equation;
				result_end = result_end + result;
				AddSub = true;
			}
			else if (j == 1)
			{
				if (oneNumSingal)
					equation_end = equation_end + " - " + equation;
				else
					equation_end = equation_end + " - (" + equation + ")";
				result_end = result_end - result;
					AddSub = true;
			}
			else if (j == 2)
			{
				if (oneNumSingal)
					equation_end = "(" + equation_end + ") × " + equation + "";
				else
					equation_end = "(" + equation_end + ") × (" + equation + ")";

				result_end = result_end * result;
				MulDiv = true;
			}
			else
			{
				if (result == 0)
					return false;
				if (oneNumSingal)
					equation_end = "(" + equation_end + ") ÷ " + equation + "";
				else
					equation_end = "(" + equation_end + ") ÷ (" + equation + ")";

				result_end = result_end / result;
				MulDiv = true;
			}
			oneNumSingal = false;

		}
	}
	//算式中不可以出现括号*******************************************************
	if (BracketControl == 1)
	{
		int arry_1[9], m = 0, n = 0;    //记录运算符
		float arry_2[10];   //记录操作数

		i = rand() % 2;   //生成随机数0/1,分别代表生成的算式第一个操作数为整数/真分数
		if (i == 0)  //第一个操作数是整数
		{
			opr1.result = CreateInt();
			ss << opr1.result;
			equation_end += ss.str();
			ss.str("");
		}
		else         //第一个操作数是真分数
		{
			opr1 = CreateFraction();
			ss << opr1.fenzi;
			equation_end += ss.str();
			ss.str("");
			equation_end += "/";
			ss << opr1.fenmu;
			equation_end += ss.str();
			ss.str("");
		}
		arry_2[n] = opr1.result;
		n++;

		//同理生成第二个操作数
		i = rand() % 2;   //生成随机数0/1,分别代表生成的基本算式第二个操作数为整数/真分数
		if (i == 0)  //第二个操作数是整数
		{
			opr2.result = CreateInt();
			ss << opr2.result;
			equation += ss.str();
			ss.str("");
		}
		else         //第二个操作数是真分数
		{
			opr2 = CreateFraction();
			ss << opr2.fenzi;
			equation += ss.str();
			ss.str("");
			equation += "/";
			ss << opr2.fenmu;
			equation += ss.str();
			ss.str("");

		}
		arry_2[n] = opr2.result;
		n++;

		num += 2;
		j = CreateOperator();
		arry_1[m] = j;
		m++;
		//根据运算符计算基本算式的结果,设置equation_end,result_end
		if (j == 0)
		{
			equation_end += " + ";
			AddSub = true;
		}
		else if (j == 1)
		{
			equation_end += " - ";
			AddSub = true;
		}
		else if (j == 2)
		{
			equation_end += " × ";
			result = arry_2[n - 2] * arry_2[n - 1];
			arry_2[n - 2] = result;
			n--;
			m--;
			MulDiv = true;
		}
		else if (j == 3)
		{
			if (opr2.result == 0) //除零操作
				return false;

			equation_end += " ÷ ";
			result = arry_2[n - 2] / arry_2[n - 1];
			arry_2[n - 2] = result;
			n--;
			m--;
			MulDiv = true;
		}
		else
		{
			cout << "error!";
			exit(0);
		}
		equation_end += equation;

		while (num < oper_num)
		{
			equation = "";
			i = rand() % 2;   //生成随机数0/1,分别代表为整数/真分数
			if (i == 0)  //第一个操作数是整数
			{
				opr1.result = CreateInt();
				ss << opr1.result;
				equation += ss.str();
				ss.str("");
			}
			else         //第一个操作数是真分数
			{
				opr1 = CreateFraction();
				ss << opr1.fenzi;
				equation += ss.str();
				ss.str("");
				equation += "/";
				ss << opr1.fenmu;
				equation += ss.str();
				ss.str("");
			}
			arry_2[n] = opr1.result;
			n++;
			num++;

			j = CreateOperator();
			arry_1[m] = j;
			m++;
			if (j == 0)
			{
				equation_end = equation_end + " + " + equation;
				AddSub = true;
			}
			else if (j == 1)
			{
				equation_end = equation_end + " - " + equation;
				AddSub = true;
			}
			else if (j == 2)
			{
				equation_end = equation_end + " × " + equation;
				result = arry_2[n - 2] * arry_2[n - 1];
				arry_2[n - 2] = result;
				n--;
				m--;
				MulDiv = true;
			}
			else
			{
				equation_end = equation_end + " ÷ " + equation;
				result = arry_2[n - 2] / arry_2[n - 1];
				arry_2[n - 2] = result;
				n--;
				m--;
				MulDiv = true;
			}

		}
		//计算算式结果
		result_end = arry_2[0];
		for (i = 0; i <= m; i++)
		{
			if (arry_1[i] == 0)
				result_end = result_end + arry_2[i + 1];
			if (arry_1[i] == 1)
				result_end = result_end - arry_2[i + 1];
		}


	}
	//加减有无负数
	if (AddSub == true && AddSubControl_negative == 1)
	{
		if (result_end < 0)
			return false;
	}
	//乘除有无余数
	if (MulDiv == true && MulDivControl_remainder == 1)
	{
		if ((int)(result_end * 10000) % 10000 != 0)
			return false;
	}
	return true;
}

int menu(int i)
{
	int l;
	system("cls");
	cout << setw(47) << "简单算式生成" << endl << endl;
	cout << setw(22) << "请对算式进行设置:" << endl << endl;
	cout << "            <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl;
	cout << "            <<                    1.算式个数                           <<" << endl;
	cout << "            <<                                                         <<" << endl;
	cout << "            <<                    2.输出方式                           <<" << endl;
	cout << "            <<                                                         <<" << endl;
	cout << "            <<                    3.括号开关                           <<" << endl;
	cout << "            <<                                                         <<" << endl;
	cout << "            <<                    4.负数开关                           <<" << endl;
	cout << "            <<                                                         <<" << endl;
	cout << "            <<                    5.余数开关                           <<" << endl;
	cout << "            <<                                                         <<" << endl;
	cout << "            <<                    6.乘除开关                           <<" << endl;
	cout << "            <<                                                         <<" << endl;
	cout << "            <<                    7.最大数值                           <<" << endl;
	cout << "            <<                                                         <<" << endl;
	cout << "            <<                    8.最小数值                           <<" << endl;
	cout << "            <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl;

	SetColor(BLUE,BLACK);
	switch (i)
	{
	case 0:
	{
			  gotoxy(34, 5 + i * 2);
			  cout << i + 1 << ".算式个数";
			  break;
	}
	case 1:
	{
			  gotoxy(34, 5 + i * 2);
			  cout << i + 1 << ".输出方式 ";
			  break;
	}
	case 2:
	{
			  gotoxy(34, 5 + i * 2);
			  cout << i + 1 << ".括号开关 ";
			  break;
	}
	case 3:
	{
			  gotoxy(34, 5 + i * 2);
			  cout << i + 1 << ".负数开关 ";
			  break;
	}
	case 4:
	{
			  gotoxy(34, 5 + i * 2);
			  cout << i + 1 << ".余数开关 ";
			  break;
	}
	case 5:
	{
			  gotoxy(34, 5 + i * 2);
			  cout << i + 1 << ".乘除开关 ";
			  break;
	}
	case 6:
	{
			  gotoxy(34, 5 + i * 2);
			  cout << i + 1 << ".最大数值 ";
			  break;
	}
	case 7:
	{
			  gotoxy(34, 5 + i * 2);
			  cout << i + 1 << ".最小数值 ";
			  break;
	}
	}
	SetColor(YELLOW,BLACK);
	gotoxy(25, 22);
	cout << "请输入设定:";
	cin >> l;
	SetColor(WHITE, BLACK);
	return l;
}

int main()
{
	//初始化变量
	int ProblemNumber = 30;           //表示要生成的题目的个数
	int OutWay = 0;                   //输出方式(0.屏幕打印 1.输出到文件)
	int BracketControl = 1;           //括号开关(0.含括号 1.不含括号)
	int AddSubControl_negative = 1;   //加减有无负数(0.可以有 1.不可以有)
	int MulDivControl_remainder = 1;  //乘除有无余数(0.可以有 1.不可以有)
	string equation[Size];            //存储算式
	float result[Size];
	srand(time(0));                 //随机函数做时间种子
	int arry[8];
	int i = 0,m;
	float answer;
	int answer_correct = 0;       //答题正确数
	//stringstream ss;

	for (i = 0; i < 8; i++)
	{
		arry[i] = menu(i);
		if (i == 7)
		{
			if (arry[i] >= arry[i - 1])
			{
				i--;
				system("cls");
				cout << "输入错误!!!"<<endl;
				cout << "提示: 输入的最小值不合法!!";
				system("pause");
			}
		}
		else if (i == 0)
		 {
			if (arry[i] <= 0)
			{
				i--;
				system("cls");
				cout << "输入错误!!!"<<endl;
				cout << "提示: 输入的个数要不小于1.";
				system("pause");
			}
		}
		else if (i != 6)
		{
			if (arry[i] != 0 && arry[i] != 1)
			{
				system("cls");
				i--;
				cout << "输入错误!!!"<<endl;
				cout << "提示: 输入的数值 0 代表默认存在,1 代表不存在。比括号控制中 0 代表有括号, 1 代表没有括号;输出方式中 0 代表屏幕打印 ,1 代表输出到文件。 ";
				system("pause");
			
			}
		}

	}
	BracketControl = arry[2];
	AddSubControl_negative = arry[3];
	MulDivControl_remainder = arry[4];
	MulDivControl = arry[5];
	MaxNum = arry[6];
	MinNum = arry[7];
	ProblemNumber = arry[0];
	OutWay = arry[1];
	system("cls");
	for (i = 0; i < ProblemNumber; i++)
	{
		m = 0;
		if (CreateEquation(BracketControl, AddSubControl_negative, MulDivControl_remainder, equation[i], result[i]))//算式合法
		{
			for (int j = 0; j < i; j++)
			{
				if (equation[i] == equation[j]) //算式重复
					m = 1;
			}

			if (m == 1) //重复
			{
				i--;
			}
			else
			{
				cout <<endl<< "第" << i + 1 << "题: " << equation[i] << " = ";
				cin >> answer;
				if ((int)(answer * 100) == (int)(result[i] * 100)) //结果正确
				{
					answer_correct++;
					SetColor(GREEN, BLACK);
					cout << "  正确!!" << endl;
					SetColor(WHITE, BLACK);
				}
				else
				{
					SetColor(RED, BLACK);
					cout << "  错误!!正确答案为:" << result[i] << endl;
					SetColor(WHITE, BLACK);
				}
			}
		}
		else  //算式不合法
			i--;
	}
	SetColor(GREEN, BLACK);
	cout <<endl<< "回答正确的题目数为:";
	SetColor(YELLOW, BLACK);
	cout<<answer_correct;
	SetColor(WHITE, BLACK);
	system("pause");
	if (OutWay == 1)
	{
		system("cls");
		ofstream file("题目");
		if (!file)
		{
			cout << "无法输出到文件!!!";
			exit(0);
		}
		for (int i = 0; i < ProblemNumber; i++)
		{
			file << "第" << i + 1 << "题  ";
			for (int j = 0; j < equation[i].length(); j++)
				file << equation[i][j];
			file << "=" << endl;
		}
		cout << "题目已写入该项目文件夹中!!(文件名:题目)" << endl;

		ofstream answer("参考答案");
		if (!answer)
		{
			cout << "无法输出到文件!!!";
			exit(0);
		}
		for (int i = 0; i < ProblemNumber; i++)
		{
			answer << "第" << i + 1 << "题  ";
			for (int j = 0; j < equation[i].length(); j++)
				answer << equation[i][j];
			answer << "=" << result[i] << endl;
		}
		cout << "答案已写入该项目文件夹中!(文件名:参考答案)" << endl;
	}
	return 0;
}

  运行截图:

                                                      主界面

       分别对1-8进行指定,其中对于开关默认0为打开,1为关闭;输出方式0为品目打印,1为输出到文件

设定屏幕目输出0,有括号0,有负数0,有余数0,有乘除0,最大值20(错误提示仅支持数字)

开始答题

如果输出到文件

四则运算3(结对开发)_第2张图片

四则运算3(结对开发)_第3张图片

四则运算3(结对开发)_第4张图片

 

项目计划总结:

时间记录日志:

四则运算3(结对开发)_第5张图片

缺陷记录日志:

四则运算3(结对开发)_第6张图片

 

你可能感兴趣的:(四则运算3(结对开发))