四则运算3

  题目要求: 随机生成四则运算,要能判定用户输入的答案是否正确,并且能处理四则运算的混合算式。

  思路:首先产生一个随机数A,产生一个运算符x,将其存放在一个字符串(例如str)中,形成Ax形式,然后产生另外一个随机数B,也存放在str中,这样就形成了一个AxB形式的字符串,再产生一个只有0或者1的随机数,如果随机数是1就对AxB加括号,0则不加,继续产生运算符及随机数B,这个式子完毕,最后加一个‘=’号;然后就是控制加减是否有负数,如果有就重新产生四则运算的式子;在产生出所有的式子之后,用户可以输入答案,然后可以将用户输入的答案和原式所计算出来的答案比较,如果相等则计算正确,让计算做对题总数的count加1;那原式的答案是怎么计算出来的呢?利用数据结构中栈的知识,先定义运算符的优先级,然后将操作数和运算符优先级最大的入栈,栈内优先级最大的先进行计算,栈内外优先级相等则出栈;对于除不尽的将结果保留两位小数。

  具体代码如下:

  1 //第三次课堂小测验,2016/3/14
  2 //张晓菲、张哲
  3 //随机生成四则运算,可以判断用户输入是否正确以及输出做对题的总个数;处理四则运算混合算式;
  4 
  5 #include<stack>
  6 #include<iostream>
  7 #include<string>
  8 #include<sstream>
  9 #include<time.h>
 10 #include<iomanip>
 11 #include<fstream>
 12 using namespace std;
 13 
 14 int check_1(int a)//判断用户输入是否符合要求
 15 {
 16     if (a != 1 && a != 0)
 17     {
 18         cout << "输入格式不正确,请重新输入:";
 19         cin >> a;
 20     }
 21     return 0;
 22 }
 23 int check_2(int a)
 24 {
 25     if (a <= 0)
 26     {
 27         cout << "输入格式不正确,请重新输入:";
 28         cin >> a;
 29     }
 30     return 0;
 31 }
 32 
 33 string change(int num0)//将表达式转换为字符串类型
 34 {
 35     char str[100];
 36     _itoa_s(num0, str, 10);
 37     string str1 = str;
 38     return str1;
 39 }
 40 
 41 int judge(char c1, char c2)//设置+.-.*./.(.)的优先等级
 42 {
 43     int a1, a2;
 44     if ('+' == c1 || '-' == c1) a1 = 3;
 45     if ('*' == c1 || '/' == c1)a1 = 5;
 46     if ('(' == c1) a1 = 1;
 47     if (')' == c1) a1 = 7;
 48     if ('#' == c1) a1 = 0;
 49     if ('+' == c2 || '-' == c2)a2 = 2;
 50     if ('*' == c2 || '/' == c2)a2 = 4;
 51     if ('(' == c2) a2 = 6;
 52     if (')' == c2) a2 = 1;
 53     if ('#' == c2) a2 = 0;
 54     if (a1>a2) return 1;
 55     if (a1 == a2) return 0;
 56     if (a1<a2) return -1;
 57 }
 58 //符号运算函数
 59 double run(char c, double d1, double d2)//计算四则运算
 60 {
 61     switch (c)
 62     {
 63     case '+':
 64         return d1 + d2;
 65         break;
 66     case '-':
 67         return d1 - d2;
 68         break;
 69     case'*':
 70         return d1*d2;
 71         break;
 72     case '/':
 73         return d1/d2;
 74         break;
 75     default:
 76         return 0.0;
 77         break;
 78     }
 79 }
 80 double calculate(string str4)//计算表达式的值
 81 {
 82     char * op = "+-*/()#";
 83     //给表达式字符串str添加'#'结束标识符
 84     str4.append(1, '#');
 85     stack<char> OPTR;//运算符栈
 86     stack<double> OPND;//操作数栈
 87     int a = -1;
 88     //先将#符号入栈
 89     OPTR.push('#');
 90     while (true)
 91     {
 92         int b = a + 1;
 93         a = str4.find_first_of(op, a + 1);
 94         if (a == string::npos) break;
 95         if (a != b)
 96         {
 97             string ss(str4, b, a - b);
 98             double d = atof(ss.c_str());
 99             //数据先入栈
100             OPND.push(d);
101         }
102         //运算符优先级比较
103         int ju = judge(OPTR.top(), str4[a]);
104         if (-1 == ju)//栈外优先级大直接入栈
105         {
106             OPTR.push(str4[a]);
107         }
108         if (0 == ju)//栈内外优先级相等则出栈
109         {
110             OPTR.pop();
111         }
112         if (1 == ju)//栈内优先级大,出栈进行运算
113         {
114             double d1 = OPND.top();
115             OPND.pop();
116             double d2 = OPND.top();
117             OPND.pop();
118             d1 = run(OPTR.top(), d2, d1);
119             //运算结果入栈
120             OPND.push(d1);
121             OPTR.pop();
122             a--;
123         }
124     }
125     //删除表达式最后的'#'结束标识符
126     str4.erase(str4.length() - 1, 1);
127     return  OPND.top();
128 }
129 int main()//主函数
130 {
131     srand((unsigned)time(NULL));//时间种子
132     int max, num, choose_way, choose_chengchu,choose_minus, choose_brackets;
133     int num_suanshi;
134     double input_result;
135     int count = 0;
136     int len;//求字符串长度
137     ofstream fout("1.txt");//输出到文件
138 
139     cout << "请输入允许的最大数值:";
140     cin >> max;
141     int k = check_2(max);
142 
143     cout << "请输入生成的题目个数:";
144     cin >> num;
145     int k1 = check_2(num);
146 
147     cout << "请选择输出方式(1、输出到屏幕 0、输出到文件):";
148     cin >> choose_way;
149     int k2 = check_1(choose_way);
150 
151     cout << "是否有乘除法(1、有 0、没有):";
152     cin >> choose_chengchu;
153     int k3 = check_1(choose_chengchu);
154 
155     switch (choose_chengchu)
156     {
157     case 1:
158 
159         break;
160     case 0:
161         cout << "请选择加减是否有负数(1、有 0、没有):";
162         cin >> choose_minus;
163         int k5 = check_1(choose_minus);
164         break;
165     }
166     
167     cout << "请选择是否有括号(1、有 0、没有):";
168     cin >> choose_brackets;
169     int k6 = check_1(choose_brackets);
170 
171     cout<<"请选择一行输出多少个算式:";
172     cin>>num_suanshi;
173     char sym[4] = { '+', '-', '*', '/' };
174     double result[1000];
175     double result1[1000];
176     int i;
177     for (i = 0; i < num; i++)
178     {
179         int oper_num = rand() % 8 + 1;//一个式子中含有几个数
180         string str_1, str_2_1, str_3;
181         int num1 = rand() % (max + 1)+1;
182         int num2 = rand() % (max + 1)+1;
183         int d;
184         switch (choose_chengchu)//是否有乘除
185         {
186         case 1:
187             d = rand() % 4;
188             break;
189         case 0:
190             d = rand() % 2;
191             break;
192         }
193         str_1 = change(num1) + sym[d] + change(num2);
194         for (int j = 0; j < oper_num; j++)
195         {
196             int c;
197             int num3 = rand() % (max + 1)+1;
198             switch (choose_chengchu)//是否有乘除
199             {
200             case 1:
201                 c = rand() % 4;
202                 break;
203             case 0:
204                 c = rand() % 2;
205                 break;
206             }
207             str_1 = str_1 + sym[c] + change(num3);
208             int b;
209             b = rand() % 2;
210             switch (choose_brackets)//判断是否有括号
211             {
212             case 1://有括号时随机产生括号
213                 if (b == 0)
214                 {
215                     str_1 = '(' + str_1 + ')';
216                 }
217                 if (b == 1)
218                 {
219                     str_1 = str_1;
220                 }
221                 break;
222             case 0://选择无括号时
223                 break;
224             }
225             str_3 = str_1;
226         }
227         result[i]= calculate(str_3);//调用calculate函数计算四则运算表达式的结果
228         switch (choose_chengchu)
229         {
230         case 1://有乘除
231             break;
232         case 0://没有乘除
233             switch (choose_minus)
234             {
235             case 1://有负数
236                 break;
237             case 0://没有负数
238             panduan :
239                 if (result[i]<0)//加减混合运算中保证结果无负数
240                 {
241                     for (int j = 0; j<oper_num; j++)
242                     {
243                         int num2_1 = rand() % (max + 1)+1;
244                         int d1;
245                         d1 = rand() % 2;
246                         str_1 = change(num2_1) + sym[d1];
247                         str_2_1 = str_2_1 + str_1;
248                         int num3 = rand() % (max + 1);
249                         str_3 = str_2_1 + change(num3) ;
250                         result[i] = calculate(str_3);
251                         goto panduan;
252                     }
253                 }
254                 break;
255             }
256             break;
257         }
258         len=sizeof(str_3);
259         int m=40-len;
260         result1[i]= calculate(str_3);
261         str_3=change(i+1)+""+str_3+"=";
262 
263         if((int(result1[i])-result1[i])!=0)//除不尽的情况下将结果保留两位小数
264         {
265             result1[i]=result1[i]*100+0.5;
266             result1[i]=int(result1[i]);
267             result1[i]=result1[i]/100;
268         }
269         switch (choose_way)//选择输出方式
270         {
271         case 1://输出到屏幕
272             cout.flags(ios::left);
273             cout <<setw(40)<<str_3 ;
274             if((i+1)%num_suanshi==0)
275                 cout<<endl;
276             break;
277         case 0://输出到文件
278             fout.flags(ios::left);
279             fout <<setw(40)<<str_3 ;
280             if((i+1)%num_suanshi==0)
281                 fout<<endl;
282             break;
283         } 
284     }
285     cout<<"请输入式子的答案:"<<endl;
286     for(i=0;i<num;i++)
287     {
288         cout<<i+1<<"";
289         cin >> input_result;//用户输入的计算结果
290         if (((result1[i]-0.05)<input_result)&&(input_result<(result1[i]+0.05)))
291         {
292             cout << "输入正确!" << endl;
293             count = count + 1;
294         }
295         else
296             cout << "输入错误!" << endl;
297     }
298     cout << "您总共做对题的个数是:";
299     cout << count << endl;
300     return 0;
301 }

运行结果如下:

  计划日志:

  计划每天用一个小时来做这次作业,每天实现一个小功能。比如第一天实现随机产生式子的功能。第二天实现随机产生括号的功能。第三天产生计算结果并判断用户输入是否正确的 功能……

  缺陷记录:

  除法无法判断是否有余数,不能查重,可能会出现题目一样的算式。

  时间记录日志:

原文地址:https://www.cnblogs.com/quite-love/p/5295294.html