作业要求:
写一个能自动生成小学四则运算题目的命令行 “软件”, 分别满足下面的各种需求,这些需求都可以用命令行参数的形式来指定:
a) 支持整数、真分数的四则运算。例如: 1/6 + 1/8 = 7/24
b) 让程序能接受用户输入答案,并判定对错,最后给出总共 对/错 的数量。
c) 逐步扩展功能和可以支持的表达式类型,最后希望能支持下面类型的题目(最多 10 个运算符,括号的数量不限制)
25 - 3 * 4 - 2 / 2 + 89 = ?
1/2 + 1/3 - 1/4 = ?
( 5 - 4 ) * ( 3 +28 ) =?
设计思路:
定义分数类,重载四则运算符+-*/、赋值符号=、逻辑运算符==和输出输出流。
对于整数,看做真分数的一种特例即可。
对于算式的生成,先随机生成运算符的数量(题目要求10个,但是针对于小学生而言..十个还是有点多),采用rand() 随机生成分子分母并化简(整数分子为1),再讲分数转化为字符串,随机生成运算符与随机决定是否括号,再去之前生成的算式拼接。
对于算式的结果计算,运用典型的中缀表达式转后缀的算法,定义一个符号栈一个分数栈进行计算。
每次生成一个算式并要求使用者给出自己的答案,判断正误,记录结果。
已经实现功能:
- 随机生成整数或者分数算式,整数算式结果为整数,分数算式结果为真分数
- 真分数的四则运算,结果为真分数
- 支持括号
- 支持判断正误,给出准确率
代码:
GitHub: https://github.com/chynphh/Elementary-arithmetic
1 #include <iostream> 2 #include <string> 3 #include <string.h> 4 #include <math.h> 5 #include <cstdlib> 6 #include <cstdio> 7 #include <ctime> 8 using namespace std; 9 10 #define OK 1 11 #define ERROR 0 12 #define TRUE 1 13 #define FALSE 0 14 #define MAX 1000 15 #define ADD 100 16 typedef int Status; 17 18 19 // 整数转字符串 20 string itoa_i(int x){ 21 char str[20]; 22 itoa(x, str, 10); 23 return str; 24 25 } 26 27 //求最大公约数 28 int gcd(int m,int n){ 29 if(m%n==0) 30 return n; 31 else 32 return gcd(n,m%n); 33 } 34 35 //分数类 36 class Fraction{ 37 public: 38 Fraction(int x1=0,int z2=1);////构造函数 39 void huajian();//分数化简 40 Fraction operator + (Fraction f2);//运算符重载 + 41 Fraction operator - (Fraction f2);//运算符重载 - 42 Fraction operator * (Fraction f2);//运算符重载 * 43 Fraction operator / (Fraction f2);//运算符重载 / 44 Fraction& operator= (const Fraction& frac){ 45 x = frac.x; 46 z = frac.z; 47 return *this; 48 } 49 bool operator==(const Fraction &c); 50 51 friend void operator >>(istream& in,Fraction &f);//输入流重载 52 friend void operator <<(ostream& out,Fraction &f);//输出流重载 53 54 55 int x;//分子 56 int z;//分母 57 }; 58 59 //输出流重载 60 void operator<<(ostream& out,Fraction &f){ 61 if(f.x==0) out<<" 0"; 62 else if(f.z==1) out<<f.x; 63 else if(f.z==-1) out<<-1*f.z; 64 else{ 65 if(f.x*f.z>0) 66 out<<abs(f.x)<<'/'<<abs(f.z); 67 else 68 out<<-1*abs(f.x)<<'/'<<abs(f.z); 69 70 } 71 } 72 73 //输入流重载 74 void operator>>(istream& in,Fraction &f){ 75 char c; 76 in>>f.x; 77 in.unsetf(ios::skipws);// 78 in>>c; 79 in.setf(ios::skipws);// 80 if(c != '/'){ 81 if(c==' '){ 82 f.z = 1; 83 } 84 else{ 85 in>>f.z; 86 throw c; 87 } 88 } 89 else{ 90 in>>f.z; 91 if(f.z == 0) 92 throw f.z; 93 } 94 } 95 96 //逻辑运算符==重载 97 bool Fraction::operator==(const Fraction &c){ 98 if (x == c.x && z == c.z) return true; 99 return false; 100 } 101 102 //分数转字符串 103 string itoa_f(Fraction a){ 104 string s = ""; 105 if(a.z == 1) s = s + itoa_i(a.x) + ""; 106 else s = s + itoa_i(a.x) + "/" + itoa_i(a.z) ; 107 return s; 108 } 109 110 //字符串转整数 111 Fraction atof_f(char* a){ 112 Fraction f; 113 int i = 0, l = 0; 114 char* b; 115 l = strlen(a); 116 while(a[i] != '/' && i < l)i++; 117 if(i < l) { 118 b = a + i + 1; 119 f.z = atoi(b); 120 } 121 else { 122 f.z = 1; 123 } 124 125 a[i] = '