一.需求:
1.支持四位数的四则运算;
2.支持括号;
3.限定题目数量;
4.支持分数出题和运算;
5.支持控制台输入。
二.具体代码实现:
1 // SiZeYS.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include<iostream> 6 #include<stdlib.h> 7 #include<iomanip> 8 #include<time.h> 9 #include<stdio.h> 10 #include <string> 11 #include"math.h" 12 #define true 1 13 #define false 0 14 #define OPSETSIZE 7 15 #define random() (rand() % 100000) 16 #pragma warning(disable: 4996) 17 #include"string.h" 18 typedef int Status; 19 using namespace std; 20 21 unsigned char Prior[7][7] = 22 { // 运算符优先级表 23 // '+' '-' '*' '/' '(' ')' '#' 24 /*'+'*/'>', '>', '<', '<', '<', '>', '>', 25 /*'-'*/'>', '>', '<', '<', '<', '>', '>', 26 /*'*'*/'>', '>', '>', '>', '<', '>', '>', 27 /*'/'*/'>', '>', '>', '>', '<', '>', '>', 28 /*'('*/'<', '<', '<', '<', '<', '=', ' ', 29 /*')'*/'>', '>', '>', '>', ' ', '>', '>', 30 /*'#'*/'<', '<', '<', '<', '<', ' ', '=', 31 }; 32 33 typedef struct StackChar 34 { 35 char c; 36 struct StackChar *next; 37 }SC; //StackChar类型的结点SC 38 39 typedef struct StackFloat 40 { 41 float f; 42 struct StackFloat *next; 43 }SF; //StackFloat类型的结点SF 44 SC *Push(SC *s, char c) //SC类型的指针Push,返回p 45 { 46 SC *p = (SC*)malloc(sizeof(SC)); 47 p->c = c; 48 p->next = s; 49 return p; 50 } 51 SF *Push(SF *s, float f) //SF类型的指针Push,返回p 52 { 53 SF *p = (SF*)malloc(sizeof(SF)); 54 p->f = f; 55 p->next = s; 56 return p; 57 } 58 SC *Pop(SC *s) //SC类型的指针Pop 59 { 60 SC *q = s; 61 s = s->next; 62 free(q); 63 return s; 64 } 65 SF *Pop(SF *s) //SF类型的指针Pop 66 { 67 SF *q = s; 68 s = s->next; 69 free(q); 70 return s; 71 } 72 float Operate(float a, unsigned char theta, float b) //计算函数Operate 73 { 74 switch (theta) 75 { 76 case '+': return a + b; 77 case '-': return a - b; 78 case '*': return a*b; 79 case '/': return a / b; 80 default: return 0; 81 } 82 } 83 char OPSET[OPSETSIZE] = { '+', '-', '*', '/', '(', ')', '#' }; 84 Status In(char Test, char *TestOp) 85 { 86 int Find = false; 87 for (int i = 0; i< OPSETSIZE; i++) 88 { 89 if (Test == TestOp[i]) 90 Find = true; 91 } 92 return Find; 93 } 94 Status ReturnOpOrd(char op, char *TestOp) 95 { 96 for (int i = 0; i< OPSETSIZE; i++) 97 { 98 if (op == TestOp[i]) 99 return i; 100 } 101 } 102 char precede(char Aop, char Bop) 103 { 104 return Prior[ReturnOpOrd(Aop, OPSET)][ReturnOpOrd(Bop, OPSET)]; 105 } 106 float EvaluateExpression(char* MyExpression) 107 { 108 // 算术表达式求值的算符优先算法 109 // 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合 110 SC *OPTR = NULL; // 运算符栈,字符元素 111 SF *OPND = NULL; // 运算数栈,实数元素 112 char TempData[20]; 113 float Data, a, b; 114 char theta, *c, Dr[] = { '#', ' ' }; 115 OPTR = Push(OPTR, '#'); 116 c = strcat(MyExpression, Dr); 117 strcpy(TempData, " ");//字符串拷贝函数 118 while (*c != '#' || OPTR->c != '#') 119 { 120 if (!In(*c, OPSET)) 121 { 122 Dr[0] = *c; 123 strcat(TempData, Dr); //字符串连接函数 124 c++; 125 if (In(*c, OPSET)) 126 { 127 Data = atof(TempData); //字符串转换函数(double) 128 OPND = Push(OPND, Data); 129 strcpy(TempData, " "); 130 } 131 } 132 else // 不是运算符则进栈 133 { 134 switch (precede(OPTR->c, *c)) 135 { 136 case '<': // 栈顶元素优先级低 137 OPTR = Push(OPTR, *c); 138 c++; 139 break; 140 case '=': // 脱括号并接收下一字符 141 OPTR = Pop(OPTR); 142 c++; 143 break; 144 case '>': // 退栈并将运算结果入栈 145 theta = OPTR->c; OPTR = Pop(OPTR); 146 b = OPND->f; OPND = Pop(OPND); 147 a = OPND->f; OPND = Pop(OPND); 148 OPND = Push(OPND, Operate(a, theta, b)); 149 break; 150 } //switch 151 } 152 } //while 153 return OPND->f; 154 } //EvaluateExpression 155 //符号生成 156 char create_symbol(int n) 157 { 158 int n1, j; 159 char symbol[1]; 160 if (n == 0) 161 { 162 n1 = 2; 163 } 164 else if (n = 1) 165 { 166 n1 = 4; 167 } 168 j = random() % n1; 169 if (j == 0) symbol[0] = '+'; 170 else if (j == 1) symbol[0] = '-'; 171 else if (j == 2) symbol[0] = '*'; 172 else symbol[0] = '/'; 173 return symbol[0]; 174 } 175 //把数字转换成字符串型 176 string int_string(int number) 177 { 178 char str[200]; 179 itoa(number, str, 10); 180 string str_ = str; 181 return str_; 182 } 183 //真分数合成一个字符串 184 string combination1(string str1, string str2, char k) 185 { 186 string equation; 187 equation = '(' + str1 + k + str2 + ')'; 188 return equation; 189 } 190 //新生成一个数 191 string create_num(int proper_fs, int range) 192 { 193 int num, num1, num2, fs; 194 string str_num, str_num1, str_num2; 195 num = random() % range + 1; 196 str_num = int_string(num); 197 if (proper_fs == 1) 198 { 199 fs = random() % 3; 200 if (fs == 1)//判断是否生成真分数 201 { 202 for (;;) 203 { 204 num1 = random() % range + 1; 205 num2 = random() % range + 1; 206 if (num1<num2) break; 207 } 208 str_num1 = int_string(num1); 209 str_num2 = int_string(num2); 210 str_num = combination1(str_num1, str_num2, '/'); 211 } 212 } 213 return str_num; 214 } 215 //运算式转换成一个字符串 216 string combination(string str1, string str2, char k) 217 { 218 string equation; 219 equation = str1 + k + str2; 220 return equation; 221 } 222 //得出正确答案 223 float get_ans(string str) 224 { 225 int len; 226 float ans; 227 len = str.length(); 228 //char num[len]; 229 char *num = new char[len]; 230 for (int j = 0; j<len; j++) 231 { 232 num[j] = str[j]; 233 } 234 //用堆栈解决。。。 235 ans = EvaluateExpression(num); 236 return ans; 237 } 238 //主函数 239 int main() 240 { 241 srand((int)time(NULL)); //设置时间种子 ,使得程序每次运行的结果都不同 242 int num1, num2, num3, num4, count, n, change, amount, shuchu, range, j, repeat = 0, bracket, proper_fs, right = 0, wrong = 0; 243 string str_num1, str_num2, temp; 244 float Answer, InputAns; 245 cout << "敢不敢来做一做我出的计算题呢?小伙伴儿,你要加油喽!!!一定要按要求作答哦~" << endl; 246 cout << "请老师先出题吧~" << endl; 247 cout << "有无乘除法?1有,0没有:" << endl; 248 cin >> n; 249 cout << "是否有括号?1有,0没有:" << endl; 250 cin >> bracket; 251 cout << "是否有真分数?1有,0没有:" << endl; 252 cin >> proper_fs; 253 cout << "请输入数字范围:" << endl; 254 cin >> range; 255 cout << "请输入出题数量:" << endl; 256 cin >> amount; 257 string Equation[1000]; 258 char symbol; 259 cout << amount << "道四则运算题如下,小伙伴们,开始答题啦:" << endl; 260 for (int i = 0; i<amount; i++) 261 { 262 //count = random() % 3 + 2; 263 count = 4; 264 str_num1 = create_num(proper_fs, range); 265 str_num2 = create_num(proper_fs, range); 266 symbol = create_symbol(n); 267 Equation[i] = combination(str_num1, str_num2, symbol); 268 if (count>2) 269 { 270 for (count; count > 2; count--) 271 { 272 symbol = create_symbol(n); 273 str_num1 = Equation[i]; 274 if (bracket == 1) 275 { 276 change = random() % 3; 277 if (change == 0) 278 { 279 str_num1 = '(' + str_num1 + ')'; 280 } 281 } 282 symbol = create_symbol(n); 283 str_num2 = create_num(proper_fs, range); 284 change = random() % 2; 285 if (change == 0) 286 { 287 temp = str_num1; 288 str_num1 = str_num2; 289 str_num2 = temp; 290 } 291 Equation[i] = combination(str_num1, str_num2, symbol); 292 } 293 } 294 //判断是否重复 295 for (j = 0; j < i; j++) 296 { 297 if (Equation[j] == Equation[i]) 298 { 299 i = i - 1; 300 repeat = 1; 301 break; 302 } 303 } 304 if (repeat != 1)//若不重复,则输出 305 { 306 cout << Equation[i] << "="; 307 //判断结果是否正确 308 cin >> InputAns; 309 Answer = get_ans(Equation[i]); 310 Answer *= 100; 311 int temp = (int)Answer; 312 Answer = ((double)temp) / 100.00; 313 if (InputAns == Answer) 314 { 315 cout << "回答正确,好棒呢!"; 316 right++; 317 } 318 else 319 { 320 cout << "你的答案好像不对哦!正确答案是"; 321 cout << setprecision(2) << fixed << Answer; 322 wrong++; 323 } 324 cout << endl; 325 } 326 } 327 cout << "你一共答对" << right << "道题哦,真棒呢!答错" << wrong << "道题,没关系,再接再厉哦!" << endl <<endl; 328 system("pause"); 329 330 }
三.运行结果:
、
四.总结:我认为上次的作业做得很粗糙,这次的改进相比上次有很大的进步,我和我的结对伙伴沈柏杉在这个项目上也都投入了大量的精力和时间,我们整整抽出一整天的时间在做,其中的身心俱疲只有我们自己知道。最终老师能给多少分,可能都不太重要了,重要我们有付出,并看到了成果。
ssh:git@git.coding.net:yuanyuancheng/sizeyunsuan.git
HTTPS:https://git.coding.net/yuanyuancheng/sizeyunsuan.git