一、记录开发过程中的时间记录日志。
PSP2.1 |
Personal Software Process Stages |
Time |
Planning |
计划 | 48小时 |
Development |
开发 | |
· Analysis |
· 需求分析 (包括学习新技术) |
一个下午+一晚 (32小时) |
· Design Spec |
·生成设计文档 | 2小时 |
·Design Review | ·设计复审(和同事审核设计文档) | 1小时 |
·Coding Standard | ·代码规范(为目前的开发制定合适的规范) | 1小时 |
·Design | ·具体设计 | 2小时 |
·Coding | ·具体编码 | 8小时 |
·Code Review | ·代码复审 | 1小时 |
·Test | ·测试(自我测试、修改代码、提交修改) | 1小时 |
Reporting | 报告 | |
·Test Report | ·测试报告 | 1小时 |
·Size Measurement | ·计算工作量 | 1小时 |
·Postmortem & Precess Improvement Plan | ·事后总结,并提出过程改进计划 | 1小时 |
合计 | 51小时 |
二、程序设计思想
按Bean+Servlet+jsp模式(即MVC模式),首先数据库要建三个表,一个储存用户信息,一个储存题目,一个储存成绩。其余是Java文件,实现对整数,真分数以及混合数的运算。最后写jsp文件,实现网页界面显示。
三、源代码
user.java
1 package model; 2 3 public class User { 4 private String username,pwd; 5 private int qNum,eNum,rNum; 6 7 public User(){} 8 9 public String getUsername() 10 { 11 return username; 12 } 13 public void setUsername(String username) 14 { 15 this.username=username; 16 } 17 18 public String getPwd() 19 { 20 return pwd; 21 } 22 public void setPwd(String pwd) 23 { 24 this.pwd=pwd; 25 } 26 27 public int getQnum() 28 { 29 return qNum; 30 } 31 public void setQnum(int qNum) 32 { 33 this.qNum=qNum; 34 } 35 public int getEnum() 36 { 37 return eNum; 38 } 39 public void setEnum(int eNum) 40 { 41 this.eNum=eNum; 42 } 43 public int getRnum() 44 { 45 return rNum; 46 } 47 public void setRnum(int rNum) 48 { 49 this.rNum=rNum; 50 } 51 }
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 package model; 2 3 import java.util.Date; 4 //----每次做题就生成一个对象记录试题的个数和用户的得分 5 public class Exam { 6 7 private int id,shiTiNum,grade,shiJuanID; 8 private String username,date; 9 10 public Exam(){} 11 12 public int getShiJuanID() { 13 return shiJuanID; 14 } 15 16 public void setShiJuanID(int shiJuanID) { 17 this.shiJuanID = shiJuanID; 18 } 19 20 public int getId() { 21 return id; 22 } 23 24 public void setId(int id) { 25 this.id = id; 26 } 27 28 public int getShiTiNum() { 29 return shiTiNum; 30 } 31 32 public void setShiTiNum(int shiTiNum) { 33 this.shiTiNum = shiTiNum; 34 } 35 36 public int getGrade() { 37 return grade; 38 } 39 40 public void setGrade(int grade) { 41 this.grade = grade; 42 } 43 44 45 46 public String getUsername() { 47 return username; 48 } 49 50 public void setUsername(String username) { 51 this.username = username; 52 } 53 54 public String getDate() { 55 return date; 56 } 57 58 public void setDate(String date) { 59 this.date = date; 60 } 61 62 63 64 }
四、运行结果截图
五、编程总结分析
实现四则运算的程序还是不太好,需要进一步完善;
页面需要进一步整理,较简单。