一、记录开发过程中的时间记录日志。
PSP2.1 |
Personal Software Process Stages |
Time |
Planning |
计划 | 50小时 |
Development |
开发 | |
· Analysis |
· 需求分析 (包括学习新技术) |
一天+一晚 (32小时) |
· Design Spec |
·生成设计文档 | 2小时 |
·Design Review | ·设计复审(和同事审核设计文档) | 1.5小时 |
·Coding Standard | ·代码规范(为目前的开发制定合适的规范) | 1小时 |
·Design | ·具体设计 | 2小时 |
·Coding | ·具体编码 | 9.5小时 |
·Code Review | ·代码复审 | 1小时 |
·Test | ·测试(自我测试、修改代码、提交修改) | 1小时 |
Reporting | 报告 | |
·Test Report | ·测试报告 | 1小时 |
·Size Measurement | ·计算工作量 | 1小时 |
·Postmortem & Precess Improvement Plan | ·事后总结,并提出过程改进计划 | 1小时 |
合计 | 53小时 |
二、程序设计思想
按Bean+Servlet+jsp模式(即MVC模式),首先数据库要建三个表,一个储存用户信息,一个储存题目,一个储存成绩。其余是Java部分,实现servlet,执行整数运算操作,混合运算操作。最后写jsp文件,实现网页界面显示。
三、程序源代码
1 package model; 2 3 public class FenShu { 4 5 private int denominator,numerator; 6 private boolean chengLi; 7 public FenShu(){} 8 9 public int getDenominator() { 10 return denominator; 11 } 12 13 public void setDenominator(int denominator) { 14 this.denominator = denominator; 15 } 16 17 public int getNumerator() { 18 return numerator; 19 } 20 21 public void setNumerator(int numerator) { 22 this.numerator = numerator; 23 } 24 25 public boolean isChengLi() { 26 return chengLi; 27 } 28 29 public void setChengLi(boolean chengLi) { 30 this.chengLi = chengLi; 31 } 32 //----在构造函数的时候就已经化简了 33 public FenShu(int numerator,int denominator) 34 { 35 this.numerator=numerator; 36 this.denominator=denominator; 37 if(denominator==0){ 38 this.chengLi=false; 39 } 40 else 41 { 42 this.chengLi=true; 43 huaJian(); 44 } 45 } 46 //化简 47 private void huaJian() { 48 int y = 1; 49 for (int i = numerator; i > 1; i--) { 50 if (numerator % i == 0 && denominator % i == 0) { 51 y = i; 52 break; 53 } 54 } 55 56 numerator /= y; 57 denominator /= y; 58 59 } 60 61 //---把字符串分割成分数,每次处理都化简 62 public FenShu(String str) 63 { 64 if(str == null) 65 { 66 this.chengLi = false; 67 } 68 int index = str.indexOf("/"); 69 if (index == -1) { 70 this.numerator = Integer.parseInt(str); 71 this.denominator = 1; 72 this.chengLi = true; 73 74 } else { 75 this.denominator = Integer.parseInt(str.substring(index + 1)); 76 if (this.denominator == 0) { 77 chengLi = false; 78 } else { 79 chengLi = true; 80 int zhengShu = str.indexOf("'"); 81 if (zhengShu == -1) { 82 // 没有整数部分 83 this.numerator = Integer.parseInt(str.substring(0, index)); 84 } else { 85 // 有整数部分 86 this.numerator = Integer.parseInt(str.substring(0, zhengShu)) * this.denominator 87 + Integer.parseInt(str.substring(zhengShu + 1, index)); 88 } 89 huaJian(); 90 } 91 } 92 } 93 94 // 加 95 public FenShu add(FenShu b) { 96 97 FenShu c = null; 98 if (this.chengLi && b.isChengLi()) { 99 int nNumerator = this.numerator * b.getDenominator() + this.denominator * b.getNumerator(); 100 int nDenominator = this.denominator * b.getDenominator(); 101 c = new FenShu(nNumerator, nDenominator); 102 } else { 103 c = new FenShu(); 104 c.setChengLi(false); 105 } 106 return c; 107 } 108 109 // 减 110 public FenShu subtract(FenShu b) { 111 FenShu c = null; 112 if (this.chengLi && b.isChengLi()) { 113 int nNumerator = this.numerator * b.getDenominator() - this.denominator * b.getNumerator(); 114 int nDenominator = this.denominator * b.getDenominator(); 115 c = new FenShu(nNumerator, nDenominator); 116 } else { 117 c = new FenShu(); 118 c.setChengLi(false); 119 } 120 return c; 121 } 122 123 // 乘 124 public FenShu multiply(FenShu b) { 125 FenShu c = null; 126 if (this.chengLi && b.isChengLi()) { 127 128 int nNumerator = this.numerator * b.getNumerator(); 129 int nDenominator = this.denominator * b.getDenominator(); 130 c = new FenShu(nNumerator, nDenominator); 131 } else { 132 c = new FenShu(); 133 c.setChengLi(false); 134 } 135 return c; 136 } 137 138 // 除 139 public FenShu divide(FenShu b) { 140 FenShu c = null; 141 if (this.chengLi && b.isChengLi() && (b.getNumerator() != 0)) { 142 143 int nNumerator = this.numerator * b.getDenominator(); 144 int nDenominator = this.denominator * b.getNumerator(); 145 c = new FenShu(nNumerator, nDenominator); 146 } else { 147 c = new FenShu(); 148 c.setChengLi(false); 149 } 150 return c; 151 } 152 153 // 输出分数形式 154 public String toString() { 155 if (this.chengLi) { 156 if (numerator != 0) { 157 if (numerator % denominator == 0) 158 return "" + numerator / denominator; 159 else if (numerator > denominator) { 160 return (numerator / denominator) + "'" + (numerator % denominator) + "/" + denominator; 161 } 162 return numerator + "/" + denominator; 163 } 164 return "0"; 165 } 166 return "ERROR"; 167 } 168 }
1 package model; 2 3 import java.util.Stack; 4 5 //---存储试题,计算试题答案 6 public class Question { 7 8 private int id,userScore,length,shiJuanID; 9 private String tiMu,rightAnswer,userAnswer,userName,logicOrder; 10 11 12 public Question(){} 13 public int getId() { 14 return id; 15 } 16 17 public void setId(int id) { 18 this.id = id; 19 } 20 21 public int getShiJuanID() { 22 return shiJuanID; 23 } 24 25 public void setShiJuanID(int shiJuanID) { 26 this.shiJuanID = shiJuanID; 27 } 28 29 public int getUserScore() { 30 return userScore; 31 } 32 33 public void setUserScore(int userScore) { 34 this.userScore = userScore; 35 } 36 37 public int getLength() { 38 return length; 39 } 40 41 public void setLength(int length) { 42 this.length = length; 43 } 44 45 public String getTiMu() { 46 return tiMu; 47 } 48 49 public void setTiMu(String tiMu) { 50 this.tiMu = tiMu; 51 try { 52 expressCalculate(); 53 } catch (MyException e) { 54 // TODO Auto-generated catch block 55 e.printStackTrace(); 56 }// 计算答案 57 this.length = (tiMu.split(" ").length + 1) / 2; 58 } 59 60 public String getRightAnswer() { 61 return rightAnswer; 62 } 63 64 public void setRightAnswer(String rightAnswer) { 65 this.rightAnswer = rightAnswer; 66 } 67 68 public String getUserAnswer() { 69 return userAnswer; 70 } 71 72 public void setUserAnswer(String userAnswer) { 73 this.userAnswer = userAnswer; 74 } 75 76 77 78 public String getUsername() { 79 return userName; 80 } 81 82 public void setUsername(String username) { 83 this.userName = username; 84 } 85 86 public String getLogicOrder() { 87 return logicOrder; 88 } 89 90 public void setLogicOrder(String logicOrder) { 91 this.logicOrder = logicOrder; 92 } 93 94 // 表达式计算,参数为字符串类型的运算式 95 private void expressCalculate() throws MyException { 96 if(this.tiMu == null) 97 { 98 throw new MyException("试题无效"); 99 } 100 String express = this.tiMu; 101 102 103 Stack<String> num = new Stack<String>(); 104 Stack<String> symbolS = new Stack<String>(); 105 symbolS.push("#"); 106 express += "#"; 107 String order = ""; 108 char ch; 109 int i = 0; 110 ch = express.charAt(i); 111 while ((!symbolS.peek().equals("#")) || (ch != '#')) {// while循环开始 112 if (isNumber(ch)) {// 读到的不是空格,说明开始读运算数 113 String readNumStr = ""; 114 while (true) { 115 readNumStr += ch; 116 ch = express.charAt(++i); 117 if (ch == ' ' || ch == '#' || ch == ')') {// 读到的是空格,或,说明运算数结束 118 break; 119 } 120 } 121 num.push(readNumStr); 122 } else if (ch == ' ') { 123 if ((i + 1) < express.length()) {// 未到字符串末尾 124 ch = express.charAt(++i); 125 } 126 }else {// 读到的是运算符 127 char compare = priorityCompare(symbolS.peek(), ch + ""); 128 129 if (compare == '=') {// 若优先级相等,则说明ch是右括号,栈顶为左括号,此时将栈顶弹出,读取下一个字符 130 symbolS.pop(); 131 ch = express.charAt(++i); 132 } else if (compare == '>') {// ch的优先级小于栈顶的优先级,要说明栈顶的运算符应该先计算,所以应弹栈运算 133 // 弹出两个运算数,弹出一个运算符 134 String bStr = num.pop(); 135 String aStr = num.pop(); 136 String symbolT = symbolS.pop(); 137 // 计算该字表达式 138 String c = yunSuan(aStr, bStr, symbolT); 139 if (c.equals("ERROR")) {// 如果计算函数返回error则说明计算过程出现了负数,说明该运算式不符合要求,停止计算,计算结果为error,返回; 140 this.rightAnswer = "ERROR"; 141 return; 142 } else {// 计算过程正常,则将计算结果压栈 143 order += aStr + "," + symbolT + "," + bStr + ",";// 将运算的子表达式加进运算顺序字符串中,操作数和操作符用逗号隔开 144 num.push(c); 145 } 146 } else if(compare == 'E') 147 { 148 this.rightAnswer = "ERROR"; 149 return; 150 } else {// 说明ch优先级大于栈顶元素的优先级,则应将ch压栈,读取下一个运算符 151 symbolS.push(ch + ""); 152 if ((i + 1) < express.length()) { 153 ch = express.charAt(++i); 154 } 155 } 156 157 } 158 } 159 this.rightAnswer = num.pop(); 160 this.logicOrder = order; 161 } 162 163 // 判断ch是否为数字 164 private boolean isNumber(char ch) { 165 if (ch >= '0' && ch <= '9') { 166 return true; 167 } 168 return false; 169 } 170 171 /* 172 * 子表达式计算,参数为两个运算数的字符串形式,和一个运算符,也为字符串类型 返回计算结果的字符串形式 173 * 如果减法运算出现负数,或除数为0,或分数的分母为0则返回ERROR 174 * 175 */ 176 private String yunSuan(String aStr, String bStr, String symbol) throws MyException { 177 if(aStr == null || bStr == null || symbol == null) 178 { 179 throw new MyException("子表达式出现错误!"); 180 } 181 int adivIndex = aStr.indexOf("/"); 182 int bdivIndex = bStr.indexOf("/"); 183 if ((adivIndex == -1) && (bdivIndex == -1)) {// a.b都是整数 184 int a = Integer.parseInt(aStr); 185 int b = Integer.parseInt(bStr); 186 switch (symbol.charAt(0)) { 187 case '+': 188 return a + b + ""; 189 case '-': { 190 if (a < b) { 191 return "ERROR"; 192 } 193 return a - b + ""; 194 } 195 case '*': { 196 return a * b + ""; 197 } 198 case '/': { 199 if (b == 0) { 200 return "ERROR"; 201 } else if (a % b == 0) { 202 return a / b + ""; 203 } 204 return new FenShu(a, b).toString(); 205 } 206 default: 207 return "ERROR"; 208 } 209 } else {// a,b中存在分数,则将a,b都当做分数进行运算 210 FenShu a = new FenShu(aStr); 211 FenShu b = new FenShu(bStr); 212 switch (symbol.charAt(0)) { 213 case '+': 214 return a.add(b).toString(); 215 case '-': 216 { 217 FenShu c = a.subtract(b); 218 if(c.getNumerator() < 0) 219 { 220 return "ERROR"; 221 } 222 return c.toString(); 223 } 224 case '*': 225 return a.multiply(b).toString(); 226 case '/': 227 return a.divide(b).toString(); 228 default: 229 return "ERROR"; 230 } 231 } 232 } 233 234 // 判断运算符优先级 235 private char priorityCompare(String a, String b) { 236 char[][] priority = { { '>', '>', '<', '<', '<', '>', '>' }, { '>', '>', '<', '<', '<', '>', '>' }, 237 { '>', '>', '>', '>', '<', '>', '>' }, { '>', '>', '>', '>', '<', '>', '>' }, 238 { '<', '<', '<', '<', '<', '=', '>' }, { '>', '>', '>', '>', ' ', '>', '>' }, 239 { '<', '<', '<', '<', '<', ' ', '=' } }; 240 int a_index = index_symbol(a); 241 int b_index = index_symbol(b); 242 if(a_index == -1 || b_index == -1) 243 { 244 return 'E'; 245 } 246 return priority[a_index][b_index]; 247 } 248 249 // 获取运算符对应的下标 250 private int index_symbol(String a) { 251 String p = "+-*/()#"; 252 // System.out.println("判断运算符对应的下标:" + a); 253 return p.indexOf(a); 254 } 255 256 257 }
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>主页</title> 9 10 <script src="js/jquery-2.1.1.min.js"></script> 11 12 13 <script type="text/javascript" src="js/index.js"></script> 14 15 <style type="text/css"> 16 #logo { 17 position: absolute; 18 left: 0px; 19 top: 17px; 20 100%; 21 z-index: 100; 22 } 23 img {z-index: -1;} 24 #logo form h1 { 25 font-style: 楷体; 26 font-size: 39px; 27 color: #C30;} 28 #user{position:absolute;left:5%;top:10px;z-index:200;} 29 #login{position:absolute;left:91%;top:10px;z-index:200;} 30 #logout{position:absolute;left:95%;top:10px;z-index:200;} 31 #wrap {position:absolute;left:0px;top:0px;100%;height:100%} 32 #menu {display: none;text-align: center;} 33 #userInfo {display: none;text-align: center;} 34 #zuoTiInput {display: none;} 35 #selectInput {display: none;text-align: center;} 36 #show {display: none; height: 350px;overflow: auto;} 37 #right {position:absolute;left:50%;top:40px;height:80%;40%} 38 #left { 39 position: absolute; 40 518px; 41 top: 116px; 42 left: 48px; 43 height: 13px; 44 } 45 #zuoTiFuZhu {text-align: center;} 46 #result {text-align: center;} 47 #user { 48 color: #C63; 49 } 50 #user { 51 font-weight: red; 52 } 53 #user { 54 color: #900; 55 } 56 #user { 57 color: #480000; 58 } 59 </style> 60 61 62 </head> 63 <body> 64 <img src="images/43e71da01e24a60e9385f7c63a60e0f2.jpg" width="100%" height="-100%"> 65 <div id="logo"> 66 <form> 67 <center> 68 <h1>小仙女小帅哥答题网</h1> 69 </center> 70 </form> 71 </div> 72 <!-- 73 <div id="loginBT" align="right"> 74 <a href="Login.html"><button>登录</button></a> 75 </div> 76 !--> 77 <div id="login"> 78 <a href="Login.html"><button>登录</button></a> 79 </div> 80 <div id="logout"> 81 <a href="Logoutac"><button>注销</button></a> 82 </div> 83 <div id="user"> 84 您好!${user.username} 85 </div> 86 <div id="wrap"> 87 88 <div id="left"> 89 90 91 <div id="loginMessage"></div> 92 93 94 <!--<div id="userInfo"> 95 用户名:${user.username} 96 <!-- <div id="loginBT" align="right"> 97 <a href="Logoutac"><button id="logout">注销</button></a> 98 </div> !--> 99 100 101 <div id="menu"> 102 <button id="zuoTi">做题</button> 103 <button id="selectLiShiShiTi">查询历史试题</button> 104 </div> 105 106 <div id="zuoTiInput" > 107 108 <table align="center"> 109 <tr><td>试题类型:</td><td><label>整数式<input type="radio" name="type" value="0" checked="checked"></label></td><td><label>真分数式<input type="radio" name="type" value="1"></label></td></tr> 110 <tr><td>有无乘除:</td><td><label>无<input type="radio" name="hasChengChu" value="0" checked="checked"></label></td><td><label>有<input type="radio" name="hasChengChu" value="1"></label></td></tr> 111 <tr><td>有无括号:</td><td><label>无<input type="radio" name="hasKuoHao" value="0" checked="checked"></label></td><td><label>有<input type="radio" name="hasKuoHao" value="1"></label></td></tr> 112 <tr><td>最大值:</td><td colspan="2"><input type="text" name="maxNum" value="10"><span id="maxNumInfo"></span></td></tr> 113 <tr><td>试题个数:</td><td colspan="2"><input type="text" name="num" value="10"><span id="numInfo"></span></td></tr> 114 <tr><td colspan="3"><input type="button" id="zuoTiInputTiJiao" value="我准备好啦"></td></tr> 115 </table> 116 117 </div> 118 119 <div id="selectInput"> 120 <select id="shiJuanList"> 121 122 </select> 123 124 <select id="typeSelect"> 125 <option value="all" selected="selected"> 126 全部 127 </option> 128 129 <option value="right"> 130 正确 131 </option> 132 133 <option value="wrong"> 134 错误 135 </option> 136 137 </select> 138 139 <button id="selectShiJuan"> 140 查询 141 </button> 142 </div> 143 144 145 <div id="show"> 146 <table id="showShiTiTable" align="center" border="1"> 147 148 </table> 149 <div id="zuoTiFuZhu"><button id="jiaoJuanBT">交卷</button><span id="shengYuTime"></span></div> 150 <div id="result"> 151 152 </div> 153 </div> 154 155 </div> 156 </div> 157 </body> 158 </html>