软件工程结对作业01
实验要求:
结对开发: 陶雨洁,李慧
一、设计思想
此实验是在JAVA版且连接SQL Server数据库的四则运算上改成网页版的四则运算。
1.首先呢,我们得先建立数据库shiTiKu和数据表shiTiKu02,定义好列。
2.首先可以先设置一个登陆界面jsp,暂时我们先设置一个用户(用户名和密码均为123),用JavaScript来判断输入是否有误。
3.当用户名和密码输入正确后,即进入题目设置界面。此处设置几个参数(包括:题目数量,取值范围,是否由乘除,是否有加减,是否包含括号),进而传递至下一个页面。
4.然后再连接数据库,利用已经写好的java bean,输出题目,然后等用户输入答案之后,用session来传递题目和用户的答案等其他信息至下一个页面。
5.判定题目正确与否,用session得到上一个页面传递而来的题目和用户输入的答案,插入至数据库中,然后判断用户输入的答案是否与正确答案一致。
6.一致时,输出表示√的图片;不一致时,输出×的图片,并输出正确答案。
7.浏览历史错题,即可对数据表中插入一个mask列,值=0,表示√;值=1,表示×。用sql语句,在数据库中查询mask=1,即输出错题。
如果当一个用户变成多个用户,也是这个道理,也是在数据表中加一个user列,用sql语句,在数据库中查询即可。
二、源程序代码
java bean类
package shiti; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; //�������ݿ��װ�࣬ /* * ��̬�����л�����ݿ�����ӡ��ر����ݿ� */ public class DBUtil { private static final String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver";// ����MySQL���ݿ��������Ϣ private static final String url = "jdbc:sqlserver://localhost:1433;DatabaseName=shiTiKu";// ����SQL Server���ݿ���û��� private static final String userName = "sa";// ����SQL Server���ݿ���û��� private static final String userPwd = "218028";// �������ݿ���û��������� // private static final String dbName = "shiTiKu";// ���ݿ��� private static Connection conn=null; private static PreparedStatement pstmt=null; private static ResultSet rs=null; public static void main(String[] args) { conn = getDBConnection(); // PreparedStatement pstmt = null; // ResultSet rs = null; closeRS(conn, pstmt, rs); } public static Connection getDBConnection() { // ��������URL // String url1 = "jdbc:jtds:sqlserver://localhost:1433/" + dbName; //String url2 = "?user=" + userName + "&password=" + userPwd; //String url3 = "&useUnicode=true&characterEncoding=UTF-8"; //String url = url1 + url2 + url3; //Connection conn = null; try { Class.forName(driverName);// ע������ conn = DriverManager.getConnection(url,userName,userPwd);// ������� } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } // �ͷ���Դ public static void closeRS(Connection conn, PreparedStatement pstmt, ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { if (pstmt != null) { pstmt.close(); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
package shiti; public class FenShu { private int denominator, numerator; private boolean chengLi; public int getDenominator() { return denominator; } public void setDenominator(int denominator) { this.denominator = denominator; } public int getNumerator() { return numerator; } public void setNumerator(int numerator) { this.numerator = numerator; } public boolean isChengLi() { return chengLi; } public void setChengLi(boolean chengLi) { this.chengLi = chengLi; } public FenShu(int numerator, int denominator) { this.numerator = numerator; this.denominator = denominator; if (denominator == 0) { this.chengLi = false; } else { this.chengLi = true; yueJian(); } } // 根据字符串构造分数 public FenShu(String str) { if(str == null) { this.chengLi = false; } int index = str.indexOf("/"); if (index == -1) { this.numerator = Integer.parseInt(str); this.denominator = 1; this.chengLi = true; } else { this.denominator = Integer.parseInt(str.substring(index + 1)); if (this.denominator == 0) { chengLi = false; } else { chengLi = true; int zhengShu = str.indexOf("'"); if (zhengShu == -1) { // 没有整数部分 this.numerator = Integer.parseInt(str.substring(0, index)); } else { // 有整数部分 this.numerator = Integer.parseInt(str.substring(0, zhengShu)) * this.denominator + Integer.parseInt(str.substring(zhengShu + 1, index)); } yueJian(); } } } public FenShu() { } // 约简 private void yueJian() { int y = 1; for (int i = numerator; i > 1; i--) { if (numerator % i == 0 && denominator % i == 0) { y = i; break; } } // int nc = numerator,dc = denominator; // if(nc != 0){ // while(nc != dc - nc){ // y = dc - nc; // if(nc > y){ // dc = nc; // nc = y; // }else{ // dc = y; // } // } // y = nc; // numerator /= y; denominator /= y; } // 加 public FenShu add(FenShu b) { FenShu c = null; if (this.chengLi && b.isChengLi()) { int nNumerator = this.numerator * b.getDenominator() + this.denominator * b.getNumerator(); int nDenominator = this.denominator * b.getDenominator(); c = new FenShu(nNumerator, nDenominator); } else { c = new FenShu(); c.setChengLi(false); } return c; } // 减 public FenShu subtract(FenShu b) { FenShu c = null; if (this.chengLi && b.isChengLi()) { int nNumerator = this.numerator * b.getDenominator() - this.denominator * b.getNumerator(); int nDenominator = this.denominator * b.getDenominator(); c = new FenShu(nNumerator, nDenominator); } else { c = new FenShu(); c.setChengLi(false); } return c; } // 乘 public FenShu multiply(FenShu b) { FenShu c = null; if (this.chengLi && b.isChengLi()) { int nNumerator = this.numerator * b.getNumerator(); int nDenominator = this.denominator * b.getDenominator(); c = new FenShu(nNumerator, nDenominator); } else { c = new FenShu(); c.setChengLi(false); } return c; } // 除 public FenShu divide(FenShu b) { FenShu c = null; if (this.chengLi && b.isChengLi() && (b.getNumerator() != 0)) { int nNumerator = this.numerator * b.getDenominator(); int nDenominator = this.denominator * b.getNumerator(); c = new FenShu(nNumerator, nDenominator); } else { c = new FenShu(); c.setChengLi(false); } return c; } // 输出分数形式 public String toString() { if (this.chengLi) { if (numerator != 0) { if (numerator % denominator == 0) return "" + numerator / denominator; else if (numerator > denominator) { return (numerator / denominator) + "'" + (numerator % denominator) + "/" + denominator; } return numerator + "/" + denominator; } return "0"; } return "ERROR"; } }
package shiti; public class MyException extends Exception { public MyException(String msg) { // TODO Auto-generated constructor stub super(msg); } }
package shiti; import java.util.Stack; public class ShiTi { private int id; private String tiMu;// 题目 private String answer;// 答案 private String calculateOrder;// 运算式计算顺序,(后缀表达式) private int countNumber;// 运算符个数 private String userAnswer; private int mask; public String getuserAnswer() { return userAnswer; } public void setuserAnswer(String userAnswer) { this.userAnswer = userAnswer; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTiMu() { return tiMu; } public void setTiMu(String tiMu) { this.tiMu = tiMu; try { expressCalculate(); } catch (MyException e) { // TODO Auto-generated catch block e.printStackTrace(); }// 计算答案 this.countNumber = (tiMu.split(" ").length + 1) / 2; } public String getAnswer() { return answer; } public void setAnswer(String answer) { this.answer = answer; } public String getCalculateOrder() { return calculateOrder; } public void setCalculateOrder(String calculateOrder) { this.calculateOrder = calculateOrder; } public int getCountNumber() { return countNumber; } public void setCountNumber(int countNumber) { this.countNumber = countNumber; } public int getMask(){return mask;} public void setMask(int mask){this.mask=mask;} public ShiTi() { } // 表达式计算,参数为字符串类型的运算式 private void expressCalculate() throws MyException { if(this.tiMu == null) { throw new MyException("试题无效"); } String express = this.tiMu; Stack<String> num = new Stack<String>(); Stack<String> symbolS = new Stack<String>(); symbolS.push("#"); express += "#"; String order = ""; char ch; int i = 0; ch = express.charAt(i); while ((!symbolS.peek().equals("#")) || (ch != '#')) {// while循环开始 if (isNumber(ch)) {// 读到的不是空格,说明开始读运算数 String readNumStr = ""; while (true) { readNumStr += ch; ch = express.charAt(++i); if (ch == ' ' || ch == '#' || ch == ')') {// 读到的是空格,或,说明运算数结束 break; } } num.push(readNumStr); } else if (ch == ' ') { if ((i + 1) < express.length()) {// 未到字符串末尾 ch = express.charAt(++i); } }else {// 读到的是运算符 char compare = priorityCompare(symbolS.peek(), ch + ""); if (compare == '=') {// 若优先级相等,则说明ch是右括号,栈顶为左括号,此时将栈顶弹出,读取下一个字符 symbolS.pop(); ch = express.charAt(++i); } else if (compare == '>') {// ch的优先级小于栈顶的优先级,要说明栈顶的运算符应该先计算,所以应弹栈运算 // 弹出两个运算数,弹出一个运算符 String bStr = num.pop(); String aStr = num.pop(); String symbolT = symbolS.pop(); // 计算该字表达式 String c = yunSuan(aStr, bStr, symbolT); if (c.equals("ERROR")) {// 如果计算函数返回error则说明计算过程出现了负数,说明该运算式不符合要求,停止计算,计算结果为error,返回; this.answer = "ERROR"; return; } else {// 计算过程正常,则将计算结果压栈 order += aStr + "," + symbolT + "," + bStr + ",";// 将运算的子表达式加进运算顺序字符串中,操作数和操作符用逗号隔开 num.push(c); } } else if(compare == 'E') { this.answer = "ERROR"; return; } else {// 说明ch优先级大于栈顶元素的优先级,则应将ch压栈,读取下一个运算符 symbolS.push(ch + ""); if ((i + 1) < express.length()) { ch = express.charAt(++i); } } } } this.answer = num.pop(); this.calculateOrder = order; } // 判断ch是否为数字 private boolean isNumber(char ch) { if (ch >= '0' && ch <= '9') { return true; } return false; } /* * 子表达式计算,参数为两个运算数的字符串形式,和一个运算符,也为字符串类型 返回计算结果的字符串形式 * 如果减法运算出现负数,或除数为0,或分数的分母为0则返回ERROR * */ private String yunSuan(String aStr, String bStr, String symbol) throws MyException { if(aStr == null || bStr == null || symbol == null) { throw new MyException("子表达式出现错误!"); } int adivIndex = aStr.indexOf("/"); int bdivIndex = bStr.indexOf("/"); if ((adivIndex == -1) && (bdivIndex == -1)) {// a.b都是整数 int a = Integer.parseInt(aStr); int b = Integer.parseInt(bStr); switch (symbol.charAt(0)) { case '+': return a + b + ""; case '-': { if (a < b) { return "ERROR"; } return a - b + ""; } case '×': { return a * b + ""; } case '÷': { if (b == 0) { return "ERROR"; } else if (a % b == 0) { return a / b + ""; } return new FenShu(a, b).toString(); } default: return "ERROR"; } } else {// a,b中存在分数,则将a,b都当做分数进行运算 FenShu a = new FenShu(aStr); FenShu b = new FenShu(bStr); switch (symbol.charAt(0)) { case '+': return a.add(b).toString(); case '-': { FenShu c = a.subtract(b); if(c.getNumerator() < 0) { return "ERROR"; } return c.toString(); } case '×': return a.multiply(b).toString(); case '÷': return a.divide(b).toString(); default: return "ERROR"; } } } // 判断运算符优先级 private char priorityCompare(String a, String b) { char[][] priority = { { '>', '>', '<', '<', '<', '>', '>' }, { '>', '>', '<', '<', '<', '>', '>' }, { '>', '>', '>', '>', '<', '>', '>' }, { '>', '>', '>', '>', '<', '>', '>' }, { '<', '<', '<', '<', '<', '=', '>' }, { '>', '>', '>', '>', ' ', '>', '>' }, { '<', '<', '<', '<', '<', ' ', '=' } }; int a_index = index_symbol(a); int b_index = index_symbol(b); if(a_index == -1 || b_index == -1) { return 'E'; } return priority[a_index][b_index]; } // 获取运算符对应的下标 private int index_symbol(String a) { String p = "+-×÷()#"; // System.out.println("判断运算符对应的下标:" + a); return p.indexOf(a); } }
package shiti; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; //试题数据库操作类,即对数据库进行增删改查的操作的类 public class ShiTiDAO { private String INSERT_SQL = "insert into shiTiKu02(tiMu,answer,calculateOrder,countNumber,userAnswer,mask) values(?,?,?,?,?,?)"; private String SELECTBYNUMBERCOUNT_SQL = "select * from shiTiKu02 where countNumber=?"; private String SELECTBYMASK_SQL = "select * from shiTiKu02 where mask=?";//寻找错题 private String SELECTALL = "select * from shiTiKu02"; public static void main(String[] args) { // TODO Auto-generated method stub ShiTiDAO dao=new ShiTiDAO(); Connection conn = null; conn = DBUtil.getDBConnection();// 获取连接 } // 向数据库中插入一条记录 public void insert(ShiTi stb) throws SQLException, MyException { if(stb == null) { throw new MyException("试题无效!"); } Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; conn = DBUtil.getDBConnection();// 获取连接 pstmt = conn.prepareStatement(INSERT_SQL);// 获取操作对象 // 设置字段值 pstmt.setString(1, stb.getTiMu()); pstmt.setString(2, stb.getAnswer()); pstmt.setString(3, stb.getCalculateOrder()); pstmt.setInt(4, stb.getCountNumber()); // 执行 pstmt.executeUpdate(); // 释放资源 DBUtil.closeRS(conn, pstmt, rs); } // 向数据库中插入多条记录,参数为list public void insert(List<ShiTi> list) throws SQLException, MyException{ if(list == null) { throw new MyException("试题无效!"); } Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; conn = DBUtil.getDBConnection();// 获取连接 pstmt = conn.prepareStatement(INSERT_SQL);// 获取操作对象 // 设置字段值 for (ShiTi stb : list) { pstmt.setString(1, stb.getTiMu()); pstmt.setString(2, stb.getAnswer()); pstmt.setString(3, stb.getCalculateOrder()); pstmt.setInt(4, stb.getCountNumber()); pstmt.setString(5,stb.getuserAnswer()); pstmt.setInt(6,stb.getMask()); pstmt.executeUpdate(); } // 执行 // 释放资源 DBUtil.closeRS(conn, pstmt, rs); } // 根据运算数个数查询,返回结果为list public List<ShiTi> selectByNumbercount(int count) throws SQLException, MyException { if(count < 2) { throw new MyException("运算数个数应大于等于2"); } Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; List<ShiTi> list = new ArrayList<ShiTi>(); conn = DBUtil.getDBConnection();// 获取连接 pstmt = conn.prepareStatement(SELECTBYNUMBERCOUNT_SQL);// 获取操作对象 // 设置字段值 pstmt.setInt(1, count); // 执行 rs = pstmt.executeQuery(); // 结果处理 ShiTi stb = null; while (rs.next()) { stb = new ShiTi(); stb.setTiMu(rs.getString("tiMu")); stb.setAnswer(rs.getString("answer")); stb.setCalculateOrder(rs.getString("calculateOrder")); stb.setCountNumber(rs.getInt("countNumber")); stb.setuserAnswer(rs.getString("userAnswer")); stb.setMask(rs.getInt("mask")); list.add(stb); } // 释放资源 DBUtil.closeRS(conn, pstmt, rs); return list; } public List<ShiTi> selectByMask(int mask) throws SQLException, MyException { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; List<ShiTi> list = new ArrayList<ShiTi>(); conn = DBUtil.getDBConnection();// 获取连接 pstmt = conn.prepareStatement(SELECTBYMASK_SQL);// 获取操作对象 // 设置字段值 pstmt.setInt(1, mask); // 执行 rs = pstmt.executeQuery(); // 结果处理 ShiTi stb = null; while (rs.next()) { stb = new ShiTi(); stb.setTiMu(rs.getString("tiMu")); stb.setAnswer(rs.getString("answer")); stb.setCalculateOrder(rs.getString("calculateOrder")); stb.setCountNumber(rs.getInt("countNumber")); stb.setuserAnswer(rs.getString("userAnswer")); stb.setMask(rs.getInt("mask")); list.add(stb); } // 释放资源 DBUtil.closeRS(conn, pstmt, rs); return list; } //查询数据库中的全部记录 public List<ShiTi> selectAll() throws SQLException { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; List<ShiTi> list = new ArrayList<ShiTi>(); conn = DBUtil.getDBConnection();// 获取连接 pstmt = conn.prepareStatement(SELECTALL);// 获取操作对象 // 执行 rs = pstmt.executeQuery(); // 结果处理 ShiTi stb = null; while (rs.next()) { stb = new ShiTi(); stb.setTiMu(rs.getString("tiMu")); stb.setAnswer(rs.getString("answer")); stb.setCalculateOrder(rs.getString("calculateOrder")); stb.setCountNumber(rs.getInt("countNumber")); stb.setuserAnswer(rs.getString("userAnswer")); stb.setMask(rs.getInt("mask")); list.add(stb); } // 释放资源 DBUtil.closeRS(conn, pstmt, rs); return list; } }
package shiti; import java.util.Random; //试题类, /* * 方法有:生成一个试题,计算试题答案, * * */ public class ShiTiOperator { /* // 获取一个运算式 public static void main(String[] args) { ShiTi a = new ShiTi(); a.setTiMu("4 + 2 / 3 - 1");//设置题目a System.out.println("答案为:" + a.getAnswer()); // ShiTi b = new ShiTi(); // b.setTiMu("2 + 1 + 4 + 3");//设置题目b // System.out.println("是否重复判断结果为:" + calculateOrderSame(a, b)); }*/ public static ShiTi getExpress(int maxNum, int hasChengChu,int hasKuoHao, int type) throws MyException { if(maxNum <= 0) { throw new MyException("最大数值应为正数"); } ShiTi stb = new ShiTi(); Random rd = new Random(); char[] fuHao = { '+', '-', '×', '÷' }; int fuHaoFanWei = 2 + 2 * hasChengChu; while (true) { int[] bracket = null;// 存储括号位置 int expressLength = rd.nextInt(3) + 2;// 随机生成一个2~4之间的整数作为该运算式的运算数的个数 stb.setCountNumber(expressLength); String[] number = new String[expressLength];// 存储运算数的数组 String[] symbol = new String[expressLength - 1];// 存储运算符的数组 String express = ""; number[0] = getOperatorNumber(type, maxNum); for (int i = 0; i < expressLength - 1; i++) { symbol[i] = fuHao[rd.nextInt(fuHaoFanWei)] + "";// 生成运算符 number[i + 1] = getOperatorNumber(type, maxNum); } if (hasKuoHao == 1) { // 需要加括号 bracket = randomAddBracket(expressLength); } // 构建表达式 for (int i = 0; i < expressLength; i++) { // 添加左括号 if (hasKuoHao == 1) { for (int j = 0; j < bracket[i]; j++) { express += "("; } } express += number[i];// 加上运算数 // 添加右括号 if (hasKuoHao == 1) { for (int j = 0; j > bracket[i]; j--) { express += ")"; } } if (i != expressLength - 1) { express += " " + symbol[i] + " ";// 加运算符,并在两侧加空格来与运算数分隔 } } stb.setTiMu(express); if (!(stb.getAnswer().equals("ERROR"))) { // System.out.println("生成的运算式为:" + express + "=" + result[0]); return stb; } } } // 随机生成括号,参数为运算式的运算数的个数 private static int[] randomAddBracket(int length) throws MyException { if(length <= 1) { throw new MyException("运算式长度不能小于2"); } int[] brackets = new int[length]; for (int i = 0; i < brackets.length; i++) brackets[i] = 0; Random rd = new Random(); for (int i = 2; i < length; i++) {// 添加的括号长度(括号包围的运算数的个数) for (int j = 0; j < length - i + 1; j++) { int t = rd.nextInt(2);// 随机生成0或1,0代表不加括号,1代表加括号 if (t == 1) { if (brackets[j] >= 0 && brackets[j + i - 1] <= 0) {// 要加的括号的第一个运算数周围没有右括号,且 // 最后一个运算数周围没有左括号 int counteract1 = 0,counteract2 = 0,counteract3 = 0; for (int k = j; k < j + i; k++) {// 将要加的括号之间的所有运算数对应的brackets相加, // 如果和为0说明这个括号之间的括号是匹配的,不会出现括号交叉现象 counteract1 += brackets[k]; } for (int k = 0; k < j - 1; k++) {// 将要加的括号之前的所有运算数对应的brackets相加, // 如果和为0说明这个括号之间的括号是匹配的,不会出现括号交叉现象 counteract2 += brackets[k]; } for (int k = j + i; k < length; k++) {// 将要加的括号之后的所有运算数对应的brackets相加, // 如果和为0说明这个括号之间的括号是匹配的,不会出现括号交叉现象 counteract3 += brackets[k]; } if (counteract1 == 0 && counteract2 == 0 && counteract3 == 0) { brackets[j]++; brackets[j + i - 1]--; j += i; } } } } } return brackets; } // 随机生成一个运算数( type==0代表生成整数,type==1代表生成真分数,maxNum代表数值范围 0~(maxNum-1) ) private static String getOperatorNumber(int type, int maxNum) throws MyException { if(maxNum <= 0) { throw new MyException("最大数值应为正数"); } Random rd = new Random(); int a; while (true) { a = rd.nextInt(maxNum); if (type == 0) {// 随机生成一个整数 return "" + a; } else {// 随机生成一个真分数 if (a == 0) { continue; } int b = rd.nextInt(a); FenShu c = new FenShu(b, a); return c.toString(); } } } //-------------------------------------------------- public static boolean calculateOrderSame(ShiTi a, ShiTi b) throws MyException { if(a == null || b == null) { throw new MyException("试题无效!"); } //比较两个运算式的运算数个数 if(a.getCountNumber() != b.getCountNumber()) { return false; } //比较两运算式的答案是否相同 if(!a.getAnswer().equals(b.getAnswer())) { return false; } // 取出运算式的运算顺序字符串, String aorder = a.getCalculateOrder(); String border = b.getCalculateOrder(); // 将a,b运算式的运算顺序字符串进行分割,按序取出每一个运算数和运算符 String[] asplit = aorder.split(","); String[] bsplit = border.split(","); int n = a.getCountNumber() - 1;//共有n组子表达式 for(int i = 0;i < n;i++) { //取a运算式该子表达式的两个运算数a1,a2,运算符af,运算结果ar String a1 = asplit[0 + i * 3]; String af = asplit[1 + i * 3]; String a2 = asplit[2 + i * 3]; //取b运算式该子表达式的两个运算数b1,b2,运算符bf,运算结果br String b1 = bsplit[0 + i * 3]; String bf = bsplit[1 + i * 3]; String b2 = bsplit[2 + i * 3]; if(af.equals(bf)) { //两子表达式符号相同 if(a1.equals(b1) && a2.equals(b2)) { continue;//该子表达式相同,继续判断下一个子表达式 } else if( (af.equals("+") || af.equals("×")) && a1.equals(b2) && a2.equals(b1) ) { continue;//该子表达式相同,继续判断下一个子表达式 } else { return false; } } else { return false; } } return true; } //-------------------------------------------------- }
package shiti; import java.util.ArrayList; import java.util.List; /* * 随机生成四则运算式3 * * */ public class SiZe3 { // 生成整数计算式添加限制条件,type为运算式类型 0代表整数式,1代表真分数式 public static List<ShiTi> createYunSuanShi(int hasChengChu,int hasKuoHao, int maxNum, int n, int type) throws MyException { int i = 0; if(n <= 0) { throw new MyException("运算数个数设置错误,应为正数"); } List<ShiTi> list = new ArrayList<ShiTi>(); ShiTi stb = null; // ShiTiDAO std = new ShiTiDAO(); while (i < n) { stb = ShiTiOperator.getExpress(maxNum, hasChengChu,hasKuoHao, type); // 检验重复 boolean chongFu = false; for (int j = 0; j < i; j++) { ShiTi t = list.get(j); if (ShiTiOperator.calculateOrderSame(stb, t)) { chongFu = true; System.out.println("出现重复:计算式一:" + t.getTiMu() + " = " + t.getAnswer() + " 运算顺序:" + t.getCalculateOrder() + " 运算数个数:" + t.getCountNumber()); System.out.println("出现重复:计算式二:" + stb.getTiMu() + " = " + stb.getAnswer() + " 运算顺序:" + stb.getCalculateOrder() + " 运算数个数:" + stb.getCountNumber()); System.out.println("\n\n"); break; } } if (chongFu == false) { list.add(stb); i++; } } return list; } }
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"> <title>用户登陆</title> <style type="text/css"> <!-- body,td,th { font-family: Times New Roman, Times, serif; color: #000000; } body { background-color: #FFFFFF; } --> </style> <script type="text/javascript"> function checkNull() { if(document.getElementById("name").value==""){ alert("未填用户名!"); return false; } if(document.getElementById("passwd").value==""){ alert("未填密码!"); return false; } if((document.getElementById("passwd").value=="123") && (document.getElementById("name").value=="123")){ alert("登陆成功!"); return true; } if((document.getElementById("passwd").value!="123") || (document.getElementById("name").value!="123")){ alert("登陆失败!"); return false; } } </script> </head> <body> <form name="form1" method="post" action="SET.jsp"> <center> <table width="460" height="210" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr bgcolor="#CCFF99"> <th height="60" bordercolor="#FFFFFF" scope="col"> <label>登陆</label></th> </tr> <tr bgcolor="#CCFF99"> <th height="41" bordercolor="#FFFFFF" scope="col"> <label><span class="STYLE1"> 用户名 <input id="name" type="text" name="name" style="width:200px; height:18px;" size="20"> </span></label></th> </tr> <tr bgcolor="#CCFF99"> <th height="41" bordercolor="#FFFFFF" scope="col"> <label><span class="STYLE1"> 密 码 <input id="passwd" type="password" name="passwd" style="width:200px; height:18px;" size="20"> </span></label></th> </tr> <tr bgcolor="#CCFF99"> <th height="41" bordercolor="#FFFFFF" scope="col"> <label><span class="STYLE1"> <input type="submit" name="submit" value="登陆" onClick="return checkNull()"> <input type="reset" name="reset" value="重置"> </span></label></th> </tr> <tr bgcolor="#CCFF99"> <th height="27" bordercolor="#FFFFFF" scope="col"> <label>如果还没有账号,请<a href="sign.jsp">注册</a>...</label></th> </tr> </table> </center> </form> </body> </html>
<%@ 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"> <title>用户注册</title> </head> <body> <center> 还未实现此功能,点击跳转至<a href="login.jsp">登陆</a>界面...... </center> </body> </html>
<%@ 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"> <title>题目设置</title> <script type="text/javascript"> function checkNull() { if(document.getElementById("number").value==""){ alert("题目数不能为空!"); return false; } if(document.getElementById("range").value==""){ alert("数值范围不能为空!"); return false; } } </script> <style type="text/css"> <!-- .STYLE1 {font-size: large} .STYLE3 { color: #FF0033; font-family: "Times New Roman", Times, serif; font-style: italic; } --> </style> </head> <body> <% request.setCharacterEncoding("utf-8"); String name=(String)request.getParameter("name"); String passwd=(String)request.getParameter("passwd"); %> <form name="form1" method="post" action="Dati.jsp"> <h5 align="center" class="STYLE3">欢迎用户<%=name%>进入答题系统~ </h5> <h5 align="center" class="STYLE3"> <a href="person.jsp">查看历史错题</a>.<a href="https://www.baidu.com/">帮助</a><a href="login.jsp">.退出</a></h5> <table align="center" width="460" height="39" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr bgcolor="#CCFF99"> <th height="27" colspan="2" bordercolor="#FFFFFF" scope="col"> <label><span class="STYLE1">四则运算题目设置</span></label></th> </tr> <tr bgcolor="#CCFF99"> <td height="27" colspan="2" align="center" bordercolor="#FFFFFF" scope="col"> <label><span class="STYLE1"> * 题目数量 <input id="number" type="text" name="number" style="width:60px; height:18px;" size="7"> </span></label></td> </tr> <tr bgcolor="#CCFF99"> <td height="27" colspan="2" align="center" bordercolor="#FFFFFF" scope="col"> <label><span class="STYLE1"> * 数值范围 <input id="range" type="text" name="range" style="width:60px; height:18px;" size="7"> </span></label></td> </tr> <tr bgcolor="#CCFF99"> <td height="27" colspan="2" align="center" bordercolor="#FFFFFF" scope="col"> <label> </label> <span class="STYLE1"> <label> <input name="type" type="radio" value="0" checked> 整数式</label> <label> <input name="type" type="radio" value="1"> 分数式</label> </span></td> </tr> <tr bgcolor="#CCFF99"> <td height="27" colspan="2" align="center" bordercolor="#FFFFFF" scope="col"> <label> </label> <span class="STYLE1"> <label> <input name="cc" type="radio" value="0" checked> 无乘除</label> <label> <input name="cc" type="radio" value="1"> 有乘除</label> </span></td> </tr> <tr bgcolor="#CCFF99"> <td height="27" colspan="2" align="center" bordercolor="#FFFFFF" scope="col"> <label></label> <span class="STYLE1"> <label> <input name="checkbox" type="radio" value="1"> 有括号</label> <label> <input name="checkbox" type="radio" value="0" checked> 无括号</label> </span></td> </tr> <tr bgcolor="#CCFF99"> <td height="27" colspan="2" align="center" bordercolor="#FFFFFF" scope="col"> <label><span class="STYLE1"> <input type="submit" name="submit" value="生成题目" onClick="return checkNull()"> <input type="reset" name="reset" value="重置"> </span></label></td> </tr> </table> </center> </form> </body> </html>
<%@ page language="java" contentType="text/html; charset=utf-8" import="java.util.*,shiti.*" pageEncoding="gb2312"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!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"> <title>答题开始</title> <style type="text/css"> <!-- #Layer1 { position:absolute; width:583px; height:233px; z-index:1; left: 357px; top: 58px; } .STYLE1 {font-size: medium} --> </style> </head> <body> <p> <!-- 从前一个页面中获得信息 --> <% request.setCharacterEncoding("utf-8"); int number=Integer.parseInt(request.getParameter("number")); int range=Integer.parseInt(request.getParameter("range")); int type=Integer.parseInt(request.getParameter("type")); int cc=Integer.parseInt(request.getParameter("cc")); int checkbox=Integer.parseInt(request.getParameter("checkbox")); %> <!-- 将试题个数number和试题list存入session对象中,用于在判断试题页面使用 --> <% List<ShiTi> list = SiZe3.createYunSuanShi(cc,checkbox, range, number, type); session.setAttribute("number", number); session.setAttribute("list", list); %> </p> <center> <table width="460" height="60" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr bgcolor="#CCFF99"> <th height="48" colspan="2" bordercolor="#FFFFFF" scope="col"> <label><span class="STYLE4">开始答题</span></label></th> </tr> </table> </center> <form name="form1" method="post" action="judge_Dati.jsp"> <% for(int i=0;i<number;i++) { ShiTi a=list.get(i); String s=a.getTiMu(); %> <center> <table width="460" height="39" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr align="left" bgcolor="#CCFF99"> <th width="56" height="27" align="center" valign="baseline" bordercolor="#FFFFFF" scope="col"><div align="center"> <%out.print(i+1);%> </div></th> <td width="375" valign="baseline" nowrap bordercolor="#FFFFFF" scope="col"><%out.print(s+" = ");%> <label> <input type="text" name="<%=(i + 1) %>" style="width:60px; height:18px;" size="7"> </label></td></tr> </table> <% } %> <table width="460" height="39" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr bgcolor="#CCFF99"> <td height="27" colspan="2" align="center" bordercolor="#FFFFFF" scope="col"> <label> <input type="submit" name="submit" style="width:60px; height:20px;" value="确认交卷"> </label> </td> </tr> </table> </center> </form> </body> </html>
<%@ page language="java" contentType="text/html; charset=utf-8" import="java.util.*,shiti.*,java.sql.*" 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"> <title>结果</title> <style type="text/css"> <!-- .STYLE2 {font-size: xx-small} .STYLE4 {font-size: large} --> </style> </head> <body> <% /* 获取session中的试题信息(试题总数和试题list) */ request.setCharacterEncoding("utf-8"); int number=(Integer)(session.getAttribute("number")); List<ShiTi> list = (List<ShiTi>) session.getAttribute("list"); /* 将试题信息从session中删除 */ session.removeAttribute("number"); session.removeAttribute("list"); /* 创建新的试题list2存用户的答案和题目 */ List<ShiTi> list2 = new ArrayList<ShiTi>(); %> <center> <table width="460" height="60" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr bgcolor="#CCFF99"> <th height="48" colspan="2" bordercolor="#FFFFFF" scope="col"> <span class="STYLE4"> <label>答题评判</label> </span></th> </tr> </table> </center> <!-- 判断答案的正确与错误 --> <% String[] msg=new String[number]; String[] tii=new String[number]; int wrong=0; for(int i=0;i<number;i++) { String userAnswer=request.getParameter((i+1)+""); int mask; ShiTi st=list.get(i); if(st.getAnswer().equals(userAnswer)) { msg[i]="dui"; tii[i]=""; mask=0; } else { msg[i]="cuo"; tii[i]=" THE KEY = "+st.getAnswer();/* 正确答案 */ mask=1; wrong++; } %> <!-- 将新的信息存入数据库中 --> <% st.setuserAnswer(userAnswer);//将用户的答案存入试题对象 st.setMask(mask); list2.add(st);//将试题对象存入试题list2, }//for %> <!-- 连接数据库方法1 --> <!-- 将添加用户答案后的试题信息shiTiList2存入数据库 --> <% ShiTiDAO stdao = new ShiTiDAO();//构建一个操作数据库的对象 stdao.insert(list2);//调用操作数据库对象的插入方法将试题信息插入到数据库 %> <!-- 页面上展示 --> <% for(int i=0;i<number;i++) { ShiTi st = list2.get(i); %> <center> <table width="460" height="39" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr align="center" bgcolor="#CCFF99"> <th width="56" height="27" valign="baseline" bordercolor="#FFFFFF" scope="col"> <div align="center"><%out.print(i+1);%> </div></th> <td width="375" valign="baseline" nowrap bordercolor="#FFFFFF" scope="col"> <div align="left"><%out.print(st.getTiMu()+" = "+st.getuserAnswer());%> <div align="right"><img src="images/<%=msg[i] %>.png"><span class="STYLE2"><%=tii[i] %></span></div> </div></td> </tr> </table> <% } %> <table width="460" height="39" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr bgcolor="#CCFF99"> <th height="27" colspan="2" bordercolor="#FFFFFF" scope="col"> <form name="form1" method="post" action="SET.jsp"> <label> <input type="submit" name="submit" style="width:60px; height:18px;" value="返回"> </label> </form> </th> </tr> </table> </center> </body> </html>
<%@ page language="java" contentType="text/html; charset=utf-8" import="java.util.*,shiti.*,java.text.DecimalFormat" 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"> <title>历史错题</title> <style type="text/css"> <!-- .STYLE2 { font-size: x-small; color: #006600; } .STYLE3 {color: #FF0000} .STYLE4 {color: #330000} --> </style> </head> <body> <!-- 从试题库中查询错题 --> <% request.setCharacterEncoding("utf-8"); ShiTiDAO stdao = new ShiTiDAO();//构建一个操作数据库的对象 List<ShiTi> list3=stdao.selectByMask(1); int wrongNum=list3.size(); List<ShiTi> list=stdao.selectAll(); int number=list.size(); float f=wrongNum*100/number; %> <center> <table width="460" height="99" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr bgcolor="#CCFF99"> <th height="48" colspan="2" bordercolor="#FFFFFF" scope="col"> <label><span class="STYLE4"><span class="STYLE3">错题集</span><br> <div align="right"> <span class="STYLE2">[</span><span class="STYLE2">错误率:<%=f %>%]</span></div></label></th> </tr> <!-- 循环的内容 --> <% for(int i=0;i<wrongNum;i++){ ShiTi st=list3.get(i); %> <table width="460" height="39" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr align="center" bgcolor="#CCFF99"> <th width="56" height="27" valign="baseline" bordercolor="#FFFFFF" scope="col"> <div align="center"><%out.print(i+1);%> </div></th> <td width="375" valign="baseline" nowrap bordercolor="#FFFFFF" scope="col"> <div align="left"><%out.print(st.getTiMu()+" = "+st.getAnswer());%> </div></td> </tr> </table> <% } %> <table width="460" height="39" border="1" cellpadding="0" cellspacing="5" bordercolor="#FFFFFF" bgcolor="#FFFFFF"> <tr bgcolor="#CCFF99"> <th height="27" colspan="2" bordercolor="#FFFFFF" scope="col"> <form name="form1" method="post" action="SET.jsp"> <label> <input type="submit" name="submit" style="width:60px; height:18px;" value="返回"> </label> </form> </th> </tr> </table> </table> </center> </body> </html>
三、运行结果截图
开始进入主页面(登陆界面,login.jsp,界面比较简陋)
然后输入用户名和密码(因为还没实现用户注册和登陆功能,所以先只设定了一个用户,其用户名和密码均为123)
如果错误将会出现提示
如果需要注册,则出现如下界面(sign.jsp)
登陆成功之后,则进入题目设置界面(SET.jsp)
此处进行题目设置,还可以浏览历史错题(错题集,并统计错误率);帮助链接至百度页面;退出链接至登陆界面。
首先,我们先进行题目设置吧~
然后点击生成题目,进入答题界面(Dati.jsp)
输入答案,之后,点击确认交卷,即进入评判界面(judge_Dati.jsp)
接着,返回到题目设置界面(SET.jsp),此处,我们可以试着点击查看历史错题(person.jsp)
点击底端的返回按钮,就重新回到了SET.jsp页面。
数据表显示如下
四、编程总结
①补充:其实可以实现多个用户登录注册的功能。就是再新建一个用户的数据表,进行增删改查,然后在试题的数据表中增加用户这一列,用SQL语句就可以实现加入多个用户后的四则运算功能。
②此程序的JAVA类其实不完全是我们写的,我们写的JAVA类的实现的四则运算的功能很少,但此次实验的主要目的就是将JAVA版的四则运算改成网页版的。我们之后,会再学习四则运算的JAVA代码。