在第三次实验的基础上,teacher又对此提出了新的要求,实现网页版或安卓的四则运算。
结对开发伙伴:
博客名:斗破2
姓名:王文奇
博客链接:http://www.cnblogs.com/qwer111/
详细网页四则运算要求:
1、生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在e1-e2的子表达式,那么结果大于等于0;
2、生成的题目中如果存在形式如e1/e2的子表达式,那么其结果应该是真分数。
3、每道题目中出现的运算符个数不超过3个,括号不做详细要求。
问题分析:
在第三次实验的基础上,要求把C++语言转换成java语言,即把cpp文件程序转换为java,jsp文件。但由于C和java在全局变量和栈的应用上有一定的不同,在对栈的使用中由于出栈和读取栈顶元素都为Object对象转换起来比较麻烦,所以我们在原先cpp文件中栈的应用改成了数组来实现压栈入栈。因为是网页版的所以就会使用jsp,html与java文件之间的数据交换,我们通过session,request和调用返回函数等方法来实现数据交互。
所遇困难:
1、在使用java中的栈时,出栈元素难以转换为所要类型。
2、jsp之间传递数组返回nill.
3、jsp与java之间的数据交互。
解决办法:
1、因为是顺序栈,所以直接使用数组来实现栈的所有功能
2、使用session来传递数组
3、在class文件中书写一个返回函数,在new生成对象时自动传递数组
前cpp文件:
1 #include<iostream> 2 #include<string> 3 #include<sstream> 4 #include<time.h> 5 #include<iomanip> 6 #include<fstream> 7 #define MAX 100 8 using namespace std; 9 10 stringstream formula; //当前算式 11 string buffer[MAX]; //缓冲区数组 12 int TopNumber; //上限 13 int BaseNumber; //下限 14 int IsMulDlvExist; //是否有乘除 15 int Amount; //操作数的个数 16 int BracketNum; //括号个数 17 int LBraket[2]; //左括号的位置 18 int RBraket[2]; //右括号的位置 19 int IsNeg; //是否有负数 20 int IsRem; //是否有余数 21 int IsBra; //是否有括号 22 int IsRep; //是否重复 23 float Result[MAX]; //正确结果数组 24 char lastOp; //记录上个运算符是否为除号 25 26 //优先级数组 27 char prior[7][7] = { 28 { '>', '>', '<', '<', '<', '>', '>' }, 29 { '>', '>', '<', '<', '<', '>', '>' }, 30 { '>', '>', '>', '>', '<', '>', '>' }, 31 { '>', '>', '>', '>', '<', '>', '>' }, 32 { '<', '<', '<', '<', '<', '=', ' ' }, 33 { '>', '>', '>', '>', ' ', '>', '>' }, 34 { '<', '<', '<', '<', '<', ' ', '=' } 35 }; 36 //操作符栈 37 typedef struct { 38 char *base; 39 char *top; 40 }OperChar; 41 //操作数栈 42 typedef struct{ 43 float *base; 44 float *top; 45 }NumberLink; 46 //初始化栈 47 void InitOperStack(OperChar &S) 48 { 49 S.base = new char[MAX]; 50 if (!S.base) 51 exit(1); 52 S.top = S.base; 53 } 54 void InitNumStack(NumberLink &S) 55 { 56 S.base = new float[MAX]; 57 if (!S.base) 58 exit(1); 59 S.top = S.base; 60 } 61 //进栈 62 void PushOper(OperChar &S,char e){ 63 if (S.top - S.base == MAX) 64 exit(1); 65 *S.top++ = e; 66 67 } 68 void PushNum(NumberLink &S,float e){ 69 if (S.top - S.base == MAX) 70 exit(1); 71 *S.top++ = e; 72 } 73 //出栈 74 void PopOper(OperChar &S, char &e) 75 { 76 if (S.top == S.base) 77 exit(1); 78 e = *--S.top; 79 } 80 void PopNum(NumberLink &S, float &e) 81 { 82 if (S.top == S.base) 83 exit(1); 84 e = *--S.top; 85 } 86 //取栈顶元素 87 char GetTopOper(OperChar S) 88 { 89 if (S.top == S.base) 90 { 91 exit(1); 92 93 } 94 return *(S.top - 1); 95 } 96 float GetTopNum(NumberLink S) 97 { 98 if (S.top == S.base) 99 { 100 exit(1); 101 102 } 103 return *(S.top - 1); 104 } 105 //将操作符转化为优先级数组的下标 106 int Change(char Oper) 107 { 108 switch (Oper) 109 { 110 case '+': return 0; break; 111 case '-': return 1; break; 112 case '*': return 2; break; 113 case '/': return 3; break; 114 case '(': return 4; break; 115 case ')': return 5; break; 116 case '=': return 6; break; 117 default: return 6; break; 118 119 } 120 } 121 //返回优先级的大小 122 char Precede(char Oper, char ch) 123 { 124 return prior[Change(Oper)][Change(ch)]; 125 } 126 //计算两个数的结果 127 float Operate(float first,char oper1, float second) 128 { 129 switch (oper1) 130 { 131 case '+': 132 { 133 return (first + second); 134 break; 135 } 136 case '-': 137 { 138 return (first - second); 139 break; 140 } 141 case '*': 142 { 143 return (first * second); 144 break; 145 } 146 case '/': 147 { 148 if (second == 0) 149 { 150 IsRep = 1; 151 return 0; 152 } 153 return (first / second); 154 break; 155 156 } 157 default: return 0; break; 158 } 159 } 160 //数字的个数 161 void NumberAmount() 162 { 163 Amount = 2 + rand() % 5; 164 } 165 //加左括号 随机选择在第几个数字前面加括号 166 void AddLbracket(){ 167 for (int j = 0; j < 2; j++) 168 LBraket[j] = 0; 169 if (Amount == 2) 170 { 171 BracketNum = 0; 172 } 173 if (Amount == 3){ 174 BracketNum = rand() % 2; 175 } 176 if (Amount > 3) 177 { 178 BracketNum = rand() % 3; 179 } 180 for (int i = 0; i < BracketNum; i++){ 181 LBraket[i] = 1 + rand() % (Amount-2); 182 } 183 } 184 //加右括号 185 void AddRbracket(){ 186 for (int j = 0; j < 2; j++) 187 RBraket[j] = 0; 188 int choose; 189 int trance; 190 if (BracketNum == 1){ 191 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 192 } 193 if (BracketNum == 2) 194 195 { 196 //把最左边的左括号放在第一个数组中 197 if (LBraket[0] < LBraket[1]) 198 { 199 trance = LBraket[0]; 200 LBraket[0] = LBraket[1]; 201 LBraket[1] = trance; 202 } 203 //当两个左括号之间相差有点远时有2中右括号添加方法 204 if (LBraket[0] - LBraket[1]>2){ 205 choose = rand() % 2; 206 if (choose == 0){ 207 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 208 RBraket[1] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 209 } 210 if (choose == 1) 211 { 212 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 213 RBraket[1] = LBraket[1] + 1 + rand() % (LBraket[0] - 2); 214 } 215 } 216 else 217 { 218 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 219 RBraket[1] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 220 if (LBraket[0] == LBraket[1] && RBraket[0] == RBraket[1]){ 221 LBraket[0] = LBraket[1] = 0; 222 RBraket[0] = RBraket[1] = 0; 223 BracketNum = 0; 224 225 } 226 if (LBraket[1] == 1 && (RBraket[0] == Amount || RBraket[1] == Amount)) 227 { 228 LBraket[0] = LBraket[1] = 0; 229 RBraket[0] = RBraket[1] = 0; 230 BracketNum = 0; 231 } 232 233 } 234 } 235 } 236 //随机产生最简真分数 237 void Score(){ 238 int Left, Right; 239 Left = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 240 Right = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 241 while (Left >= Right || Left==0) 242 { 243 Left = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 244 Right = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 245 } 246 int max=1; 247 //求最大公约数 248 for (int i = 2; i <= Left; i++) 249 { 250 if (Left%i == 0 && Right%i == 0) 251 { 252 max = i; 253 } 254 } 255 if (max > 1) 256 { 257 Left /= max; 258 Right /= max; 259 } 260 formula << '('<<Left << '/' << Right<<')'; 261 } 262 //随机生成操作符 263 void Operater() 264 { 265 int choose; 266 char op; 267 if (IsMulDlvExist == 1) 268 choose = 1 + rand() % 4; 269 else 270 choose = 1 + rand() % 2; 271 272 switch (choose) 273 { 274 case 1:{op = '+'; lastOp = '+'; break; } 275 case 2:{op = '-'; lastOp = '-'; break; } 276 case 3:{op = '*'; lastOp = '*'; break; } 277 case 4: 278 { 279 //防止连续除法产生运算误区 280 op = '/'; 281 if (lastOp == '/') 282 IsRep = 1; 283 else 284 lastOp = '/'; 285 break; 286 } 287 } 288 formula << op; 289 } 290 //随机生成整数 291 void Integer(){ 292 int num; 293 num = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 294 formula << num; 295 } 296 //创建算式 297 void CreateNumber(){ 298 for (int k = 1; k <= Amount; k++) 299 { 300 301 for (int i = 0; i < 2; i++){ 302 if (LBraket[i] == k) 303 formula << '('; 304 } 305 306 int cho; 307 cho = rand() % 2; 308 if (cho == 0) 309 { 310 Integer(); 311 } 312 else 313 Score(); 314 for (int j = 0; j < 2; j++){ 315 if ((RBraket[j] == k) && RBraket[j] != 0) 316 formula << ')'; 317 } 318 if (k == Amount) 319 formula << '='; 320 else 321 Operater(); 322 } 323 } 324 //检查是否重复及判断括号是否添加正确 325 int Repeat(int time){ 326 buffer[time] = formula.str(); 327 int juege=0; 328 int trance; 329 for (int i = 0; i < time; i++) 330 { 331 if (buffer[i] == buffer[time]) 332 { 333 juege = 1; 334 break; 335 } 336 } 337 if (IsBra != 1) 338 { 339 if (BracketNum == 1) 340 { 341 if (LBraket[0] == 1 && RBraket[0] == Amount) 342 juege = 1; 343 } 344 if (BracketNum == 2) 345 { 346 if (RBraket[0] < RBraket[1]) 347 { 348 trance = RBraket[0]; 349 RBraket[0] = RBraket[1]; 350 RBraket[1] = trance; 351 } 352 if (LBraket[1] == 1 && RBraket[0] == Amount&&LBraket[0] < RBraket[1]) 353 juege = 1; 354 } 355 } 356 return juege; 357 358 } 359 //利用栈计算结果 参考《数据结构---C语言》 360 float EvaluateExpression(){ 361 OperChar OPTR; 362 NumberLink OPND; 363 InitOperStack(OPTR); 364 PushOper(OPTR, '='); 365 InitNumStack(OPND); 366 int count = 0; 367 float Num = 0, first, second; 368 char oper1; 369 char bracket1; 370 while (true) 371 { 372 Num = 0; 373 //读取数字 374 while (formula.str()[count] >= '0'&&formula.str()[count] <= '9') 375 { 376 if (formula.str()[count] == '0') 377 { 378 if (count == 0) 379 PushNum(OPND, 0); 380 if (count != 0 && !(formula.str()[count - 1] >= '0'&&formula.str()[count - 1] <= '9')) 381 PushNum(OPND, 0); 382 } 383 384 Num = Num * 10; 385 Num = Num + formula.str()[count] - 48; 386 count++; 387 388 } 389 if (Num > 0) 390 { 391 PushNum(OPND, Num); 392 } 393 if (formula.str()[count] == '='&&GetTopOper(OPTR) == '=') 394 { 395 break; 396 } 397 //判断运算符优先级 398 switch (Precede(GetTopOper(OPTR), formula.str()[count])) 399 { 400 case '<': 401 { 402 PushOper(OPTR, formula.str()[count]); 403 count++; 404 break; 405 } 406 case '>': 407 { 408 PopOper(OPTR, oper1); 409 PopNum(OPND, second); 410 PopNum(OPND, first); 411 PushNum(OPND, Operate(first, oper1, second)); 412 break; 413 } 414 case '=': 415 { 416 PopOper(OPTR, bracket1); 417 count++; 418 } 419 } 420 } 421 return GetTopNum(OPND); 422 } 423 int main() 424 { 425 ofstream out("1.txt", ios::out); 426 int OutChoose = 0; 427 int truenum=0; 428 int choose; 429 bool flag=true; 430 int range=0; 431 srand((unsigned)time(NULL)); 432 /*cin >> IsMulDlvExist; 433 cin >> BaseNumber; 434 cin >> TopNumber; 435 cin >> IsNeg; 436 cin >> IsRem; 437 cin >> IsBra;*/ 438 cout << " 欢迎来到四则运算答题系统!" << endl; 439 cout << "说明: 初级只有加减法无括号无负数无余数(默认数值范围0-5) 中级有乘除有括号无负数无余数(默认范围0-20) 高级有乘除有括号有负数有余数(默认范围0-100)" << endl; 440 while (flag) 441 { 442 cout << "现在有初级,中级,高级,三种关卡,你要挑战哪一关?" << endl; 443 cout << "1.初级 2.中级 3.高级 请选择:"; 444 cin >> choose; 445 switch (choose) 446 { 447 case 1: 448 { 449 cout << "是否打印试卷?0、否 1、是 请选择 : "; 450 cin >> OutChoose; 451 cout << "是否需要数值重设范围?0、否 1、是 请选择 : "; 452 cin >> range; 453 IsMulDlvExist=0; 454 BaseNumber=0; 455 TopNumber=5; 456 if (range == 1){ 457 cout << "请输入下限(正数):"; 458 cin >> BaseNumber; 459 cout << "请输入上限(正数):"; 460 cin >> TopNumber; 461 } 462 IsNeg=1; 463 IsRem=1; 464 IsBra=1; 465 flag = false; 466 break; 467 } 468 case 2: 469 { 470 cout << "是否打印试卷?0、否 1、是 请选择 : "; 471 cin >> OutChoose; 472 cout << "是否需要数值重设范围?0、否 1、是 请选择 : "; 473 cin >> range; 474 IsMulDlvExist = 1; 475 BaseNumber = 0; 476 TopNumber = 20; 477 if (range == 1){ 478 cout << "请输入下限(正数):"; 479 cin >> BaseNumber; 480 cout << "请输入上限(正数):"; 481 cin >> TopNumber; 482 } 483 IsNeg = 1; 484 IsRem = 1; 485 IsBra = 0; 486 flag = false; 487 break; 488 } 489 case 3: 490 { 491 cout << "是否打印试卷?0、否 1、是 请选择 : "; 492 cin >> OutChoose; 493 cout << "是否需要数值重设范围?0、否 1、是 请选择 : "; 494 cin >> range; 495 IsMulDlvExist = 1; 496 BaseNumber = 0; 497 TopNumber = 100; 498 if (range == 1){ 499 cout << "请输入下限(正数):"; 500 cin >> BaseNumber; 501 cout << "请输入上限(正数):"; 502 cin >> TopNumber; 503 } 504 IsNeg = 0; 505 IsRem = 0; 506 IsBra = 0; 507 flag = false; 508 break; 509 } 510 default: 511 { 512 cout << "输入有误,请重新选择:" << endl; 513 flag = true; 514 break; 515 } 516 } 517 518 } 519 520 521 float sum=0; 522 for (int i = 0; i < 30; i++) 523 { 524 lastOp = '+'; 525 IsRep = 0; 526 NumberAmount(); 527 if (IsBra == 0) 528 { 529 AddLbracket(); 530 AddRbracket(); 531 } 532 CreateNumber(); 533 Result[i] = EvaluateExpression(); 534 while (Repeat(i) == 1 || IsRep == 1 || (IsNeg == 1 && (Result[i] < 0 || Result[i] == -0)) || (IsRem == 1 && (int(Result[i]*10000))%10000!=0)) 535 { 536 537 IsRep = 0; 538 lastOp = '+'; 539 formula.str(""); 540 NumberAmount(); 541 if (IsBra == 0) 542 { 543 AddLbracket(); 544 AddRbracket(); 545 } 546 CreateNumber(); 547 Result[i] = EvaluateExpression(); 548 } 549 cout << "第" << i + 1 << "题:" ; 550 cout << formula.str(); 551 552 cin >> sum; 553 if (OutChoose == 1) 554 { 555 out << "第" << i + 1 << "题:"; 556 out << formula.str() << sum; 557 } 558 if (abs(int(100 * sum) -int(100 * Result[i]))<=1) 559 { 560 cout << "小朋友太棒了,回答正确! "; 561 if (OutChoose==1) 562 out << "小朋友太棒了,回答正确! "; 563 truenum++; 564 } 565 else 566 { 567 cout << "回答错误,小朋友继续加油!正确答案:" << Result[i] << endl; 568 if (OutChoose == 1) 569 out << "回答错误,小朋友继续加油!正确答案:" << Result[i] << endl; 570 } 571 572 formula.str(""); 573 } 574 cout << endl; 575 cout << "你一共答对了" << truenum << "道题!" << endl; 576 if (OutChoose==1) 577 out << "你一共答对了" << truenum << "道题!" << endl; 578 return 0; 579 }
cpp转换后
MyHtml.html代码:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>首页</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 6 <meta name="keywords" content="keyword1,keyword2,keyword3"> 7 <meta name="description" content="this is my page"> 8 9 10 <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> 11 12 </head> 13 14 <body background="images/A1.jpg"> 15 <h1 align="center">四则运算</h1> 16 <!-- 传递参数的值给index.jsp处理 --> 17 <form action="index.jsp" method="post"> 18 19 <!-- 互斥选择,值只能有一个 --> 20 <center> 21 <br>请选择上限(分数无上下限): 22 <select name="TopNumber"> 23 <option value=20>20</option> 24 <option value=30>30</option> 25 <option value=50>50</option> 26 <option value=80>80</option> 27 <option value=100>100</option> 28 </select><br> 29 <br>请选择下限(分数无上下限): 30 <select name="BaseNumber"> 31 <option value=0>0</option> 32 <option value=1>1</option> 33 <option value=3>3</option> 34 <option value=5>5</option> 35 <option value=10>10</option> 36 </select><br> 37 <!-- 多项选择,值可以有多个,在jsp中用数组保存 --> 38 <br>请在以下选项中打勾: 39 <input type="checkbox" name="function" value=1>有乘除 40 <input type="checkbox" name="function" value=2>无余数 41 <input type="checkbox" name="function" value=3>有括号 42 <br> 43 <br> 44 45 <input type="submit" name="submit" value="确定"> 46 </center> 47 </form> 48 </body> 49 </html>
index.jsp文件代码:
1 <%@ page language="java" contentType="text/html; charset=utf-8" 2 3 pageEncoding="utf-8"%> 4 <%@ page import="test5.*"%> 5 <% 6 String path = request.getContextPath(); 7 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 8 %> 9 10 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 11 <html> 12 <head> 13 <base href="<%=basePath%>"> 14 15 <title>答题</title> 16 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 17 <meta http-equiv="pragma" content="no-cache"> 18 <meta http-equiv="cache-control" content="no-cache"> 19 <meta http-equiv="expires" content="0"> 20 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 21 <meta http-equiv="description" content="This is my page"> 22 <!-- 23 <link rel="stylesheet" type="text/css" href="styles.css"> 24 --> 25 </head> 26 27 <body background="images/A2.jpg"> 28 29 <% 30 String[] s=new String[30]; 31 float k[]=new float[30]; 32 Calculate a=new Calculate(); 33 34 request.setCharacterEncoding("UTF-8"); 35 String[] function = request.getParameterValues("function"); 36 String TopNumber,BaseNumber; 37 TopNumber=request.getParameter("TopNumber"); 38 BaseNumber=request.getParameter("BaseNumber"); 39 a.SetValue(a.StrToNum(TopNumber),a.StrToNum(BaseNumber)); 40 if(function!=null){ 41 for(int i=0;i<function.length;i++){ 42 if(function[i].equals("1")) 43 { 44 a.SetValue1(1); 45 } 46 if(function[i].equals("2")) 47 { 48 a.SetValue2(1); 49 } 50 if(function[i].equals("3")) 51 { 52 a.SetValue3(0); 53 } 54 } 55 } 56 57 58 %> 59 <form action="MyJsp.jsp" method="post"> 60 <center> 61 <% 62 a.main(); 63 float temp; 64 String[] se=new String[30]; 65 for(int i=0;i<30;i++){ 66 s[i]=a.cs(i); 67 se[i]="name"; 68 se[i]=se[i]+i; 69 k[i]=a.css(i); 70 out.print("<tr>"+s[i]+"</tr>"); 71 out.println("<br>"); 72 73 74 %> 75 <input type="text" name=<%=se[i] %>><br> 76 <% 77 } 78 session.setAttribute( "v1",s); 79 session.setAttribute( "v2",k); 80 %> 81 <br><input type="submit" name="submit" value="提交"> 82 83 <% 84 85 86 %> 87 </center> 88 </form> 89 90 91 92 93 </body> 94 </html>
MyJsp.jsp文件代码:
1 <%@ page language="java" import="java.util.*" pageEncoding="gb2312" contentType="text/html; charset=gb2312"%> 2 <%@ page import="test5.*"%> 3 <% 4 String path = request.getContextPath(); 5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 6 %> 7 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 9 <html> 10 <head> 11 <base href="<%=basePath%>"> 12 13 <title>结果</title> 14 15 <meta http-equiv="pragma" content="no-cache"> 16 <meta http-equiv="cache-control" content="no-cache"> 17 <meta http-equiv="expires" content="0"> 18 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 19 <meta http-equiv="description" content="This is my page"> 20 <!-- 21 <link rel="stylesheet" type="text/css" href="styles.css"> 22 --> 23 24 </head> 25 26 <body background="images/A3.jpg"> 27 <% request.setCharacterEncoding("UTF-8");%> 28 <center> 29 <% 30 31 String[] name=new String[30]; 32 String[] sum=new String[30]; 33 Calculate a=new Calculate(); 34 float sum1[]=new float[30]; 35 int right=0; 36 String[] s= (String[])session.getAttribute("v1"); 37 float[] k=(float[])session.getAttribute("v2"); 38 39 for(int i=0;i<30;i++) 40 sum1[i]=0; 41 for(int i=0;i<30;i++){ 42 name[i]="name"; 43 name[i]=name[i]+i; 44 45 sum[i]=request.getParameter(name[i]); 46 //sum[i]=request.getParameterValues(name[i])"; 47 out.print(s[i]); 48 out.print("<tr>"+sum[i]+"</tr>"); 49 if(sum[i]=="") 50 out.print("未回答!"); 51 else{ 52 if(((int)(k[i]*100))%100!=0) 53 sum1[i]=a.StrToFloat1(sum[i]); 54 else 55 sum1[i]=a.StrToFloat(sum[i]); 56 if(Math.abs(sum1[i]*100-k[i]*100)<4){ 57 out.print(" 回答正确!"); 58 right++; 59 } 60 else 61 out.print(" 回答错误,正确答案是: "+k[i]); 62 } 63 64 out.println("<br>"); 65 } 66 out.print("总共做对 "+right+" 题,正确率为:"+(right/30.0)*100+" %"); 67 %><br> 68 <input type="button" value="返回首页" onClick="window.location.href='MyHtml.html'"> 69 <input type="button" value="关闭" onClick="window.close();"> 70 </center> 71 </body> 72 </html>
Calculate.java文件代码:
package test5; import java.util.*; public class Calculate { static int MAX=100; static String formula = ""; //当前算式 static String[] buffer = new String[MAX]; //缓冲区数组 static int TopNumber; //上限 static int BaseNumber; //下限 static int IsMulDlvExist; //是否有乘除 static int Amount; //操作数的个数 static int BracketNum; //括号个数 static int[] LBraket = new int[2]; //左括号的位置 static int[] RBraket = new int[2]; //右括号的位置 static int IsNeg; //是否有负数 static int IsRem; //是否有余数 static int IsBra; //是否有括号 static int IsRep; //是否重复 static float[] Result= new float[MAX]; //正确结果数组 static char lastOp; //记录上个运算符是否为除号 //优先级数组 static char[][] prior = { { '>', '>', '<', '<', '<', '>', '>' }, { '>', '>', '<', '<', '<', '>', '>' }, { '>', '>', '>', '>', '<', '>', '>' }, { '>', '>', '>', '>', '<', '>', '>' }, { '<', '<', '<', '<', '<', '=', ' ' }, { '>', '>', '>', '>', ' ', '>', '>' }, { '<', '<', '<', '<', '<', ' ', '=' } }; //将操作符转化为优先级数组的下标 static int Change(String Oper) { switch (Oper.charAt(0)) { case '+': return 0; case '-': return 1; case '*': return 2; case '/': return 3; case '(': return 4; case ')': return 5; case '=': return 6; default: return 6; } } static int Change(char Oper) { switch (Oper) { case '+': return 0; case '-': return 1; case '*': return 2; case '/': return 3; case '(': return 4; case ')': return 5; case '=': return 6; default: return 6; } } static //返回优先级的大小 char Precede(char Oper, char ch) { return prior[Change(Oper)][Change(ch)]; } //计算两个数的结果 static float Operate(float first, char oper1, float second) { switch (oper1) { case '+': { return (first + second); } case '-': { if (first-second<0) { IsRep = 1; return 0; } return (first - second); } case '*': { return (first * second); } case '/': { if (second == 0) { IsRep = 1; return 0; } return (first / second); } default: return 0; } } //数字的个数 static void NumberAmount() { Amount = 2 + (int)((Math.random())*3); } //加左括号 随机选择在第几个数字前面加括号 static void AddLbracket(){ for (int j = 0; j < 2; j++) LBraket[j] = 0; if (Amount == 2) { BracketNum = 0; } if (Amount == 3){ BracketNum = (int)((Math.random())*2); } if (Amount > 3) { BracketNum = (int)((Math.random())*3); } for (int i = 0; i < BracketNum; i++){ LBraket[i] = 1 + (int)((Math.random())*(Amount - 2)); } } //加右括号 static void AddRbracket(){ for (int j = 0; j < 2; j++) RBraket[j] = 0; int choose; int trance; if (BracketNum == 1){ RBraket[0] = LBraket[0] + 1 +(int)((Math.random())* (Amount - LBraket[0])); } if (BracketNum == 2) { //把最左边的左括号放在第一个数组中 if (LBraket[0] < LBraket[1]) { trance = LBraket[0]; LBraket[0] = LBraket[1]; LBraket[1] = trance; } //当两个左括号之间相差有点远时有2中右括号添加方法 if (LBraket[0] - LBraket[1]>2){ choose = (int)((Math.random())*2); if (choose == 0){ RBraket[0] = LBraket[0] + 1 + (int)((Math.random())*(Amount - LBraket[0])); RBraket[1] = LBraket[0] + 1 + (int)((Math.random())*(Amount - LBraket[0])); } if (choose == 1) { RBraket[0] = LBraket[0] + 1 + (int)((Math.random())*(Amount - LBraket[0])); RBraket[1] = LBraket[1] + 1 + (int)((Math.random())*(LBraket[0] - 2)); } } else { RBraket[0] = LBraket[0] + 1 + (int)((Math.random())*(Amount - LBraket[0])); RBraket[1] = LBraket[0] + 1 + (int)((Math.random())*(Amount - LBraket[0])); if (LBraket[0] == LBraket[1] && RBraket[0] == RBraket[1]){ LBraket[0] = LBraket[1] = 0; RBraket[0] = RBraket[1] = 0; BracketNum = 0; } if (LBraket[1] == 1 && (RBraket[0] == Amount || RBraket[1] == Amount)) { LBraket[0] = LBraket[1] = 0; RBraket[0] = RBraket[1] = 0; BracketNum = 0; } } } } //随机产生最简真分数 static void Score(){ int Left, Right; Left = BaseNumber + (int)((Math.random())*(TopNumber - BaseNumber + 1)); Right = BaseNumber + (int)((Math.random())*(TopNumber - BaseNumber + 1)); while (Left >= Right || Left == 0) { Left = BaseNumber + (int)((Math.random())*(TopNumber - BaseNumber + 1)); Right = BaseNumber + (int)((Math.random())*(TopNumber - BaseNumber + 1)); } int max = 1; //求最大公约数 for (int i = 2; i <= Left; i++) { if (Left%i == 0 && Right%i == 0) { max = i; } } if (max > 1) { Left /= max; Right /= max; } formula += "(" + Left + "/" + Right + ")"; } //随机生成操作符 static void Operater() { int choose; char op='+'; if (IsMulDlvExist == 1) choose = 1 + (int)((Math.random())* 4); else choose = 1 + (int)((Math.random())*2); switch (choose) { case 1:{op = '+'; lastOp = '+'; break; } case 2:{op = '-'; lastOp = '-'; break; } case 3:{op = '*'; lastOp = '*'; break; } case 4: { //防止连续除法产生运算误区 op = '/'; if (lastOp == '/') IsRep = 1; else lastOp = '/'; break; } } formula += op; } //随机生成整数 static void Integer(){ int num; num = BaseNumber + (int)((Math.random())*(TopNumber - BaseNumber + 1)); formula += num; } //创建算式 static void CreateNumber(){ for (int k = 1; k <= Amount; k++) { for (int i = 0; i < 2; i++){ if (LBraket[i] == k) formula += "("; } int cho; cho = (int)((Math.random())*2); if (cho == 0) { Integer(); } else Score(); for (int j = 0; j < 2; j++){ if ((RBraket[j] == k) && RBraket[j] != 0) formula += ")"; } if (k == Amount) formula += "="; else Operater(); } } //检查是否重复及判断括号是否添加正确 static int Repeat(int time){ buffer[time] = formula; int juege = 0; int trance; for (int i = 0; i < time; i++) { if (buffer[i] == buffer[time]) { juege = 1; break; } } if (IsBra != 1) { if (BracketNum == 1) { if (LBraket[0] == 1 && RBraket[0] == Amount) juege = 1; } if (BracketNum == 2) { if (RBraket[0] < RBraket[1]) { trance = RBraket[0]; RBraket[0] = RBraket[1]; RBraket[1] = trance; } if (LBraket[1] == 1 && RBraket[0] == Amount&&LBraket[0] < RBraket[1]) juege = 1; } } return juege; } static float EvaluateExpression(){ //Stack OPTR=new Stack(); //Stack OPND=new Stack(); float[] OPND=new float[MAX]; char[] OPTR =new char[MAX]; int Ntop=0; int Ctop=0; //InitOperStack(OPTR); //OPTR.push("="); OPTR[Ctop++]='='; //PushOper(OPTR, '='); //InitNumStack(OPND); int count = 0; float Num = 0, first, second; char oper1; char bracket1; while (true) { Num = 0; //读取数字 while (formula.charAt(count) >= '0'&&formula.charAt(count) <= '9') { if (formula.charAt(count) == '0') { if (count == 0) //OPND.push(new Float(0)); OPND[Ntop++]=0; if (count != 0 && !(formula.charAt(count-1) >= '0'&&formula.charAt(count-1) <= '9')) //OPND.push(new Float(0)); OPND[Ntop++]=0; } Num = Num * 10; Num = Num + formula.charAt(count) - 48; count++; } if (Num > 0) { //OPND.push(new Float(Num)); //PushNum(OPND, Num); OPND[Ntop++]=Num; } if (formula.charAt(count) == '='&&OPTR[Ctop-1] == '=') { break; } //判断运算符优先级 switch (Precede(OPTR[Ctop-1], formula.charAt(count))) { case '<': { //OPTR.push(formula.charAt(count)); OPTR[Ctop++]=formula.charAt(count); //PushOper(OPTR, formula.str()[count]); count++; break; } case '>': { //PopOper(OPTR, oper1); //oper1=(char) OPTR.pop(); oper1=OPTR[--Ctop]; //PopNum(OPND, second); //second=(float) OPND.pop(); second=OPND[--Ntop]; //PopNum(OPND, first); //first=(float)OPND.pop(); first=OPND[--Ntop]; //PushNum(OPND, Operate(first, oper1, second)); //OPND.push(Operate(first, oper1, second)); OPND[Ntop++]=Operate(first, oper1, second); break; } case '=': { //PopOper(OPTR, bracket1); //bracket1=(char) OPTR.pop(); bracket1=OPTR[--Ctop]; count++; } } } return OPND[Ntop-1]; } public static void SetValue(int IsMulDlvExist1,int IsRem1,int IsBra1,int TopNumber1,int BaseNumber1) { IsMulDlvExist=0; BaseNumber=0; TopNumber=10; IsNeg=0; IsRem=0; IsBra=1; IsMulDlvExist=IsMulDlvExist1; TopNumber=TopNumber1; BaseNumber=BaseNumber1; IsRem=IsRem1; IsBra=IsBra1; } public static void SetValue1(int IMDE) { IsMulDlvExist=IMDE; } public static void SetValue2(int Rem) { IsRem=Rem; } public static void SetValue3(int Bra) { IsBra=Bra; } public static void SetValue(int TopNumber1,int BaseNumber1){ IsMulDlvExist=0; BaseNumber=0; TopNumber=10; IsNeg=0; IsRem=0; IsBra=1; TopNumber=TopNumber1; BaseNumber=BaseNumber1; } public static int StrToNum(String x) { int num=0; for(int i=0;i<x.length();i++) { num=num*10+x.charAt(i)-48; } return num; } public static float StrToFloat(String x) { float num=0; int doat=0; int mi=-1; for(int i=0;i<x.length();i++) { if(x.charAt(i)=='.') { doat=1; continue; } if(doat==1) { num=(float) (num+(x.charAt(i)-48)*Math.pow(10,mi)); mi--; }else{ num=num*10+x.charAt(i)-48; } } return num; } public static float StrToFloat1(String x) { float a=0; float first=0; float second=0; int point=0; int has=0; for(int i=0;i<x.length();i++) { if(x.charAt(i)=='/') { has=1; } } if(has==1) { for(int i=0;i<x.length();i++) { if(x.charAt(i)=='/') { point=1; continue; } if(point==1) { second=second*10+x.charAt(i)-48; }else { first=first*10+x.charAt(i)-48; } } return (first/second); } else { a=StrToFloat(x); return a; } } static int ma() { int OutChoose = 0; int truenum = 0; int choose; boolean flag = true; int range = 0; //IsMulDlvExist=1; //BaseNumber=0; //TopNumber=10; //IsNeg=0; //IsRem=0; //IsBra=0; /*cout << " 欢迎来到四则运算答题系统!" << endl; cout << "说明: 初级只有加减法无括号无负数无余数(默认数值范围0-5) 中级有乘除有括号无负数无余数(默认范围0-20) 高级有乘除有括号有负数有余数(默认范围0-100)" << endl; while (flag) { cout << "现在有初级,中级,高级,三种关卡,你要挑战哪一关?" << endl; cout << "1.初级 2.中级 3.高级 请选择:"; cin >> choose; switch (choose) { case 1: { cout << "是否打印试卷?0、否 1、是 请选择 : "; cin >> OutChoose; cout << "是否需要数值重设范围?0、否 1、是 请选择 : "; cin >> range; IsMulDlvExist = 0; BaseNumber = 0; TopNumber = 5; if (range == 1){ cout << "请输入下限(正数):"; cin >> BaseNumber; cout << "请输入上限(正数):"; cin >> TopNumber; } IsNeg = 1; IsRem = 1; IsBra = 1; flag = false; break; } case 2: { cout << "是否打印试卷?0、否 1、是 请选择 : "; cin >> OutChoose; cout << "是否需要数值重设范围?0、否 1、是 请选择 : "; cin >> range; IsMulDlvExist = 1; BaseNumber = 0; TopNumber = 20; if (range == 1){ cout << "请输入下限(正数):"; cin >> BaseNumber; cout << "请输入上限(正数):"; cin >> TopNumber; } IsNeg = 1; IsRem = 1; IsBra = 0; flag = false; break; } case 3: { cout << "是否打印试卷?0、否 1、是 请选择 : "; cin >> OutChoose; cout << "是否需要数值重设范围?0、否 1、是 请选择 : "; cin >> range; IsMulDlvExist = 1; BaseNumber = 0; TopNumber = 100; if (range == 1){ cout << "请输入下限(正数):"; cin >> BaseNumber; cout << "请输入上限(正数):"; cin >> TopNumber; } IsNeg = 0; IsRem = 0; IsBra = 0; flag = false; break; } default: { cout << "输入有误,请重新选择:" << endl; flag = true; break; } } } */ //float sum = 0; for (int i = 0; i < 30; i++) { lastOp = '+'; IsRep = 0; NumberAmount(); if (IsBra == 0) { AddLbracket(); AddRbracket(); } CreateNumber(); Result[i] = EvaluateExpression(); while (Repeat(i) == 1 || IsRep == 1 || (IsNeg == 1 && (Result[i] < 0 || Result[i] == -0)) || (IsRem == 1 && ((int)(Result[i]*10000))%10000!=0)) { IsRep = 0; lastOp = '+'; formula=""; NumberAmount(); if (IsBra == 0) { AddLbracket(); AddRbracket(); } CreateNumber(); Result[i] = EvaluateExpression(); } buffer[i]=formula; formula=""; } return 0; } public static float css(int number){ return Result[number]; } public static String cs(int number){ return buffer[number]; } public static void main() { int a; a=ma(); for (int i = 0; i < 30; i++) { System.out.println(buffer[i]+Result[i]); } } }
结果展示:
总结:这一次作业因为有原先的程序,所以在具体实现代码基本是原样照搬,我感觉这一次主要考验我们的是java web的编写能力,我又再一次对java做了温习。
项目计划总结:
时间记录日志:
缺陷记录日志: