标签:
题目要求: 随机生成四则运算,要能判定用户输入的答案是否正确,并且能处理四则运算的混合算式。
思路:首先产生一个随机数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 }
运行结果如下:
总结:这次作业不足的地方是:除法无法判断是否有余数,不能查重,可能会出现题目一样的算式。但是较上次作业来说,能随机产生括号,以及长式子,并且可以判断用户输入的结果是否正确。两个人合作确实比一个人弄得要快,而且两个人思路也就更多一点。
时间记录日志:
标签:
原文地址:http://www.cnblogs.com/quite-love/p/5295294.html