四则运算 3

老师提出了新的要求

1.学生写的程序必须能判定用户的输入答案是否正确

2.程序必须能处理四种运算的混合算式

要求两人合作分析,单独编程,单独撰写博客

团队成员:苗堃、罗毅(http://www.cnblogs.com/ly199553/

设计思路:

查阅了相关资料,发现小学四则运算含有括号数量不多,于是结组讨论时选取了较为简单的我的程序,将数组全部转化为字符串形式,

利用栈实现中缀表达式转换为后缀表达式,转换原则为

1.当读到一个操作数时,立即将它放到输出中。操作符则不立即输出,放入栈中。遇到左圆括号也推入栈中。

2.如果遇到一个右括号,那么就将栈元素弹出,将符号写出直到遇到一个对应的左括号。但是这个左括号只被弹出,并不输出。

3.在读到操作符时,如果此时栈顶操作符优先性大于或等于此操作符,弹出栈顶操作符直到发现优先级更低的元素位置。除了处理‘)‘

的时候,否则决不从栈中移走‘(‘。操作符中,‘+‘ ‘-‘优先级最低,‘(‘ ‘)‘优先级最高。

4.如果读到输入的末尾,将栈元素弹出直到该栈变成空栈,将符号写到输出中。

两位数的字符串传递时加入字符@来区分(http://www.cnblogs.com/ly199553/p/5292391.html

输入答案后与正确答案进行比较判断对错

  1 #include<stack>
  2 #include<iostream>
  3 #include<deque>
  4 #include<string>
  5 #include<sstream>
  6 #include<time.h>
  7 using namespace std;
  8
  9 int  Num[100];    //将数字存入数组a
 10 string op_arrays[100];    //将运算符存入数组b
 11 string  All[100];    //合成总数组e
 12 string fu[100];      //辅助数组
 13 int true_num = 0;     //统计做对的题目数
 14 int false_num = 0;    //统计做错的题目数
 15
 16 bool isPra(char);    //判断是否为括号
 17 int getPri(char);    //获得符号优先性
 18 void check(char c, stack<char>& coll2, deque<char>& coll3);//判断符号优先性
 19 void allocate(deque<char>& coll1, stack<char>& coll2, deque<char>& coll3);  //将中缀表达式分解为符号和运算数
 20 void calculate(deque<char>& coll3, stack<double>& coll4);  //计算后缀表达式
 21
 22 int main()
 23 {
 24     srand((int)time(NULL));//设置随机种子,使得程序每次运行的结果都不同
 25     int subject_number;    //出题数量
 26     int random_number = 0;    //运算数字字数
 27     int operation_character = 0;
 28     int fuhao = 0;    //判定运算符
 29
 30     int Jude_has_brackets;       //定义左、右括号的是否存在的随机变量
 31     string left;    //左括号变量
 32     string right;    //左括号变量
 33     string sign = "a";   //定义符号变量
 34     char Jude_has_mul_dev;   //定义是否需要乘除法的变量
 35
 36     deque<char> coll0;  //消除中缀表达式的空格
 37     deque<char> coll1;  //盛放中缀表达式
 38     stack<char> coll2;  //盛放操作符
 39     deque<char> coll3;    //盛放后缀表达式
 40     stack<double>coll4;    //计算后缀表达式的辅助容器
 41
 42     int min, Max;    //定义输入的值得范围的最值(仅能输入整数<=30)
 43     string w = " ";
 44
 45     //写一个简易菜单
 46     cout << "欢       / ̄\_/ ̄\ "<<endl;
 47     cout << "迎      ▏     ▔▔▔▔\    " << endl;
 48     cout << "使     /\ /      ﹨" << endl;
 49     cout << "用   ∕       /   )" << endl;
 50     cout << "小   ▏        ●  ▏"<<endl;
 51     cout << "天   ▏           ▔█ " << endl;
 52     cout << "才  ◢██◣      /\__/" << endl;
 53     cout << "四   █████◣       /" << endl;
 54     cout << "则   █████████████◣ " << endl;
 55     cout << "运 ◢██████████████▆▄" << endl;
 56     cout << "算  █◤◢██◣◥█████████◤\" << endl;
 57     cout << "自 ◥◢████ ████████◤   \" << endl;
 58     cout << "助   █████ ██████◤      ﹨" << endl;
 59     cout << "系  │   │█████◤        ▏" << endl;
 60     cout << "统  │   │            ▏" << endl;
 61     cout << "   ∕   ∕    /▔▔▔\     ∕" << endl;
 62     cout << "  ∕___/﹨   ∕      \  /\" << endl;
 63     cout << "           \    \_     ﹨/  ﹨" << endl;
 64     cout << "             \___\     ﹨/▔\﹨/▔\" << endl;
 65     cout << "                      \   ∕" << endl;
 66         cout << "1.请输入产生数字的范围(最小和最大):";
 67         cin >> min >> Max;
 68         cout << "提示:若您需要做乘除法 请不要做超过30以外的乘除法" << endl;
 69         cout << endl;
 70         cout << "2.是否需要乘除法[y为需要乘除法 n为不需要乘除法] ";
 71         cin >> Jude_has_mul_dev;
 72         while (min<0)
 73         {
 74         cout << "请做正数运算:" << endl;
 75         cout << "输入最小值" << endl;
 76         cin >> min;
 77          }
 78     while (Max>30 && Jude_has_mul_dev == ‘y‘)
 79     {
 80         cout << "请重新输入最大值:" << endl;
 81         cin >> Max;
 82     }
 83     cout << "请输入出题数量:";
 84     cin >> subject_number;
 85
 86     int i = 0, j, k;
 87     if (‘y‘ == Jude_has_mul_dev)
 88     {
 89         random_number = rand() % 9 + 2;    //随机生成2~10个数
 90         for (j = 0; j < subject_number; j++)    //设置题目数量
 91         {
 92             //清除数组元素
 93             memset(Num, 0, sizeof(Num));
 94             memset(op_arrays, 0, sizeof(op_arrays));
 95             memset(fu, 0, sizeof(fu));
 96
 97             random_number = rand() % 9 + 2;    //随机生成2~10个数
 98             for (i = 0; i < random_number; i++)
 99             {
100                 stringstream ss;
101                 operation_character = rand() % (Max - min + 1) + min;
102                 Num[i] = operation_character;
103                 fuhao = rand() % 4 + 1;
104                 switch (fuhao)
105                 {
106                 case 1:sign = "+"; break;
107                 case 2:sign = "-"; break;
108                 case 3:sign = "*"; break;
109                 case 4:sign = "/"; break;
110                 }
111                 //若为除法则除数不为零
112                 while (Num[i] == 0 && i >= 1)
113                 {
114                     if (op_arrays[i - 1] == "/")
115                     {
116                         operation_character = rand() % (Max - min + 1) + min;
117                         Num[i] = operation_character;
118                     }
119                 }
120                 op_arrays[i] = sign;
121
122                 fu[4 * i] = w;
123                 ss << Num[i];
124                 ss >> fu[4 * i + 1];
125                 fu[4 * i + 2] = w;
126                 if (i != (random_number - 1))   //最后一次不产生符号
127                     fu[4 * i + 3] = op_arrays[i];
128                 else fu[4 * i + 3] = w;
129             }
130             Jude_has_brackets = rand() % 2 + 1;  //随机确定有无括号
131             switch (Jude_has_brackets)
132             {
133             case 1:
134                 left = "(";
135                 right = ")";
136                 break;
137             case 2:
138                 left = w;
139                 right = w;
140                 break;
141             }
142
143             for (i = 0; i < random_number; i++)
144             {
145                 for (k = 0; k < (random_number - 1) / 2; k++)
146                 {
147                     fu[4 * k] = left;
148                     if (left == "(")
149                     {
150                         fu[4 * k + 10] = right;
151                     }
152                 }
153                 if ((fu[4 * i] == left) && (fu[4 * i + 2] == right))
154                 {
155                     fu[4 * i] = w;
156                     fu[4 * i + 2] = w;
157                 }
158
159                 All[j] += fu[4 * i] + fu[4 * i + 1] + fu[4 * i + 2] + fu[4 * i + 3];
160             }
161             cout << j + 1 << "题. " << All[j] << "= " ;
162             for (int i = 0; i != All[j].size(); ++i)
163             {
164                 //逐一加入每个字符,这里使用deque因为deque在两端删除添加的速度最快
165                 coll0.push_back(All[j][i]);      //在尾部加入一个元素
166             }
167
168             //将coll0转换为后缀表达式coll1
169             for (int i = 0; i != All[j].size(); ++i)
170             {
171                 char k = coll0.front();
172                 coll0.pop_front();
173                 if (k != ‘ ‘)        //消除空格
174                     coll1.push_back(k);
175             }
176             //从coll中取出元素,分配元素到coll2和coll3中
177             allocate(coll1, coll2, coll3);
178
179             //计算后缀表达式
180             calculate(coll3, coll4);
181
182             double result = 0;
183             cin >> result;
184             if (result == coll4.top())
185             {
186                 cout << "正确!" << endl;
187                 true_num++;
188                 cout << "计算结果为:" << coll4.top() << endl;
189             }
190             else
191             {
192                 cout << "错误!" << endl;
193                 false_num++;
194                 cout << "计算结果为:" << coll4.top() << endl;
195             }
196             //将栈清空
197             coll4.pop();
198         }
199         if (true_num >= false_num)
200             cout << "恭喜你!您共做对" << true_num << "道题!" << "做错" << false_num << "道题!" << endl;
201         else
202             cout << "还需加油!您共做对" << true_num << "道题!" << "做错" << false_num << "道题!" << endl;
203     }
204     else
205     {
206         random_number = rand() % 9 + 2;    //随机生成2~10个数
207         for (j = 0; j < subject_number; j++)    //设置题目数量
208         {
209             //清除数组元素
210             memset(Num, 0, sizeof(Num));
211             memset(op_arrays, 0, sizeof(op_arrays));
212             memset(fu, 0, sizeof(fu));
213
214             random_number = rand() % 9 + 2;    //随机生成2~10个数
215             for (i = 0; i < random_number; i++)
216             {
217                 stringstream ss;
218                 operation_character = rand() % (Max - min + 1) + min;
219                 Num[i] = operation_character;
220                 fuhao = rand() % 2 + 1;
221                 switch (fuhao)
222                 {
223                 case 1:sign = "+"; break;
224                 case 2:sign = "-"; break;
225                 }
226                 op_arrays[i] = sign;
227
228                 fu[4 * i] = w;
229                 ss << Num[i];
230                 ss >> fu[4 * i + 1];
231                 fu[4 * i + 2] = w;
232                 if (i != (random_number - 1))   //最后一次不产生符号
233                     fu[4 * i + 3] = op_arrays[i];
234                 else fu[4 * i + 3] = w;
235             }
236             Jude_has_brackets = rand() % 2 + 1;  //随机确定有无括号
237             switch (Jude_has_brackets)
238             {
239             case 1:
240                 left = "(";
241                 right = ")";
242                 break;
243             case 2:
244                 left = w;
245                 right = w;
246                 break;
247             }
248
249             for (i = 0; i < random_number; i++)
250             {
251                 for (k = 0; k < (random_number - 1) / 2; k++)
252                 {
253                     fu[4 * k] = left;
254                     if (left == "(")
255                     {
256                         fu[4 * k + 10] = right;
257                     }
258                 }
259                 if ((fu[4 * i] == left) && (fu[4 * i + 2] == right))
260                 {
261                     fu[4 * i] = w;
262                     fu[4 * i + 2] = w;
263                 }
264
265                 All[j] += fu[4 * i] + fu[4 * i + 1] + fu[4 * i + 2] + fu[4 * i + 3];
266             }
267             cout << j + 1 << "题. " << All[j] << "= " << endl;
268             for (int i = 0; i != All[j].size(); ++i)
269             {
270                 //逐一加入每个字符,这里使用deque因为deque在两端删除添加的速度最快
271                 coll0.push_back(All[j][i]);      //在尾部加入一个元素
272             }
273
274             //将coll0转换为后缀表达式coll1
275             for (int i = 0; i != All[j].size(); ++i)
276             {
277                 char k = coll0.front();
278                 coll0.pop_front();
279                 if (k != ‘ ‘)        //消除空格
280                     coll1.push_back(k);
281             }
282             //从coll中取出元素,分配元素到coll2和coll3中
283             allocate(coll1, coll2, coll3);
284
285             //计算后缀表达式
286             calculate(coll3, coll4);
287
288             double result = 0;
289             cin >> result;
290             if (result == coll4.top())
291             {
292                 cout << "正确!" << endl;
293                 true_num++;
294                 cout << "计算结果为:" << coll4.top() << endl;
295             }
296             else
297             {
298                 cout << "错误!" << endl;
299                 false_num++;
300                 cout << "计算结果为:" << coll4.top() << endl;
301             }
302             //将栈清空
303             coll4.pop();
304         }
305         if (true_num >= false_num)
306             cout << "恭喜你!您共做对" << true_num << "道题!" << "做错" << false_num << "道题!" << endl;
307         else
308             cout << "还需加油!您共做对" << true_num << "道题!" << "做错" << false_num << "道题!" << endl;
309     }
310     return 0;
311 }
312
313
314 //判断是否为括号
315 bool isPra(char c)
316 {
317     if (c == ‘(‘ || c == ‘)‘)
318         return true;
319     else
320         return false;
321 }
322
323 //获得符号的优先性
324 int getPri(char c)
325 {
326     switch (c)
327     {
328     case ‘+‘:
329     case ‘-‘:
330         return 0;    //如果是加减,返回0
331         break;
332     case ‘*‘:
333     case ‘/‘:
334         return 1;    //如果是乘除,返回1
335         break;
336     case ‘(‘:
337     case ‘)‘:
338         return -1;  //注意,这里将括号设为最低优先级,因此括号不会被弹出,除非遇到右括号
339         break;
340     }
341     return 2;
342 }
343
344 //判断符号的优先性
345 void check(char c, stack<char>& coll2, deque<char>& coll3)
346 {
347     if (coll2.empty())
348     {
349         coll2.push(c);
350         return;
351     }
352
353     if (isPra(c))
354     {
355         if (c == ‘(‘)
356             coll2.push(c);
357         else
358         {
359             //弹出所有元素直到遇到左括号
360             while (coll2.top() != ‘(‘)
361             {
362                 char ch = coll2.top();
363                 coll3.push_back(ch);
364                 coll2.pop();
365             }
366
367             //当遇到左括号时,弹出但不加入coll3(后缀表达式中)--(“(”“)”都不放入后缀表达式中)
368             coll2.pop();  //弹出左括号
369         }
370     }
371     else    //如果不是括号
372     {
373         //取出栈顶元素,与当前符号进行优先性比较
374         char sym = coll2.top();
375
376         //比较两符号的优先性
377         if (getPri(c) <= getPri(sym))
378         {
379             //如果c的优先性比栈顶符号小或等于,弹出栈顶元素
380             coll2.pop();
381             //并将其压入coll3(后缀表达式)中
382             coll3.push_back(sym);
383             //递归调用check,比较当前符号c与下一个栈顶符号的优先性
384             check(c, coll2, coll3);
385         }
386         else
387         {
388             //如果c比栈顶符号优先级大,那将c压入coll2(操作符栈)中
389             coll2.push(c);
390         }
391     }
392 }
393
394 //从coll中取出元素,分配元素到coll2和coll3中
395 void allocate(deque<char>& coll1, stack<char>& coll2, deque<char>& coll3)
396 {
397     while (!coll1.empty())
398     {
399         char c = coll1.front();
400         coll1.pop_front();
401
402         if (c >= ‘0‘&&c <= ‘9‘)
403         {
404             coll3.push_back(c);
405             //判断是否为两位数
406             if (!coll1.empty())
407             {
408                 c = coll1.front();
409                 if (c >= ‘0‘&&c <= ‘9‘)
410                     coll3.push_back(‘@‘);
411             }
412         }
413         else
414         {
415             //调用check函数,针对不同情况作出不同操作
416             check(c, coll2, coll3);
417         }
418
419     }
420
421     //如果输入结束,将coll2的元素全部弹出,加入后缀表达式中
422     while (!coll2.empty())
423     {
424         char c = coll2.top();
425         coll3.push_back(c);
426         coll2.pop();
427     }
428 }
429
430
431 //计算后缀表达式(修改)
432 void calculate(deque<char>& coll3, stack<double>& coll4)
433 {
434     while (!coll3.empty())
435     {
436         char c = coll3.front();   //取出第一个元素
437         double op = 0;
438         coll3.pop_front();   //并弹出此元素
439                              //coll3.erase(coll3.begin());
440                              //如果是操作数,压入栈中
441
442                              //若是两位数在压入辅助数组后需要进行判断
443         if (c >= ‘0‘&&c <= ‘9‘)
444         {
445             op = (c - ‘0‘);
446             coll4.push(op);
447             //cout<<"op="<<op<<endl;
448         }
449         else if (c == ‘@‘)            //如果是两位数则再读一位(若超过两位需要while扩展)
450         {
451             char d = coll3.front();
452             op = coll4.top();
453             coll4.pop();
454             op = op * 10 + (d - ‘0‘);
455             coll4.push(op);
456             coll3.pop_front();
457         }
458         else     //如果是操作符,从栈中弹出元素进行计算
459         {
460             double op1 = coll4.top();
461             coll4.pop();
462             double op2 = coll4.top();
463             coll4.pop();
464             switch (c)
465             {
466             case ‘+‘:
467                 coll4.push(op2 + op1);
468                 break;
469             case ‘-‘:
470                 coll4.push(op2 - op1);
471                 break;
472             case ‘*‘:
473                 coll4.push(op2*op1);
474                 break;
475             case ‘/‘:
476                 coll4.push(op2 / op1);  //注意是op2(op)op1而不是op1(op)op2
477                 break;
478             }
479         }
480     }
481 }

结果截图:

总结反思:

本次只做了些辅助工作,本来经过上次的实验很有信心想通过完成这次实验来提高自己(确实有所提高,但没有达到预期),虽然花了足够多的时间,数组转换为字符串、添加真分数这些较为简单的步骤自己都没有完成,效率不高,自己总结下原因有二:1.结对编程对同组大牛有依赖心理 2.没有理清楚思路头绪上来就敲代码(总体表现很慌乱,不知所措),今后一定要先理清思路再动手,有一个明确的方向,要学的很多,努力程度还差很远,加油!

时间: 2024-11-02 21:56:45

四则运算 3的相关文章

自动生成小学四则运算题目(C语言)

这个简易四则运算是我在百度上找的博主叫53余雅诗的一篇c语言代码,网址为http://www.cnblogs.com/ys1101/p/4368103.html,功能是可以选择加减乘除进行简易的四则运算,判断对错.我在VS2017上编译没有bug,因为功能只有整数运算,所以我在此基础上加了真分数的四则运算以及统计得分等,最后成功运行程序.我把我的源代码放在github上,地址为https://github.com/xiaofancheng/helloworld.

四则运算题目生成程序

a.需求分析 看了大家对于本课程的目标和规划,很多同学都希望能提高自己的实践能力,没有捷径可走,就是练习.练习再练习!那么就从第一个个人项目开始吧,用一周的时间完成一个基于控制台的四则运算程序,实现一个自动生成小学四则运算题目的命令行程序 从<构建之法>第一章的 "程序" 例子出发,像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 "软件",满足以下需求: 除了整数以外,还要支持真分数的四则运算,真分数的运算,例如:1/6 + 1/8 =

四则运算题目生成程序(基于控制台)

题目描述: 能自动生成小学四则运算题目的命令行 "软件",满足以下需求: 除了整数以外,还要支持真分数的四则运算,真分数的运算,例如:1/6 + 1/8 = 7/24 运算符为 +, ?, ×, ÷ 并且要求能处理用户的输入,并判断对错,打分统计正确率 要求能处理用户输入的真分数, 如 1/2, 5/12 等 使用 -n 参数控制生成题目的个数,例如执行下面命令将生成10个题目 功能设计: 1.  通过随机数的生成,实现+, ?, ×, ÷的确定 2.  +, ?, ×, ÷分别赋予整

第一周 结对编程四则运算

项目需求:程序随机生成四则运算计算题,并在用户填写答案后判断答案正误. 结对成员:李峤 任务分配:算法思想及采用的主要函数由李峤负责. 部分代码输入及结果测试由本人负责. 大体分成两个模块 :1.随机生成四则运算计算题 2.判断录入答案正误 主要代码如下: 1 #include<stdio.h> 2 #include<string.h> 3 #include<time.h> 4 #include<stdlib.h> 5 int main() 6 { 7 ch

判断随机生成的四则运算结果

功能:1.随机生成一个四则运算 2.用户输入式子结果后判断是否正确(结果取整) #include<stdio.h> #include<string.h> #include<stdlib.h> #include<stack> using namespace std; int n,t,n1; struct ZX { char a; bool b;//if b=0 括号 if b=1 数字 } ; stack<ZX>s1; void atersz(ZX

四则运算作业初步_064121陶源

这个四则运算的功能很有限,只能进行两个数的加减乘除四种运算,能显示最简分数结果,但没法将能化为整数的分数变成整数,比如6/3,最后会显示成2/1. 代码类型是C++,技巧上,参考了网上的operator重载操作符这个技巧,自己本不知道这个知识点. 分数化简的过程自己也是参考了其他资源,然后自己仔细阅读并理解,在旁边用例子注释. 编译平台是在Mac OS系统的Xcode上编译的,第一次在非vc++平台上编译. 代码:                                        

二柱子四则运算3

二柱子四则运算3 可怜的二柱子……又一次被坑了…… 老师又在上次的“二柱子四则运算2”的基础上增添了要求,如下: 1.学生写的程序必须能判定用户的输入答案是否正确.直到题目结束,告诉用户做对了几道题. 2.程序必须能处理四种运算的混合模式. 注意:连续的减法和除法,应该遵守左结合的规定. 连续除法要打括号,否则会引起歧义. 一.实验思路 二.实验源代码 三.实验总结和反思 最后,附上我和我的小伙伴的工作照……没有正脸.老师们不要介意啦啦啦~~~~ 小伙伴博客内容页:http://www.cnbl

软件工程第一次作业,小学生四则运算的出题程序

一.背景 阿超有个儿子上小学二年级,老师每天让家长给孩子出30道加减法题,虽然不多,但是每天都做也算是个负担,阿超作为一个老牌程序员当然想用计算机来解决这个小问题,目前对于这个问题对于任何语言都不是问题,比如: C/C++.C#.Java.Python.VB.JavaScript.Perl…… 具体要求如下: 能自动生成小学四则运算题目(注意是给小学生用的,要是结果出现负数的话他们会迷茫的!) 除了整数外,还要支持真分数的四则运算 请大家用任何一种自己擅长的语言来编写这段程序,并把程序的介绍和自

软件工程之四则运算--Github

由于现在配置问题,然后借用同学电脑将代码上传至Github,网址为:https://github.com/be821/RealFour 参考相关Github文档: 1. http://my.oschina.net/u/1050949/blog/194536?fromerr=IBt08Hdf 2. http://www.linuxidc.com/Linux/2013-06/85372p3.htm 3. http://blog.csdn.net/yanzi1225627/article/detail

四则运算封装

form1 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; namespace 四则运算 { public partial class Form1