(已改编为网页版)
程序设计思想:
创建表达式类Expression、运算数类RationalNumber、表达式随机生成器类ExpressionRandom、表达式组成元素类Element
每个Element由一个运算数(RationalNumber) + 一个运算符(String)构成
对每一个表达式,按照以下规则将其拆分:
如表达式“2+3-4/7
一个运算数+一个运算符作为一个元素(Element,详见Element.java),如即2+、3-
每个表达式为2个或三个Element构成的列表(List),最后一个元素(Element)没有跟着的运算符,补充"#"即表达式“2+3-4/7”由一个列表{2+、3-、4/7#}表示。
源程序代码:
RationalNumber.java
1 /*******运算数类*******/ 2 3 package model; 4 public class RationalNumber { 5 private int denominator; //分母 6 private int numerator; //分子 7 8 /***构造函数,整数看做分母为1的分数***/ 9 public RationalNumber(int numerator) { 10 this.numerator = numerator; 11 denominator = 1; 12 } 13 /****构造函数,第一个参数为分子,第二个为分母****/ 14 public RationalNumber(int numerator,int denominator) { 15 this.denominator = denominator; 16 this.numerator = numerator; 17 } 18 public int getDenominator() { 19 return denominator; 20 } 21 public void setDenominator(int denominator) { 22 this.denominator = denominator; 23 } 24 public int getNumerator() { 25 return numerator; 26 } 27 public void setNumerator(int numerator) { 28 this.numerator = numerator; 29 } 30 31 /***判断两个分数是否相等***/ 32 @Override 33 public boolean equals(Object obj) { 34 // TODO Auto-generated method stub 35 RationalNumber rn = (RationalNumber)obj; 36 if(this.denominator == rn.denominator && this.numerator == rn.numerator) { 37 return true; 38 }else return false; 39 } 40 41 /*****分数相加*****/ 42 public RationalNumber plus(RationalNumber rb) { 43 int addNum1 = this.numerator * rb.denominator; 44 int addNum2 = rb.numerator * this.denominator; 45 int demo = this.denominator * rb.denominator; 46 RationalNumber value = new RationalNumber(addNum1 + addNum2,demo); 47 value.simply(); 48 return value; 49 } 50 51 /*****分数相减*****/ 52 public RationalNumber minus(RationalNumber rb) { 53 int addNum1 = this.numerator * rb.denominator; 54 int addNum2 = rb.numerator * this.denominator; 55 int demo = this.denominator * rb.denominator; 56 RationalNumber value = new RationalNumber(addNum1 - addNum2,demo); 57 value.simply(); 58 return value; 59 } 60 61 /*****分数相乘*****/ 62 public RationalNumber multiply(RationalNumber rb) { 63 RationalNumber value = new RationalNumber(this.numerator * rb.numerator,this.denominator * rb.denominator); 64 value.simply(); 65 return value; 66 } 67 68 /*****分数相除*****/ 69 public RationalNumber divide(RationalNumber rb) { 70 RationalNumber value = new RationalNumber(this.numerator * rb.denominator,this.denominator * rb.numerator); 71 value.simply(); 72 return value; 73 } 74 75 /*****分数化简*****/ 76 public void simply() { 77 if(numerator == 0) { 78 denominator = 1; 79 return ; 80 } 81 82 int small,big,temp; 83 if(numerator > denominator) { 84 small = denominator; 85 big = numerator; 86 }else { 87 big = denominator; 88 small = numerator; 89 } 90 while(small != 0) { 91 temp = big % small; 92 big = small; 93 small = temp; 94 } 95 numerator /= big; 96 denominator /= big; 97 } 98 99 /****取得字符串****/ 100 @Override 101 public String toString() { 102 if(denominator == 1) 103 return String.valueOf(numerator); 104 else return String.valueOf(numerator + "/" + denominator); 105 } 106 107 /****取得Html格式字符串****/ 108 public String toHtmlDiv() { 109 String str = null; 110 if(denominator == 1) 111 str = "<div class='nomal'>" + this.numerator + "</div>"; 112 else 113 str = "<div class='fraction'><div>" + this.numerator + "</div><div style='border-top:2px solid black;'>" + this.denominator + "</div></div>"; 114 return str; 115 } 116 }
1 /**每个Element由一个运算数(RationalNumber) + 一个运算符(String)构成: 2 * 具体代码如下: 3 */ 4 5 package model; 6 7 public class Element{ 8 9 RationalNumber fraction; //运算数 10 String operator; //运算符 11 //构造方法 12 public Element(RationalNumber fraction, String operator) { 13 this.fraction = fraction; 14 this.operator = operator; 15 } 16 //运算数的get/set方法 17 public RationalNumber getFraction() { 18 return fraction; 19 } 20 public void setFraction(RationalNumber fraction) { 21 this.fraction = fraction; 22 } 23 //运算符的get/set方法 24 public String getOperator() { 25 return operator; 26 } 27 public void setOperator(String operator) { 28 this.operator = operator; 29 } 30 //重载equals方法,判读两个元素是否相同 31 @Override 32 public boolean equals(Object obj) { 33 Element element = (Element)obj; 34 if(this.fraction.equals(element) && this.operator.equals(element.operator)) 35 return true; 36 else return false; 37 } 38 39 40 }
Expression.java
1 /**对每一个表达式,按照以下规则将其拆分: 2 * 如表达式“2+3-4/7” 3 * 一个运算数+一个运算符作为一个元素(Element,详见Element.java),如即2+、3- 4 * 每个表达式为2个或三个Element构成的列表(List), 5 * 最后一个元素(Element)没有跟着的运算符,补充"#" 6 * 7 * 即表达式“2+3-4/7”由一个列表{2+、3-、4/7#}表示。 8 */ 9 10 package model; 11 12 import java.util.List; 13 14 public class Expression { 15 private List<Element> expr; //Element构成的列表,表示一个表达式 16 17 public Expression(List<Element> expr) { //构造方法,参数为List<Element>类型 18 this.expr = expr; 19 } 20 21 //表达式列表的get/set方法 22 public List<Element> getExpr() { 23 return expr; 24 } 25 26 public void setExpr(List<Element> expr) { 27 this.expr = expr; 28 } 29 30 //得到表达式字符串,如"1+2/4/7" 31 @Override 32 public String toString() { 33 String exprStr = new String(); 34 for(Element e:expr) { 35 exprStr += e.getFraction().toString(); 36 if(!e.getOperator().equals("#")) 37 exprStr += e.getOperator(); 38 } 39 return exprStr; 40 } 41 42 /****取得Html格式字符串 43 * 如"<div class='nomal'>7</div><div class='nomal'>×</div><div class='nomal'>1</div><div class='nomal'>+</div><div class='nomal'>86</div><div class="nomal">=</div>" 44 * 在html中直接加入toHtmlDiv()生成的字符串,可规范显示该表达式 45 */ 46 public String toHtmlDiv() { 47 String exprStr = new String(); 48 for(Element e:expr) { //将每个元素转为html格式div,详见Element.java 49 exprStr += e.getFraction().toHtmlDiv(); 50 if(!e.getOperator().equals("#")) 51 { 52 //存运算符时以"*、/"表示乘除运算符,此处转换为"×、÷" 53 if(e.getOperator().equals("*")) 54 exprStr += "<div class='nomal'>×</div>"; 55 else if(e.getOperator().equals("/")) 56 exprStr += "<div class='nomal'>÷</div>"; 57 else 58 exprStr += "<div class='nomal'>"+ e.getOperator() + "</div>"; 59 } 60 } 61 exprStr += "<div class="nomal">=</div>"; 62 System.out.println(exprStr); 63 return exprStr; 64 } 65 66 /****两个算数表达式是否相同****/ 67 @Override 68 public boolean equals(Object obj) { 69 Expression expr = (Expression)obj; 70 if(this.expr.size() != expr.expr.size()) 71 return false; 72 for(int i = 0;i < this.expr.size();i++) 73 { 74 if(!this.expr.get(i).equals(expr.expr.get(i))) 75 return false; 76 } 77 return true; 78 } 79 80 /****计算结果,表达式不合法时,返回null****/ 81 public RationalNumber getResult() { 82 RationalNumber rn = null; //结果 83 int length = this.getExpr().size(); //运算数个数 84 String op1 = this.getExpr().get(0).operator,op2; //第1、2个运算符 85 if(length == 2) //二元运算 86 rn = calc(this.getExpr().get(0).fraction,op1,this.getExpr().get(1).fraction); 87 else { 88 op2 = this.getExpr().get(1).operator; 89 RationalNumber rn_temp; //中间数 90 //运算符优先级判断 91 if((op1.equals("+") || op1.equals("-"))&&(op2.equals("*")||op2.equals("/"))){ 92 rn_temp = calc(this.getExpr().get(1).fraction,op2,this.getExpr().get(2).fraction); 93 if(rn_temp == null)return null; 94 //if(rn_temp == null || rn_temp.getDenominator() > 100 || rn_temp.getNumerator() > 100 || rn_temp.getDenominator() < 0 || rn_temp.getNumerator() < 0 || rn_temp.getDenominator() == 0|| (rn_temp.getDenominator() != 1 && rn_temp.getNumerator() >= rn_temp.getDenominator())) return null; 95 rn = calc(this.getExpr().get(0).fraction,op1,rn_temp); 96 }else { 97 rn = calc(this.getExpr().get(0).fraction,op1,this.getExpr().get(1).fraction); 98 if(rn == null)return null; 99 rn = calc(rn,op2,this.getExpr().get(2).fraction); 100 } 101 } 102 103 if(rn == null || rn.getDenominator() > 100 || rn.getNumerator() > 100 || rn.getDenominator() < 0 || rn.getNumerator() < 0 || rn.getDenominator() == 0|| (rn.getDenominator() != 1 && rn.getNumerator() >= rn.getDenominator())) 104 return null; 105 else 106 return rn; 107 } 108 109 /****根据单个运算符计算单个结果***/ 110 private RationalNumber calc(RationalNumber rn1,String o,RationalNumber rn2) { 111 RationalNumber rn = null; 112 if(rn1.getDenominator() > 100 || rn1.getNumerator() > 100 || rn1.getDenominator() < 0 || rn1.getNumerator() < 0 || rn1.getDenominator() == 0|| (rn1.getDenominator() != 1 && rn1.getNumerator() >= rn1.getDenominator()) || rn2.getDenominator() > 100 || rn2.getNumerator() > 100 || rn2.getDenominator() < 0 || rn2.getNumerator() < 0 || rn2.getDenominator() == 0 || (rn2.getDenominator() != 1 && rn2.getNumerator() >= rn2.getDenominator())){ 113 rn = null; 114 }else { 115 if(o.equals("+")) 116 rn = rn1.plus(rn2); 117 else if(o.equals("-")) 118 rn = rn1.minus(rn2); 119 else if(o.equals("*")) 120 rn = rn1.multiply(rn2); 121 else if(o.equals("/")) 122 { 123 if(rn2.getNumerator() != 0) 124 rn = rn1.divide(rn2); 125 else return null; 126 } 127 } 128 return rn; 129 } 130 }
ExpressionRandom.java
1 /******题目(也称为运算表达式)随机生成器*****/ 2 3 package model; 4 5 import java.util.ArrayList; 6 import java.util.List; 7 8 public class ExpressionRandom { 9 /***定义运算符****/ 10 private static String[] operator = {"+","-","*","/"}; 11 12 /****随机得到一个表达式,elementNum为元素个数,isFraction表示是否支持分数计算*****/ 13 public static Expression getExpression(int elementNum,boolean isFraction) { 14 /***表达式列表***/ 15 List<Element> expr = new ArrayList<Element>(); 16 int i,nume,demo; //循环变量,分子,分母 17 /***随机生成elementNum个Element(随机分数 + 运算符),并添加到expr***/ 18 for(i = 0;i < elementNum;i++) { 19 nume = (int) (Math.random() * 101); 20 if(isFraction) 21 demo = (int) (Math.random() * 100 + 1); //分母不能为0 22 else demo = 1; 23 String oper = operator[(int)(Math.random() * 4)]; 24 RationalNumber rb = new RationalNumber(nume,demo); 25 rb.simply(); 26 expr.add(new Element(rb,oper)); 27 } 28 expr.get(i-1).setOperator("#"); 29 /****通过expr构造运算表达式,并返回****/ 30 return new Expression(expr); 31 } 32 33 /****得到经过过滤的表达式*****/ 34 public static Expression getValidExpression(int elementNum,boolean isFraction) { 35 Expression expr = null; 36 do { 37 expr = getExpression(elementNum,isFraction); 38 }while(expr.getResult() == null); //(当表达式不合法时,返回计算结果为null) 39 return expr; 40 } 41 42 /******测试主函数********/ 43 public static void main(String[] args) { 44 for(int i = 0;i < 100;) { 45 Expression expr = ExpressionRandom.getExpression(2, true); 46 if(expr.getResult() != null) { 47 System.out.println(expr.toString() + "=" + expr.getResult() + " "); 48 i++; 49 } 50 } 51 } 52 }
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" href="css/style.css"/> <title>小学生四则运算</title> </head> <body> <img alt="asdfsadf" src="img/pdf.png"> <form action="arithmetic.jsp" class="option"> <center><h2>题目定制</h2></center> <p>请选择题目类型: <select name="elementNum"> <option>2</option> <option>3</option> </select>元运算<br /></p> 题目数量: <input name="count" value="10" type="radio" />10 <input name="count" value="20" type="radio" />20 <input name="count" value="30" type="radio" />30 <input name="count" value="40" type="radio" />40 <input name="count" value="50" type="radio" />50 <input name="count" value="60" type="radio" />60<br/> <input name="count" value="1000000" type="radio" />10000000(极限测试,慎选!!) <br /><br /> <input type="checkbox" name="fraction" /><label>分数计算</label> <br /> <button class="submit" style="margin-top:50px">开始答题!</button> </form> </body> </html>
arithmetic.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@page import="model.*" 4 import="java.util.List" 5 import="java.util.ArrayList"%> 6 <%ExpressionRandom exprRand = new ExpressionRandom(); %> 7 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 8 <html> 9 <head> 10 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 11 <title>小学生算数</title> 12 <link rel="stylesheet" type="text/css" href="css/style.css"/> 13 <script type="text/javascript" src="js/jquery-2.1.0.js" ></script> 14 <script type="text/javascript" src="js/demo.js" ></script> 15 </head> 16 <body> 17 18 <% 19 //题目数量 20 String str = request.getParameter("count"); 21 22 int count = 0; //题目数量 23 int elementNum = 0; //运算数个数 24 boolean isFraction = false; //分数计算 25 List<Expression> exprs = new ArrayList<Expression>(); //题目 26 if(str != null){ //判断是由用户定制题目页面跳转至该页面 27 count = Integer.parseInt(str); 28 elementNum = Integer.parseInt(request.getParameter("elementNum")); 29 isFraction = (request.getParameter("fraction") != null); 30 for(int i = 0;i < count;i++){ 31 exprs.add(ExpressionRandom.getValidExpression(elementNum, isFraction)); 32 //out.println(exprs.get(i).toString()); 33 } 34 session.setAttribute("exprs", exprs); 35 }else{ 36 37 } 38 %> 39 <form action="result.jsp"> 40 <table class="box" align="center" border="0" cellspacing="10" cellpadding="10"> 41 <%for(int i = 0;i < count;i+=2){%> 42 <tr> 43 <td align="center" class='expr'> 44 <%=exprs.get(i).toHtmlDiv()%> 45 </td> 46 <td><input autocomplete="off" value="" class="result" name="result" type="text"/></td> 47 <td align="center" class='expr'> 48 <%=exprs.get(i + 1).toHtmlDiv()%> 49 </td> 50 <td><input autocomplete="off" value="" class="result" name="result" type="text"/></td> 51 </tr> 52 <%} %> 53 <tr> 54 <td colspan="4" align="center"><button class="submit">提交</button></td> 55 </tr> 56 </table> 57 <input name="time" class="timer" type="text" /> 58 </form> 59 </body> 60 </html>
result.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@page import="model.*" 4 import="java.util.List" 5 import="java.util.ArrayList"%> 6 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 7 <html> 8 <head> 9 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 10 <title>结果</title> 11 <link rel="stylesheet" type="text/css" href="css/style.css"/> 12 </head> 13 <body> 14 <% List<Expression> exprs =(List<Expression>) session.getAttribute("exprs"); //题目 15 String[] result = request.getParameterValues("result"); //用户答案 16 int right = 0,i = 0; 17 for(String re:result){ 18 re = re.trim(); //去除两端空格 19 if(re.equals(exprs.get(i).getResult().toString())) 20 right++; 21 i++; 22 } 23 /*for(i = 0;i < exprs.size();i++){ 24 System.out.println(result[i]+"-------"+exprs.get(i).getResult()); 25 if(result[i].equals(exprs.get(i).getResult())) 26 right++; 27 i++; 28 }*/ 29 30 %> 31 <table class="box" align="center" border="0" cellspacing="10" cellpadding="10"> 32 <tr> 33 <td colspan="6">你共答对了<%=right %>道题,答错<%=exprs.size()-right %>道题,得分:<%=(double)right/exprs.size() * 100 %>,用时:<%=request.getParameter("time") %></td> 34 </tr> 35 <%for(i = 0;i < exprs.size();i+=2){%> 36 <tr> 37 <td align="center" class='expr'> 38 <%=exprs.get(i).toHtmlDiv()%> 39 </td> 40 <td><input disabled="disabled" value="<%=result[i] %>" class="result" name="result" type="text"/></td> 41 <% 42 if(exprs.get(i).getResult().toString().equals(result[i])){ 43 %> 44 <td>√</td> 45 <% 46 }else{ 47 %> 48 <td>× 正确答案:<%=exprs.get(i).getResult() %></td> 49 <% 50 } 51 %> 52 <td align="center" class='expr'> 53 <%=exprs.get(i + 1).toHtmlDiv()%> 54 </td> 55 <td><input disabled="disabled" value="<%=result[i+1] %>" class="result" name="result" type="text"/></td> 56 <% 57 if(exprs.get(i + 1).getResult().toString().equals(result[i + 1])){ 58 %> 59 <td>√</td> 60 <% 61 }else{ 62 %> 63 <td>× 正确答案:<%=exprs.get(i + 1).getResult() %></td> 64 <% 65 } 66 %> 67 </tr> 68 <%} %> 69 <tr> 70 <td colspan="6" align="center"><button class="submit" onClick="history.go(-1)">返回</button></td> 71 </tr> 72 </table> 73 </body> 74 </html>
运行结果截图:
上课未按时完成的原因:未能迅速理清思路。