第二周:结对项目改进

一.需求:

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

原文地址:https://www.cnblogs.com/yuanyuancheng/p/5863009.html