Java博客作业(三)
一、前言
题目集七
知识点:菜单计价系统
题量:少
难度:较难
题目集八
知识点:课程成绩统计、使用comparable接口处理信息排序、ArrayList的使用、正则表达式
题量:中等
难度:较难
题目集九
知识点:统计Java程序中关键词出现次数、HashMap、HashSet、Matcher、Pattern、treeMap。
题量:少
难度:较难
题目集十
知识点:HashMap-检索、HashMap-排序、多态、课程成绩统计系统
题量:一般
难度:较难
题目集十一
知识点:ArrayList-排序、Comparable接口、Stack、面向对象基础-覆盖
题量:一般
难度:较难
二、设计与分析 与 踩坑心得
题目集七
菜单计价程序-5
又是菜单计价程序题的迭代,不过此次题目并非是菜单-4的迭代,而是菜单-3的另一个迭代分支,这也意味着此次难度并不会比上次大。此次题目主要对特色菜进行了川菜、晋菜、浙菜的区分,并且增加了口味度。在输入信息方面,除添加的口味度信息外,为了考虑客户订多桌菜的情况,输入桌号时,还将增加用户的信息,如用户姓名、电话号码。在输出方面,要求先按要求输出每一桌的信息,最后按字母顺序依次输出每位客户需要支付的金额。
我新建了Costomr类,里面主要有三个参数:name用户姓名、telnum用户电话号码、sumprice用户订单总价.
以及两个方法:Setcustomer(String name, String telnum,int sumprice)用来添加用户信息、paixu()对用户信息进行排序(按用户名字字母顺序)。相应代码如下:

1 public void Setcustomer(String name, String telnum,int sumprice) { 2 if(i==0) {//保存第一位用户 3 this.name[i] = name; 4 this.telnum[i] = telnum; 5 this.sumprice[i] = sumprice; 6 i++; 7 } 8 else {// 9 for(j=0; j<i ;j++) { 10 if(this.name[j].equals(name)) {//同一个用户 11 this.sumprice[j] += sumprice;//更改用户支付总价 12 k = 0; 13 } 14 } 15 if(k == 1){//新用户 16 this.name[i] = name; 17 this.telnum[i] = telnum; 18 this.sumprice[i] = sumprice; 19 i++; 20 } 21 } 22 }

1 public void paixu() { 2 int n = 0; 3 int m = 0; 4 String temp = ""; 5 int t = 0; 6 for(n=0;n<i-1;n++) { 7 for(m=n;m<i-1;m++) { 8 if(this.name[m].charAt(0)>this.name[m+1].charAt(0)) { 9 temp=name[m]; 10 name[m]=name[m+1]; 11 name[m+1]=temp; 12 temp=telnum[m]; 13 telnum[m]=telnum[m+1]; 14 telnum[m+1]=temp; 15 t=sumprice[m]; 16 sumprice[m]=sumprice[m+1]; 17 sumprice[m+1]=t; 18 } 19 } 20 } 21 }
Dish类中新增了type属性,用来区分菜品是否是特色菜以及特色菜类型(普通菜为“普通”,特色菜为“川菜”、“晋菜”、“浙菜”)。
Order类中新增avspicy、avsour、avsweet等属性用来表示订单平均口味度值。word(String type)方法用于判定口味度值对应的口味度。相应代码如下:

1 public String word(String type) { 2 if(type.equals("川菜")) { 3 int n = (int)Math.round(avspicy); 4 switch(n) { 5 case 0: return "不辣"; 6 case 1: return "微辣"; 7 case 2: return "稍辣"; 8 case 3: return "辣"; 9 case 4: return "很辣"; 10 case 5: return "爆辣"; 11 } 12 } 13 else if(type.equals("晋菜")) { 14 int n = (int)Math.round(avsour); 15 switch(n) { 16 case 0: return "不酸"; 17 case 1: return "微酸"; 18 case 2: return "稍酸"; 19 case 3: return "酸"; 20 case 4: return "很酸"; 21 } 22 } 23 else if(type.equals("浙菜")) { 24 int n = (int)Math.round(avsweet); 25 switch(n) { 26 case 0: return "不甜"; 27 case 1: return "微甜"; 28 case 2: return "稍甜"; 29 case 3: return "甜"; 30 } 31 } 32 return null; 33 }
至于代码主体部分,依旧是沿用之前的方法,使用while()循环处理每一行数据,对每行字符串个数count进行 if 判定,如count==4时,为向菜单中添加特色菜品信息或点单且菜品为普通菜,之后再在内部不断细化。
本次题目整体难度其实并不高,相比菜单4其实更好拿分,并且有了前几次的经验,理解题意并付诸实践会更加容易,稍微令人头痛的不是基本的逻辑关系了,更多的是规定的输出形式,如对空格以及特定地区换行和wrong format等异常情况的处理。
本题完整代码如下:

1 import java.util.Scanner; 2 import java.time.LocalDate; 3 import java.time.temporal.ChronoUnit; 4 5 public class Main { 6 public static void main(String[] args) { 7 // TODO Auto-generated method stub 8 Scanner sc = new Scanner(System.in); 9 Menu menu = new Menu(); 10 Table[] tablemes = new Table[10]; 11 String dishName; //dishName为用户输入的菜名 12 String[] temp; 13 int orderNum=0, delete_Num, portion, amount, delete_Price = 0; 14 int i=0,j=0; 15 int tablenum=0; 16 int onum = 0; 17 int dengji = 0; 18 String type = "普通"; 19 Dish dish; 20 while (true) { 21 String st = sc.nextLine(); 22 temp = st.split(" "); 23 if(st.equals("end")) 24 break; 25 int count = temp.length; 26 if (count == 2) { 27 if (temp[1].equals("delete")) {//第二个为delete 28 onum = Integer.parseInt(temp[0]); 29 int c = tablemes[tablenum].torder.delARecordByOrderNum(onum); 30 //有删除菜品记录,则将此记录菜品价格赋给c,没有则输出"delete error;" 31 if(tablemes[tablenum].torder.findRecordByNum(onum)!=null) {//删除的菜品记录存在 32 if(tablemes[tablenum].torder.findRecordByNum(onum).d.type.equals("普通")) {//删除菜品为普通菜 33 tablemes[tablenum].sumprice -= c; 34 tablemes[tablenum].disprice -= Math.round( c*tablemes[tablenum].discount); 35 } 36 else {//删除菜品为特色菜 37 tablemes[tablenum].sumTprice -= c; 38 tablemes[tablenum].disprice -= Math.round( c*tablemes[tablenum].Tdiscount); 39 if(tablemes[tablenum].torder.findRecordByNum(onum).d.type.equals("川菜")) { 40 tablemes[tablenum].torder.avspicy = 41 (tablemes[tablenum].torder.avspicy * tablemes[tablenum].torder.chuancai - 42 tablemes[tablenum].torder.findRecordByNum(onum).dengji * tablemes[tablenum].torder.findRecordByNum(onum).amount) / 43 (tablemes[tablenum].torder.chuancai - tablemes[tablenum].torder.findRecordByNum(onum).amount); 44 tablemes[tablenum].torder.chuancai -= tablemes[tablenum].torder.findRecordByNum(onum).amount; 45 } 46 else if(tablemes[tablenum].torder.findRecordByNum(onum).d.type.equals("晋菜")) { 47 tablemes[tablenum].torder.avsour = 48 (tablemes[tablenum].torder.avsour * tablemes[tablenum].torder.jincai - 49 tablemes[tablenum].torder.findRecordByNum(onum).dengji * tablemes[tablenum].torder.findRecordByNum(onum).amount) / 50 (tablemes[tablenum].torder.jincai - tablemes[tablenum].torder.findRecordByNum(onum).amount); 51 tablemes[tablenum].torder.jincai -= tablemes[tablenum].torder.findRecordByNum(onum).amount; 52 } 53 else if(tablemes[tablenum].torder.findRecordByNum(onum).d.type.equals("浙菜")) { 54 tablemes[tablenum].torder.avsweet = 55 (tablemes[tablenum].torder.avsweet * tablemes[tablenum].torder.zhecai - 56 tablemes[tablenum].torder.findRecordByNum(onum).dengji * tablemes[tablenum].torder.findRecordByNum(onum).amount) / 57 (tablemes[tablenum].torder.zhecai - tablemes[tablenum].torder.findRecordByNum(onum).amount); 58 tablemes[tablenum].torder.zhecai -= tablemes[tablenum].torder.findRecordByNum(onum).amount; 59 } 60 } 61 } 62 63 } 64 else {//普通菜增加 65 menu.addDish(temp[0], Integer.parseInt(temp[1]),"普通"); 66 } 67 } 68 69 else if (count == 4) { 70 if(temp[3].equals("T")) {//特色菜增加 71 menu.addDish(temp[0], Integer.parseInt(temp[2]), temp[1]); 72 } 73 else { 74 //普通菜点单//增加订单的情况; 75 onum =Integer.parseInt(temp[0]); 76 dishName =temp[1]; 77 portion = Integer.parseInt(temp[2]); 78 amount = Integer.parseInt(temp[3]); 79 tablemes[tablenum].torder.addARecord(onum,dishName,-1,portion,amount,"普通"); 80 dish = menu.searchDish(dishName); 81 if (dish != null) { 82 tablemes[tablenum].torder.records[orderNum].d = dish; 83 int a = tablemes[tablenum].torder.records[orderNum].getPrice(); 84 if(tablemes[tablenum].discount>0) 85 System.out.println(tablemes[tablenum].torder.records[orderNum].orderNum + " " + dish.name + " " +a ); 86 tablemes[tablenum].sumprice +=a; 87 tablemes[tablenum].disprice += Math.round( a*tablemes[tablenum].discount); 88 } 89 orderNum++; 90 } 91 } 92 93 else if(count == 5){//特色菜点单//增加订单 94 onum =Integer.parseInt(temp[0]); 95 dishName =temp[1]; 96 dengji = Integer.parseInt(temp[2]); 97 portion = Integer.parseInt(temp[3]); 98 amount = Integer.parseInt(temp[4]); 99 dish = menu.searchDish(dishName); 100 type = dish.type; 101 if(!dish.validengji(type, dengji)) { // type的辣度等级不合法 102 if(type.equals("川菜")) { 103 System.out.println("spicy num out of range :"+dengji); 104 } 105 else if(type.equals("晋菜")) { 106 System.out.println("acidity num out of range :"+dengji); 107 } 108 else if(type.equals("浙菜")) { 109 System.out.println("sweetness num out of range :"+dengji); 110 } 111 } 112 else { 113 tablemes[tablenum].torder.addARecord(onum,dishName,dengji,portion,amount,type); 114 type = "普通"; 115 dish = menu.searchDish(dishName); 116 if (dish != null) { 117 tablemes[tablenum].torder.records[orderNum].d = dish; 118 int a = tablemes[tablenum].torder.records[orderNum].getPrice(); 119 if(tablemes[tablenum].discount>0) 120 System.out.println(tablemes[tablenum].torder.records[orderNum].orderNum + " " + dish.name + " " +a ); 121 tablemes[tablenum].sumTprice += a; 122 tablemes[tablenum].disprice += Math.round( a*tablemes[tablenum].Tdiscount); 123 } 124 orderNum++; 125 } 126 } 127 128 else if(count == 6) {//代点特色菜 129 onum =Integer.parseInt(temp[0]); 130 int daitable = Integer.parseInt(temp[1]); 131 dishName =temp[2]; 132 dengji = Integer.parseInt(temp[3]); 133 portion = Integer.parseInt(temp[4]); 134 amount = Integer.parseInt(temp[5]); 135 dish = menu.searchDish(dishName); 136 type = dish.type; 137 tablemes[daitable].torder.addARecord(onum,dishName,dengji,portion,amount,type); 138 type = "普通"; 139 dish = menu.searchDish(dishName); 140 if (dish != null) { 141 tablemes[daitable].torder.records[orderNum].d = dish; 142 int a = tablemes[daitable].torder.records[orderNum].getPrice() * amount; 143 if(tablemes[daitable].discount>0) 144 System.out.println(tablemes[daitable].torder.records[orderNum].orderNum + " table " +tablenum+" pay for table "+daitable+ " " +a ); 145 tablemes[tablenum].sumTprice += a; 146 tablemes[tablenum].disprice += Math.round( a*tablemes[tablenum].Tdiscount); 147 } 148 } 149 150 else if (count == 7) {//三个空格 ///桌子信息 151 if (temp[0].equals("table")) {//桌号 152 tablenum++;//跳过0; 153 orderNum = 0; 154 tablemes[tablenum] = new Table(tablenum,temp[3],temp[4]); 155 tablemes[tablenum].time.setTenDate(temp[5]); 156 tablemes[tablenum].time.setTenTime(temp[6]); 157 tablemes[tablenum].discount(tablemes[tablenum].time.getTimeofDay(), tablemes[tablenum].time.getDayOfWeek()); 158 tablemes[tablenum].Tdiscount(tablemes[tablenum].time.getDayOfWeek()); 159 if(tablemes[tablenum].discount>0) 160 System.out.println("table " + tablenum + ": "); 161 } 162 } 163 else { 164 System.out.println("wrong format"); 165 System.exit(0); 166 } 167 168 } 169 for (i = 1; i <= tablenum; i++) { 170 if(tablemes[i].Gettottalprice()==0)//输出价格等信息 171 System.exit(0); 172 //输出 川菜+份数+辣度 等等等等等信息.............. 173 if(tablemes[i].discount>0) { 174 if(tablemes[i].torder.chuancai != 0) { 175 System.out.print("川菜 "+tablemes[i].torder.chuancai+" "+tablemes[i].torder.word("川菜")); 176 } 177 if(tablemes[i].torder.jincai != 0) { 178 if(tablemes[i].torder.chuancai != 0) { 179 System.out.print(" 晋菜 "+tablemes[i].torder.jincai+" "+tablemes[i].torder.word("晋菜")); 180 } 181 else System.out.print("晋菜 "+tablemes[i].torder.jincai+" "+tablemes[i].torder.word("晋菜")); 182 } 183 if(tablemes[i].torder.zhecai != 0) { 184 if(tablemes[i].torder.chuancai != 0 || tablemes[i].torder.jincai != 0) { 185 System.out.println(" 浙菜 "+tablemes[i].torder.zhecai+" "+tablemes[i].torder.word("浙菜")); 186 } 187 else System.out.println("浙菜 "+tablemes[i].torder.zhecai+" "+tablemes[i].torder.word("浙菜")); 188 } 189 else System.out.printf("\n"); 190 } 191 else System.out.printf("\n"); 192 } 193 j=0; 194 Customer customer = new Customer(); 195 for(i = 1; i<=tablenum; i++) { 196 customer.Setcustomer(tablemes[i].name,tablemes[i].telnum,tablemes[i].disprice); 197 } 198 customer.paixu(); 199 for(i = 0;i<30;i++) { 200 // System.out.println(customer.name[i]); 201 if(customer.name[i]!=null) { 202 System.out.println(customer.name[i]+" "+customer.telnum[i]+" "+customer.sumprice[i]); 203 } 204 } 205 } 206 } 207 208 class Customer{ 209 String[] name = new String[30]; 210 String[] telnum = new String[30]; 211 int[] sumprice = new int[30]; 212 int i = 0;//保存用户个数 213 int j = 0; 214 int k = 1;//k=0时,用户重复;k=1时,新名字 215 public void Setcustomer(String name, String telnum,int sumprice) { 216 if(i==0) {//保存第一位用户 217 this.name[i] = name; 218 this.telnum[i] = telnum; 219 this.sumprice[i] = sumprice; 220 i++; 221 } 222 else {// 223 for(j=0; j<i ;j++) { 224 if(this.name[j].equals(name)) {//同一个用户 225 this.sumprice[j] += sumprice;//更改用户支付总价 226 k = 0; 227 } 228 } 229 if(k == 1){//新用户 230 this.name[i] = name; 231 this.telnum[i] = telnum; 232 this.sumprice[i] = sumprice; 233 i++; 234 } 235 } 236 } 237 238 public void paixu() { 239 int n = 0; 240 int m = 0; 241 String temp = ""; 242 int t = 0; 243 for(n=0;n<i-1;n++) { 244 for(m=n;m<i-1;m++) { 245 if(this.name[m].charAt(0)>this.name[m+1].charAt(0)) { 246 temp=name[m]; 247 name[m]=name[m+1]; 248 name[m+1]=temp; 249 temp=telnum[m]; 250 telnum[m]=telnum[m+1]; 251 telnum[m+1]=temp; 252 t=sumprice[m]; 253 sumprice[m]=sumprice[m+1]; 254 sumprice[m+1]=t; 255 } 256 } 257 } 258 } 259 } 260 261 262 263 class Dish {//菜品类:对应菜谱上一道菜的信息。 264 String name = "";//菜品名称 265 int unit_price;//单价 266 String type = "普通";// 267 268 public Dish() { 269 super(); 270 // TODO Auto-generated constructor stub 271 } 272 273 public Dish(String name, int unit_price, String type) { 274 super(); 275 this.name = name; 276 this.unit_price = unit_price; 277 this.type = type; 278 } 279 280 public Dish(String name, int unit_price) { 281 super(); 282 this.name = name; 283 this.unit_price = unit_price; 284 } 285 286 public void resetDish(String name, int unit_price, String type) { 287 this.name = name; 288 this.unit_price = unit_price; 289 this.type = type; 290 } 291 292 public int getPrice(int portion) { 293 //计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) 294 int price = 0; 295 if(portion == 1) { 296 price = unit_price; 297 } 298 else if(portion == 2) { 299 price = (int)(unit_price * 1.5 + 0.5); 300 } 301 else if(portion == 3) { 302 price = (int)(unit_price * 2 + 0.5); 303 } 304 else System.out.println("portion out of range " + portion); 305 return price; 306 } 307 public boolean validengji(String type, int dengji) { 308 if(type.equals("川菜")&&dengji>=0&&dengji<=5) { 309 return true; 310 } 311 else if(type.equals("晋菜")&&dengji>=0&&dengji<=4){ 312 return true; 313 } 314 else if(type.equals("浙菜")&&dengji>=0&&dengji<=3){ 315 return true; 316 } 317 return false; 318 } 319 } 320 321 class Menu {//菜谱类:对应菜谱,包含饭店提供的所有菜的信息。 322 Dish[] dishs = new Dish[30];//普通菜品数组,保存所有非特价菜菜品信息 323 static int i = 0;//dish个数 324 public Dish searchDish(String dishName){ 325 //根据菜名在菜谱中查找菜品信息,返回Dish对象. 326 int j = 0; 327 for(j=0;j<i;j++) { 328 if(dishs[j]==null) 329 System.out.println(dishName+" does not exist"); 330 if(dishs[j].name.equals(dishName)) { 331 return dishs[j];//找到菜 332 } 333 } 334 System.out.println(dishName+" does not exist"); 335 return null;//没找到,返回空 336 } 337 338 public void addDish(String dishName,int unit_price,String type){ 339 //添加一道菜品信息 340 int m = 0; 341 for(int j = 0; j<i ;j++) { 342 if(dishs[j].name.equals(dishName)) { 343 dishs[j].resetDish(dishName, unit_price, type); 344 m++; 345 } 346 } 347 if(m==0) { 348 dishs[i] = new Dish(dishName, unit_price, type); 349 i++; 350 } 351 352 } 353 } 354 355 class Order {//订单类:保存用户点的所有菜的信息。 356 Record[] records = new Record[30];//保存订单上每一道的记录 357 int k = 0;//records数组的元素个数 358 //平均 口味(辣/酸/甜)度 359 double avspicy = 0; 360 double avsour = 0; 361 double avsweet = 0; 362 int chuancai = 0; 363 int jincai = 0; 364 int zhecai = 0; 365 public Order() { 366 super(); 367 // TODO Auto-generated constructor stub 368 } 369 public Order(Record[] records) { 370 super(); 371 this.records = records; 372 } 373 public Record[] getRecords() { 374 return records; 375 } 376 public void setRecords(Record[] records) { 377 this.records = records; 378 } 379 380 public int getTotalPrice() { 381 //计算订单的总价 382 int i = 0; 383 int sum = 0; 384 for(i=0;i<records.length;i++) { 385 sum += records[i].getPrice(); 386 } 387 return sum; 388 } 389 390 public String word(String type) { 391 if(type.equals("川菜")) { 392 int n = (int)Math.round(avspicy); 393 switch(n) { 394 case 0: return "不辣"; 395 case 1: return "微辣"; 396 case 2: return "稍辣"; 397 case 3: return "辣"; 398 case 4: return "很辣"; 399 case 5: return "爆辣"; 400 } 401 } 402 else if(type.equals("晋菜")) { 403 int n = (int)Math.round(avsour); 404 switch(n) { 405 case 0: return "不酸"; 406 case 1: return "微酸"; 407 case 2: return "稍酸"; 408 case 3: return "酸"; 409 case 4: return "很酸"; 410 } 411 } 412 else if(type.equals("浙菜")) { 413 int n = (int)Math.round(avsweet); 414 switch(n) { 415 case 0: return "不甜"; 416 case 1: return "微甜"; 417 case 2: return "稍甜"; 418 case 3: return "甜"; 419 } 420 } 421 return null; 422 } 423 424 public void addARecord(int orderNum,String dishName,int dengji,int portion,int amount, String type){ 425 //添加一条菜品信息到订单中。 426 records[k] = new Record(); 427 records[k].d.name=dishName; 428 records[k].orderNum=orderNum; 429 records[k].dengji=dengji; 430 records[k].portion=portion; 431 records[k].amount=amount; 432 k++; 433 if(type.equals("川菜")) { 434 if(avspicy == 0) { 435 avspicy = dengji; 436 chuancai = chuancai + amount ; 437 } 438 else { 439 avspicy = (dengji*amount + avspicy * chuancai)/(amount+chuancai); 440 chuancai = chuancai + amount; 441 } 442 } 443 else if(type.equals("晋菜")) { 444 if(avsour == 0) { 445 avsour =dengji; 446 jincai = jincai + amount ; 447 } 448 else { 449 avsour = (dengji*amount + avsour * jincai)/(amount + jincai); 450 jincai = jincai + amount; 451 } 452 } 453 else if(type.equals("浙菜")){ 454 if(avsweet == 0) { 455 avsweet =dengji; 456 zhecai = zhecai + amount ; 457 } 458 else { 459 avsweet = (dengji*amount + avsweet * zhecai)/(amount + zhecai); 460 zhecai = zhecai + amount; 461 } 462 463 } 464 } 465 466 public int delARecordByOrderNum(int orderNum){ 467 //根据序号删除一条记录 468 for(int i = 0; i < k; i++) 469 if(records[i].orderNum == orderNum) 470 return records[i].getPrice(); 471 System.out.println("delete error;"); 472 return 0; 473 } 474 475 476 public Record findRecordByNum(int orderNum){ 477 //根据序号查找一条记录 478 int j = 0; 479 for(j=0;j<k;j++) { 480 if(records[j].orderNum==orderNum) { 481 return records[j]; 482 } 483 } 484 return null;//没找到,返回空 485 } 486 } 487 488 class Record {//点菜记录类:保存订单上的一道菜品记录 489 int orderNum = 0;//序号 490 Dish d = new Dish(" ",0);//菜品 491 int dengji = 0; //辣度/酸度/甜度 492 int portion = 1; //份额(1/2/3代表小/中/大份) 493 int amount = 1; //菜品数量 494 public int getPrice(){ 495 //计价,计算本条记录的价格 496 return d.getPrice(portion)*amount; 497 } 498 499 public void setOrderNum(int orderNum) { 500 this.orderNum = orderNum; 501 } 502 public void setD(Dish d) { 503 this.d = d; 504 } 505 public void setPortion(int portion) { 506 this.portion = portion; 507 } 508 public void setAmount(int amount) { 509 this.amount = amount; 510 } 511 512 } 513 514 class Table { 515 int tableNum = 0;//桌号 516 int sumprice = 0;//一桌价格原价 517 int sumTprice = 0; 518 int disprice = 0;//一桌折扣价 519 float discount = -1; 520 float Tdiscount = -1; 521 String name = "";//名字 522 String telnum = "";//电话号码 523 Order torder = new Order(); 524 Time time = new Time(); 525 526 public Table(int tableNum,String name,String telnum) { 527 this.tableNum=tableNum; 528 this.name = name; 529 this.telnum = telnum; 530 } 531 int Gettottalprice(){ 532 if(discount>0){ 533 System.out.print("table " + tableNum + ": " + (sumprice+sumTprice) +" "+ disprice + " "); 534 return 1; 535 }else { 536 System.out.println("table " + tableNum + " out of opening hours"); 537 return 0; 538 } 539 } 540 void discount(int timeofday,int dayofweek){ 541 if((timeofday>=10.5*3600&&timeofday<=14.5*3600)&&(dayofweek>=1&&dayofweek<=5)) 542 discount =0.6F; 543 else if((timeofday>=17*3600&&timeofday<=20.5*3600)&&(dayofweek>=1&&dayofweek<=5)) 544 discount =0.8F; 545 else if((timeofday>=9.5*3600&&timeofday<=21.5*3600)&&(dayofweek==6||dayofweek==7)) 546 discount =1.0F; 547 } 548 void Tdiscount(int dayofweek){ 549 if(dayofweek>=1&&dayofweek<=5) 550 Tdiscount =0.7F; 551 else if(dayofweek==6||dayofweek==7) 552 Tdiscount =1.0F; 553 } 554 } 555 556 557 class Time { 558 int [] TenTime; 559 int [] TenDate; 560 public void setTenDate(String DATE) { 561 String[] strings=DATE.split("/");//字符型 562 int[] TenDate=new int [3]; 563 for(int i=0;i<3;i++) 564 TenDate[i]=Integer.parseInt(strings[i]);//Int 565 this.TenDate = TenDate; 566 } 567 public void setTenTime(String TIME) { 568 String[] strings=TIME.split("/");//字符型 569 int[] TenTime=new int [3]; 570 for(int i=0;i<3;i++) 571 TenTime[i]=Integer.parseInt(strings[i]);//Int 572 this.TenTime = TenTime; 573 } 574 public int[] getTenTime() { 575 return TenTime; 576 } 577 public int[] getTenDate() { 578 return TenDate; 579 } 580 public int getDayOfWeek(){// 获取周第几天 581 LocalDate date = LocalDate.of(TenDate[0],TenDate[1],TenDate[2]);//LocalDate 582 return (date.getDayOfWeek().getValue());//调用LocalDate类中的getDayOfWeek方法,获取周第几天 583 } 584 585 public int getTimeofDay(){ 586 int tentime; 587 tentime=TenTime[0]*3600+TenTime[1]*60+TenTime[2]; 588 return tentime; 589 } 590 591 }
题目集八
课程成绩统计程序-1
题目信息如下:

7-1 课程成绩统计程序-1 分数 100 作者 蔡轲 单位 南昌航空大学 某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。 考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。 考察的总成绩直接等于期末成绩 必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。 1、输入: 包括课程、课程成绩两类信息。 课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。 课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式 课程性质输入项:必修、选修 考核方式输入选项:考试、考察 课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩 课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩 以上信息的相关约束: 1)平时成绩和期末成绩的权重默认为0.3、0.7 2)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】 3)学号由8位数字组成 4)姓名不超过10个字符 5)课程名称不超过10个字符 6)不特别输入班级信息,班级号是学号的前6位。 2、输出: 输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。 为避免误差,平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。 1)学生课程总成绩平均分按学号由低到高排序输出 格式:学号+英文空格+姓名+英文空格+总成绩平均分 如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams" 2)单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出 格式:课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分 如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet" 3)班级所有课程总成绩平均分按班级由低到高排序输出 格式:班级号+英文空格+总成绩平均分 如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet" 异常情况: 1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist" 2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch" 以上两种情况如果同时出现,按第一种情况输出结果。 3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch" 4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format" 5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。 信息约束: 1)成绩平均分只取整数部分,小数部分丢弃 参考类图: image.png 输入样例1: 仅有课程。例如: java 必修 考试 数据结构 选修 考试 形式与政治 选修 考察 end 输出样例1: 在这里给出相应的输出。例如: java has no grades yet 数据结构 has no grades yet 形式与政治 has no grades yet 输入样例2: 单门考试课程 单个学生。例如: java 必修 考试 20201103 张三 java 20 40 end 输出样例2: 在这里给出相应的输出。例如: 20201103 张三 34 java 20 40 34 202011 34 输入样例3: 单门考察课程 单个学生。例如: java 选修 考察 20201103 张三 java 40 end 输出样例3: 在这里给出相应的输出。例如: 20201103 张三 40 java 40 40 202011 40 输入样例4: 考试课程 单个学生 不匹配的考核方式。例如: java 必修 考试 20201103 张三 java 20 end 输出样例4: 在这里给出相应的输出。例如: 20201103 张三 : access mode mismatch 20201103 张三 did not take any exams java has no grades yet 202011 has no grades yet 输入样例5: 单门课程,单个学生,课程类型与考核类型不匹配。例如: java 必修 考察 20201103 张三 java 40 end 输出样例5: 在这里给出相应的输出。例如: java : course type & access mode mismatch java does not exist 20201103 张三 did not take any exams 202011 has no grades yet 输入样例6: 单门课程,多个学生。例如: java 选修 考察 20201103 李四 java 60 20201104 王五 java 60 20201101 张三 java 40 end 输出样例6: 在这里给出相应的输出。例如: 20201101 张三 40 20201103 李四 60 20201104 王五 60 java 53 53 202011 53 输入样例7: 单门课程,单个学生,课程类型与考核类型不匹配。例如: 形式与政治 必修 考试 数据库 选修 考试 java 选修 考察 数据结构 选修 考察 20201103 李四 数据结构 70 20201103 李四 形式与政治 80 90 20201103 李四 java 60 20201103 李四 数据库 70 78 end 输出样例7: 在这里给出相应的输出。例如: 20201103 李四 73 java 60 60 数据结构 70 70 数据库 70 78 75 形式与政治 80 90 87 202011 73 输入样例8: 单门课程,单个学生,成绩越界。例如: 数据结构 选修 考察 20201103 李四 数据结构 101 end 输出样例8: 在这里给出相应的输出。例如: wrong format 数据结构 has no grades yet 输入样例9: 多门课程,多个学生,多个成绩。例如: 形式与政治 必修 考试 数据库 选修 考试 java 选修 考察 数据结构 选修 考察 20201205 李四 数据结构 70 20201103 李四 形式与政治 80 90 20201102 王五 java 60 20201211 张三 数据库 70 78 end 输出样例9: 在这里给出相应的输出。例如: 20201102 王五 60 20201103 李四 87 20201205 李四 70 20201211 张三 75 java 60 60 数据结构 70 70 数据库 70 78 75 形式与政治 80 90 87 202011 73 202012 72
首先阅读题干,分析题目需求,提取关键信息,这道题目给出了一个学校课程成绩的管理系统,题目包含以下几个部分:
-
输入部分:包括课程和课程成绩两类信息。 课程信息包括课程名称、课程性质、考核方式三项,成绩信息包括学号、姓名、课程名称、平时成绩、期末成绩五项。 学校课程从性质上分为必修课和选修课,从考核方式上分为考试和考察。 成绩由平时成绩和期末成绩计算得出。
-
输出部分:包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。 需要遍历所有的学生和课程信息,并按照要求输出所需的统计信息。
-
异常情况:
a.解析某个成绩信息时,课程名称不在已输入的课程列表中:输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"
b.解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配:输出:学号+英文空格+姓名+英文空格+": access mode mismatch"
c.解析某个课程信息时,输入的课程性质和课程的考核方式不匹配:输出:课程名称+" : course type & access mode mismatch"
d.格式错误或其他信息:输出:"wrong format"
e.如果出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。
1. 首先需要从输入中获取课程信息,对于每个课程信息,需要进行以下操作:
a. 验证课程性质和考核方式是否匹配,如果不匹配,则直接输出错误信息并跳过该课程的信息。
b. 将课程信息加入到课程列表中。
2. 接下来需要从输入中获取成绩信息,对于每个成绩信息,需要进行以下操作:
a. 验证课程是否存在于课程列表中,如果不存在,则输出错误信息并跳过该成绩信息。
b. 验证成绩数量和课程的考核方式是否匹配,如果不匹配,则输出错误信息并跳过该成绩信息。
c. 对于考试和考察成绩信息,计算总成绩,对于实验成绩信息,计算平均成绩,将成绩信息加入到对应的学生、课程和班级的成绩列表中。
3. 遍历学生的成绩列表,计算每个学生的总成绩平均分,并将结果排序后输出。
4. 遍历课程列表,计算每个课程的平时成绩平均分、期末考试平均分和总成绩平均分,并将结果按照课程名称排序后输出。
5. 遍历班级的成绩列表,计算每个班级的总成绩平均分,并将结果排序后输出。
在实现编程时,我遇到以下问题:
1. 难以确定如何处理输入的数据:
输入数据需要进行解析和验证,而解析和验证的方式可能会影响程序的设计。例如,对于成绩信息的处理,需要对平时成绩和期末成绩进行权重计算,还需要根据考核方式进行不同的计算,这会增加程序的复杂度。
2. 难以处理输入数据中的错误和异常情况:
输入数据中存在各种错误和异常情况,例如,成绩超出范围、输入格式错误、成绩数量和考核方式不匹配等,这些情况都需要程序进行正确处理。在编写程序时需要考虑各种异常情况,并进行充分的测试和验证,以确保程序的正确性。
3. 如何进行数据的存储和计算:
程序需要对成绩数据进行存储和计算,并最终输出成绩统计数据。在存储和计算时,需要考虑哪些数据结构和算法最适合当前的问题,以及数据结构和算法的复杂度如何等因素。
4. 如何进行输出格式的控制:
程序需要按照指定的输出格式输出成绩统计数据,包括学生的总成绩平均分、单门课程的平时成绩平均分、期末考试平均分和总成绩平均分、班级的总成绩平均分等信息。输出格式的控制需要考虑各种细节问题,如空格、排序、小数点等,需要根据具体的规则进行设置。
5. 如何进行程序的测试和评估:
在完成程序编写后,我需要排查程序漏洞以通过各个测试点,但是我很难做到这一点,我没有充分的样例,需要自己琢磨出现的错误,自己写测试样例并尽可能覆盖更多的测试点。
总之,在编写程序时需要仔细考虑各种问题,并进行充分的测试和评估,以确保程序的正确性、健壮性和可扩展性。

1 if(count == 3 || (count==2&&temp[1].equals("必修"))){//添加课程信息 2 if(count == 3){ 3 if(temp[1].matches("^[\\w\\W]{1,10}$") ){//课程名 4 choose.addCourse(new Course(temp[0],temp[1],temp[2])); 5 } 6 else System.out.println("wrong format"); 7 } 8 else { 9 if(temp[1].matches("^[\\w\\W]{1,10}$") ){//课程名 10 choose.addCourse(new Course(temp[0],temp[1],"考试")); 11 } 12 else System.out.println("wrong format"); 13 } 14 }
同理,便可以处理其他数据信息。由于录入的信息有格式要求,为方便起见统一使用正则表达式进行数据的合法性判断,具体如下:

1 if(count == 5){ 2 if(temp[3].matches("^([1-9]\\d?|100|0)$")&&temp[4].matches("^([1-9]\\d?|100|0)$")//分数 3 &&temp[0].matches("\\d{8}")//ID 4 &&temp[1].matches("^[\\w\\W]{1,10}$") &&temp[2].matches("^[\\w\\W]{1,10}$"))//姓名与课程名 5 { 6 choose.addScore(new Score(st)); 7 } 8 else System.out.println("wrong format"); 9 }
只有数据合法时,才会录入课程成绩信息。
对于信息的录入,首先在主方法中创建Choose类对象,
Choose类中具有以下属性:
private ArrayList<Score> scores = new ArrayList<>();
private ArrayList<Student> students = new ArrayList<>();
public ArrayList<Classroom> classrooms = new ArrayList<>();
分别用来存放不同类型的数据
Choose类中具有方法
对于addCourse方法,首先需要判断想要添加的course对象是否合法(课程性质与考核形式不冲突,如必修课的考核形式一定是考试),之后要判断是否存在课程重名的情况,如果想要添加的course对象已经存在于choose类的存放course的list中,则不添重复加此课程。反之,添加进courses链中。
对于addScore方法,于addCourse方法类似,不过由于课程成绩信息牵涉到的信息过多(学生信息、课程成绩、班级等)因此,需要具备更复杂的逻辑关系将各个数据进行存储处理。如需要判断班级是否是新的班级,若不是,需要将学生信息添加到已经存在的班级中;需要判断学生是否是新学生,若不是,需要将成绩信息存在此学生之前创建的对象中,而不是新建一个对象;以及需要判断课程是否存在,不存在时需要输出异常语句,但此条信息中的学生信息、班级信息依旧需要录入,只不过没有成绩。
之后要对处理后的信息进行输出,Choose类中有如下方法:
由于输出有排序限制:学生课程总成绩平均分按学号从低到高排序输出、单门课程成绩按课程名称的字符顺序输出、班级成绩信息按班级由低到高顺序输出。
因此需要在遍历数据信息输出前,将存储的数据进行排序。在Choose类中编写了sortStu、sortCla方法将信息进行排序。为了单门课程成绩按字符顺序输出,我在Course类实现Compara接口,并重写compareTo方法,如下:
public int compareTo(Course o) {
Comparator<Object> c = Collator.getInstance(Locale.CHINA);
return ((Collator) c).compare(this.courseName,o.courseName);
}
此题整体逻辑不算复杂,但是处理起来还是很棘手,有各种各样的异常情况需要分析处理,写着写着容易将自己绕晕。
此题完整代码如下:

1 import java.text.Collator; 2 import java.util.*; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner scanner = new Scanner(System.in); 7 Choose choose = new Choose(); 8 while(true){ 9 String st = scanner.nextLine(); 10 String[] temp = st.split(" "); 11 int count = temp.length; 12 if(st.equals("end")) 13 break; 14 if(count == 3 || (count==2&&temp[1].equals("必修"))){//添加课程信息 15 if(count == 3){ 16 if(temp[1].matches("^[\\w\\W]{1,10}$") ){//课程名 17 choose.addCourse(new Course(temp[0],temp[1],temp[2])); 18 } 19 else System.out.println("wrong format"); 20 } 21 else { 22 if(temp[1].matches("^[\\w\\W]{1,10}$") ){//课程名 23 choose.addCourse(new Course(temp[0],temp[1],"考试")); 24 } 25 else System.out.println("wrong format"); 26 } 27 } 28 if(count == 5 || count == 4){//添加课程成绩信息 29 if(count == 5){ 30 if(temp[3].matches("^([1-9]\\d?|100|0)$")&&temp[4].matches("^([1-9]\\d?|100|0)$")//分数 31 &&temp[0].matches("\\d{8}")//ID 32 &&temp[1].matches("^[\\w\\W]{1,10}$") &&temp[2].matches("^[\\w\\W]{1,10}$"))//姓名与课程名 33 { 34 choose.addScore(new Score(st)); 35 } 36 else System.out.println("wrong format"); 37 } 38 else{ 39 if(temp[3].matches("^([1-9]\\d?|100|0)$")//分数 40 &&temp[0].matches("\\d{8}")//ID 41 &&temp[1].matches("^[\\w\\W]{1,10}$") &&temp[2].matches("^[\\w\\W]{1,10}$")){ 42 choose.addScore(new Score(st)); 43 } 44 else System.out.println("wrong format"); 45 } 46 } 47 } 48 choose.getStuScore(); 49 choose.getCouScore(); 50 choose.getClaScore(); 51 } 52 } 53 54 class Choose { 55 private ArrayList<Course> courses = new ArrayList<>(); 56 private ArrayList<Score> scores = new ArrayList<>(); 57 private ArrayList<Student> students = new ArrayList<>(); 58 public ArrayList<Classroom> classrooms = new ArrayList<>(); 59 int classnum = 0; 60 public void addCourse(Course course) {//添加课程信息 61 if (course.getNature().equals("必修")) {//课程性质考试形式冲突 62 if (!course.getEvaluation_mode().equals("考试")) { 63 System.out.println(course.getCourseName() + " : course type & access mode mismatch"); 64 return; 65 } 66 } 67 if (!this.courses.isEmpty()) { 68 int n = 0; 69 for (Course c : courses) { 70 if (c.getCourseName().equals(course.getCourseName())) {//课程重名 71 n++; 72 } 73 } 74 if(n==0){ 75 courses.add(course); 76 } 77 } 78 else courses.add(course); 79 } 80 public void addScore(Score score) {//添加课程成绩信息 81 if (!this.courses.isEmpty()) { 82 int n = 0;//判断课程是否存在 83 for (Course c : courses) { 84 if (c.getCourseName().equals(score.getCourseName())) { 85 n++;//课程存在 86 if (c.getEvaluation_mode().equals("考试") && (score.getUsual_score() == 0 || score.getFinal_score() == 0)) {//成绩与考核方式不匹配 87 System.out.println(score.getStudentId() + " " + score.getStudentName() + " : access mode mismatch"); 88 int xx = 0; 89 students.add(new Student(score.getStudentName(), score.getStudentId())); 90 for (Classroom cl : classrooms) { 91 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 92 xx++; 93 break; 94 } 95 } 96 if (xx == 0) {//新班级 97 classrooms.add(new Classroom(0, score.getStudentId().substring(0, 6))); 98 } 99 } 100 else if(c.getEvaluation_mode().equals("考察")&&(score.getUsual_score()!=0)){ 101 System.out.println("wrong format"); 102 } 103 else { 104 scores.add(score); 105 c.addScore(score.getUsual_score(), score.getFinal_score(), score.thescore()); 106 107 108 int k = 0;//判断是不是新学生 109 for (Student s : students) { 110 if (s.getID().equals(score.getStudentId())) {//之前就存在这个学生 111 k = 1; 112 s.addScores(score); 113 int yy = 0; 114 for (Classroom cl : classrooms) { 115 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 116 cl.score += score.thescore(); 117 cl.k++; 118 yy++; 119 break; 120 } 121 } 122 } 123 } 124 if (k == 0) {//新学生 125 int xx = 0; 126 students.add(new Student(score.getStudentName(), score.getStudentId(), score)); 127 for (Classroom cl : classrooms) { 128 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 129 cl.score += score.thescore(); 130 cl.k++; 131 xx++; 132 break; 133 } 134 } 135 if (xx == 0) {//新班级 136 classrooms.add(new Classroom(score.thescore(), score.getStudentId().substring(0, 6))); 137 classnum++; 138 } 139 } 140 141 142 143 144 } 145 } 146 } 147 if (n == 0) {//课程不存在 148 System.out.println(score.getCourseName() + " does not exist"); 149 150 int xx = 0; 151 students.add(new Student(score.getStudentName(), score.getStudentId())); 152 for (Classroom cl : classrooms) { 153 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 154 xx++; 155 break; 156 } 157 } 158 if (xx == 0) {//新班级 159 classrooms.add(new Classroom(0, score.getStudentId().substring(0, 6))); 160 } 161 } 162 163 } 164 else{ 165 System.out.println(score.getCourseName() + " does not exist"); 166 167 int xx = 0; 168 students.add(new Student(score.getStudentName(), score.getStudentId())); 169 for (Classroom cl : classrooms) { 170 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 171 xx++; 172 break; 173 } 174 } 175 if (xx == 0) {//新班级 176 classrooms.add(new Classroom(0, score.getStudentId().substring(0, 6))); 177 } 178 } 179 } 180 181 public void getStuScore(){//学生所有课程总成绩平均分 182 sortStu(); 183 for(Student s : students){ 184 if(s.getPjf() == 0){ 185 System.out.println(s.getID()+" "+s.getName() + " did not take any exams"); 186 return; 187 } 188 else { 189 System.out.println(s.getID() +" "+s.getName()+ " "+s.getPjf()); 190 } 191 } 192 } 193 194 public void getCouScore(){ 195 Collections.sort(courses); 196 for(Course c: courses){ 197 if(c.getScore()==0){ 198 System.out.println(c.getCourseName()+" has no grades yet"); 199 } 200 else{ 201 if(c.getUsualscore()!=0){ 202 System.out.println(c.getCourseName()+" "+c.getUsualscore()/c.getK()+" "+c.getFinalscore()/c.getK()+" "+c.getScore()/c.getK()); 203 } 204 else{ 205 System.out.println(c.getCourseName()+" "+c.getFinalscore()/c.getK()+" "+c.getScore()/c.getK()); 206 } 207 } 208 } 209 } 210 public void getClaScore(){//班级平均分 211 sortCla(); 212 for(Classroom c:classrooms){ 213 c.getCScore(); 214 } 215 } 216 217 public void sortStu(){ 218 Collections.sort(students, new Comparator<Student>() { 219 @Override 220 public int compare(Student o1, Student o2) { 221 return o1.getID().compareTo(o2.getID()); 222 } 223 }); 224 } 225 226 public void sortCla(){ 227 Collections.sort(classrooms, new Comparator<Classroom>() { 228 @Override 229 public int compare(Classroom o1, Classroom o2) { 230 return o1.cID.compareTo(o2.cID); 231 } 232 }); 233 } 234 235 public ArrayList<Course> getCourses() { 236 return courses; 237 } 238 239 public void setCourses(ArrayList<Course> courses) { 240 this.courses = courses; 241 } 242 243 public ArrayList<Score> getScores() { 244 return scores; 245 } 246 247 public void setScores(ArrayList<Score> scores) { 248 this.scores = scores; 249 } 250 251 public ArrayList<Student> getStudents() { 252 return students; 253 } 254 255 public void setStudents(ArrayList<Student> students) { 256 this.students = students; 257 } 258 259 } 260 261 class Course implements Comparable<Course>{ 262 private String courseName ; //课程名称 263 private String nature = "必修"; //课程性质 264 private String access_mode = "考试"; //考核模式 265 private int score = 0; 266 private int usualscore = 0; 267 private int finalscore = 0; 268 private int k = 0; 269 private int c = 0; 270 //构造方法 271 public Course() { 272 273 } 274 public Course(String courseName,String nature,String access_mode) { 275 this.courseName = courseName; 276 this.nature = nature; 277 this.access_mode = access_mode; 278 c++; 279 } 280 public void addScore(int us,int fs,int s){ 281 score += s; 282 usualscore+= us; 283 finalscore+= fs; 284 k++; 285 } 286 //getset方法 287 288 public int getC() { 289 return c; 290 } 291 292 public void setC(int c) { 293 this.c = c; 294 } 295 296 public String getCourseName() { 297 return courseName; 298 } 299 public void setCourseName(String courseName) { 300 this.courseName = courseName; 301 } 302 public String getNature() { 303 return nature; 304 } 305 public void setNature(String nature) { 306 this.nature = nature; 307 } 308 public String getEvaluation_mode() { 309 return access_mode; 310 } 311 public void setEvaluation_mode(String evaluation_mode) { 312 this.access_mode = evaluation_mode; 313 } 314 315 public String getAccess_mode() { 316 return access_mode; 317 } 318 319 public void setAccess_mode(String access_mode) { 320 this.access_mode = access_mode; 321 } 322 323 public int getScore() { 324 return score; 325 } 326 327 public void setScore(int score) { 328 this.score = score; 329 } 330 331 public int getUsualscore() { 332 return usualscore; 333 } 334 335 public void setUsualscore(int usualscore) { 336 this.usualscore = usualscore; 337 } 338 339 public int getFinalscore() { 340 return finalscore; 341 } 342 343 public void setFinalscore(int finalscore) { 344 this.finalscore = finalscore; 345 } 346 347 public int getK() { 348 return k; 349 } 350 351 public void setK(int k) { 352 this.k = k; 353 } 354 355 @Override 356 public int compareTo(Course o) { 357 Comparator<Object> c = Collator.getInstance(Locale.CHINA); 358 return ((Collator) c).compare(this.courseName,o.courseName); 359 } 360 } 361 362 class Score{ 363 private String studentId; 364 private String studentName; 365 private String courseName; 366 private int usual_score;//平时成绩 367 private int final_score;//期末成绩 368 public Score(String line) { 369 String[] parts = line.split(" "); 370 studentId = parts[0]; 371 studentName = parts[1]; 372 courseName = parts[2]; 373 usual_score = parts.length > 4 ? Integer.parseInt(parts[3]) : 0; 374 final_score = Integer.parseInt(parts[parts.length - 1]); 375 } 376 377 public int thescore(){ 378 if(getUsual_score()==0) 379 return getFinal_score(); 380 else return (int) (getUsual_score()*0.3+getFinal_score()*0.7); 381 } 382 383 public String getStudentId() { 384 return studentId; 385 } 386 387 public void setStudentId(String studentId) { 388 this.studentId = studentId; 389 } 390 391 public String getStudentName() { 392 return studentName; 393 } 394 395 public void setStudentName(String studentName) { 396 this.studentName = studentName; 397 } 398 399 public String getCourseName() { 400 return courseName; 401 } 402 403 public void setCourseName(String courseName) { 404 this.courseName = courseName; 405 } 406 407 public int getUsual_score() { 408 return usual_score; 409 } 410 411 public void setUsual_score(int usual_score) { 412 this.usual_score = usual_score; 413 } 414 415 public int getFinal_score() { 416 return final_score; 417 } 418 419 public void setFinal_score(int final_score) { 420 this.final_score = final_score; 421 } 422 } 423 class Student{ 424 private String name; 425 private String ID; 426 private ArrayList<Score> scores = new ArrayList<>(); 427 public Student(String name, String ID, Score scores) { 428 this.name = name; 429 this.ID = ID; 430 this.scores.add(scores); 431 } 432 public Student(String name,String ID){ 433 this.name = name; 434 this.ID = ID; 435 } 436 public void addScores(Score scores){ 437 this.scores.add(scores); 438 } 439 public int getPjf(){ 440 int pjf = 0; 441 for(Score s : scores){ 442 pjf += s.thescore(); 443 } 444 if(!scores.isEmpty()) 445 pjf = pjf/ scores.size(); 446 return pjf; 447 } 448 449 public String getName() { 450 return name; 451 } 452 453 public void setName(String name) { 454 this.name = name; 455 } 456 457 public String getID() { 458 return ID; 459 } 460 461 public void setID(String ID) { 462 this.ID = ID; 463 } 464 465 public ArrayList<Score> getScores() { 466 return scores; 467 } 468 469 public void setScores(ArrayList<Score> scores) { 470 this.scores = scores; 471 } 472 } 473 474 class Classroom{ 475 public int score = 0; 476 public String cID; 477 public int k = 0; 478 479 public Classroom(int score, String cID) { 480 this.score = score; 481 this.cID = cID; 482 if(score!=0){ 483 k++; 484 } 485 } 486 487 public void getCScore(){ 488 if( k == 0){ 489 System.out.println(cID+" has no grades yet"); 490 } 491 else{ 492 System.out.println(cID+" "+(int)(score/k)); 493 } 494 } 495 }
题目集九
统计Java程序中关键词的出现次数
题目信息如下:

7-1 统计Java程序中关键词的出现次数 分数 100 作者 段喜龙 单位 南昌航空大学 编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下: Java中共有53个关键字(自行百度) 从键盘输入一段源码,统计这段源码中出现的关键字的数量 注释中出现的关键字不用统计 字符串中出现的关键字不用统计 统计出的关键字及数量按照关键字升序进行排序输出 未输入源码则认为输入非法 输入格式: 输入Java源码字符串,可以一行或多行,以exit行作为结束标志 输出格式: 当未输入源码时,程序输出Wrong Format 当没有统计数据时,输出为空 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为数量\t关键字 输入样例: 在这里给出一组输入。例如: //Test public method public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); this.loadFactor = loadFactor; this.threshold = tableSizeFor(initialCapacity); } exit 输出样例: 在这里给出相应的输出。例如: 1 float 3 if 2 int 2 new 2 public 3 this 2 throw 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
首先分析题目,程序需要从标准输入读入Java源码,统计其中关键字的出现次数,并按照关键字升序排列输出结果。
我使用while循环语句读取每一行的代码信息,使用Java的正则表达式库实现关键字的匹配,使用Java集合框架中的Map实现储存关键字计数。在代码实现中,程序忽略了单行注释和多行注释中的关键字的统计,并且在遇到字符串时也忽略了其中的关键字的统计。同时程序在遇到“exit”字符串时结束程序的运行,妥善处理了输入非法的情况,最终输出关键字及数量排序后的统计数据。
代码String regex = "\\b" + keyword + "\\b"用来匹配Java源代码中的关键字,`\b`表示一个单词的边界。当keyword的值为“while”时,该正则表达式就是`\bwhile\b`,它可以很好地与Java源代码中的“while”单词进行匹配,但不会误匹配“while”的变种,例如“whiles”、“inwhile”等字符串。
为了实现对Java源码每一行中的关键字的匹配和计数。
我首先使用Java正则表达式中的Pattern类的`compile()`方法,将定义好的关键字正则表达式`regex`编译成Pattern模式。然后使用该模式构建一个matcher对象,这个对象将用于检查类似`line`这样的Java代码行是否包含关键字。
接下来使用Matcher的`find()`方法在`line`中查找符合正则表达式的子串。如果`find()`返回`true`,则说明这一行代码包含至少一个关键字,获取该匹配串并存为`matchedKeyword`。然后使用`keywordCountMap`统计`matchedKeyword`的出现次数。如果`matchedKeyword`已经存在于`keywordCountMap`中,则获取它的计数值并加1;否则默认计数为0后加1。最后将更新后的计数值写回Map中。
此外,我使用正则表达式和String类中的replace方法去除了有干扰的代码块:
line = line.replaceAll("//.*","");用来将出现在行中间的单行注释之后的内容替换为空
line = line.replaceAll("\".*?\"","");用来将字符串内的内容替换为空,这样先前的内容就不会被统计。
具体代码如下:

1 import java.util.*; 2 import java.util.regex.Matcher; 3 import java.util.regex.Pattern; 4 public class Main { 5 public static void main(String[] args) { 6 String[] KEYWORDS = { 7 "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char","class", "const", "continue", "default", "do", "double", "else", "enum", 8 "extends", "final", "finally", "float", "for", "if", "goto", "implements","import", "instanceof", "int", "interface", "long", "native", "new", "package", 9 "private", "protected", "public", "return", "short", "static", "strictfp","super", "switch", "synchronized", "this", "throw", "throws", "transient", 10 "try", "void", "volatile", "while","true","false","null" 11 }; 12 Map<String, Integer> keywordCountMap = new TreeMap<>();//存放keyword-count键值对,默认按键的升序排序 13 Scanner scanner = new Scanner(System.in); 14 String line; 15 int linecount = 0;//判断行数 16 boolean isCodeRegion = true;//判断是否是代码区 17 while (true) { 18 line = scanner.nextLine(); 19 if (line.equals("exit")) { 20 break; 21 } 22 linecount++; 23 line = line.replaceAll("//.*",""); 24 line = line.replaceAll("\".*?\"",""); 25 line = line.replaceAll("=","1"); 26 if (line.trim().startsWith("//")) { 27 continue;//单行注释,直接跳过此行 28 } 29 if (line.trim().startsWith("/*")) { 30 isCodeRegion = false; //多行注释开头,接下来都不是代码区 31 } 32 if (isCodeRegion) { 33 for (String keyword : KEYWORDS) { 34 String regex = "\\b" + keyword + "\\b"; // 使用正则表达式匹配单词边界 35 Matcher matcher = Pattern.compile(regex).matcher(line);//检查line是否包含关键字 36 while (matcher.find()) {//代码包含至少一个关键字 37 String matchedKeyword = matcher.group();//获取该匹配串并存为matchedKeyword 38 int count = keywordCountMap.getOrDefault(matchedKeyword, 0);//取出matchedKeyword对应的值,没有则赋0 39 keywordCountMap.put(matchedKeyword, count + 1);//count+1 40 } 41 } 42 } 43 if (line.trim().endsWith("*/")) { 44 isCodeRegion = true; //多行注释结尾,接下来是代码区 45 } 46 } 47 if(linecount==0){ 48 System.out.println("Wrong Format"); 49 return; 50 } 51 if (keywordCountMap.isEmpty()) {//没有统计数据时输出为空 52 System.out.println(""); 53 return; 54 } 55 for (String keyword : keywordCountMap.keySet()) { 56 int count = keywordCountMap.get(keyword); 57 System.out.println(count + "\t" + keyword); 58 } 59 } 60 }
题目集十
课程成绩统计程序-2
题目信息如下:

7-3 课程成绩统计程序-2 分数 60 作者 蔡轲 单位 南昌航空大学 课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。 某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。 考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。 考察的总成绩直接等于期末成绩 实验的总成绩等于课程每次实验成绩的平均分 必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。 1、输入: 包括课程、课程成绩两类信息。 课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。 课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式 课程性质输入项:必修、选修、实验 考核方式输入选项:考试、考察、实验 考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩 考试/考查课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩 实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩 实验次数至少4次,不超过9次 实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩 以上信息的相关约束: 1)平时成绩和期末成绩的权重默认为0.3、0.7 2)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】 3)学号由8位数字组成 4)姓名不超过10个字符 5)课程名称不超过10个字符 6)不特别输入班级信息,班级号是学号的前6位。 2、输出: 输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。 为避免误差,平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。 1)学生课程总成绩平均分按学号由低到高排序输出 格式:学号+英文空格+姓名+英文空格+总成绩平均分 如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams" 2)单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出 考试/考察课程成绩格式:课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分 实验课成绩格式:课程名称+英文空格+总成绩平均分 如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet" 3)班级所有课程总成绩平均分按班级由低到高排序输出 格式:班级号+英文空格+总成绩平均分 如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet" 异常情况: 1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist" 2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch" 以上两种情况如果同时出现,按第一种情况输出结果。 3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch" 4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format" 5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。 信息约束: 1)成绩平均分只取整数部分,小数部分丢弃 参考类图(与第一次相同,其余内容自行补充): e724fa4193aa9ee32e78a68cd96fd6df_22401e04-c501-4b28-bb65-dabe39d374e7.png 输入样例1: 在这里给出一组输入。例如: java 实验 实验 20201103 张三 java 4 70 80 90 end 输出样例1: 在这里给出相应的输出。例如: 20201103 张三 : access mode mismatch 20201103 张三 did not take any exams java has no grades yet 202011 has no grades yet 输入样例2: 在这里给出一组输入。例如: java 实验 实验 20201103 张三 java 3 70 80 90 end 输出样例2: 在这里给出相应的输出。例如: wrong format java has no grades yet 输入样例3: 在这里给出一组输入。例如: java 必修 实验 20201103 张三 java 3 70 80 90 100 end 输出样例3: 在这里给出相应的输出。例如: java : course type & access mode mismatch wrong format 输入样例4: 在这里给出一组输入。例如: java 必修 实验 20201103 张三 java 4 70 80 90 105 end 输出样例4: 在这里给出相应的输出。例如: java : course type & access mode mismatch wrong format 输入样例5: 在这里给出一组输入。例如: java 选修 考察 C语言 选修 考察 java实验 实验 实验 编译原理 必修 考试 20201101 王五 C语言 76 20201216 李四 C语言 78 20201307 张少军 编译原理 82 84 20201103 张三 java实验 4 70 80 90 100 20201118 郑觉先 java 80 20201328 刘和宇 java 77 20201220 朱重九 java实验 4 60 60 80 80 20201132 王萍 C语言 40 20201302 李梦涵 C语言 68 20201325 崔瑾 编译原理 80 84 20201213 黄红 java 82 20201209 赵仙芝 java 76 end 输出样例5: 在这里给出相应的输出。例如: 20201101 王五 76 20201103 张三 85 20201118 郑觉先 80 20201132 王萍 40 20201209 赵仙芝 76 20201213 黄红 82 20201216 李四 78 20201220 朱重九 70 20201302 李梦涵 68 20201307 张少军 83 20201325 崔瑾 82 20201328 刘和宇 77 C语言 65 65 java 78 78 java实验 77 编译原理 81 84 82 202011 70 202012 76 202013 77
本题是课程成绩统计程序的迭代,有了上一次的基础,这次写起来便轻松很多。
首先分析题目,本次程序主要是在第一次的基础上增加了实验课,实验课的考核方式也一定为实验,规定实验次数至少四次,不超过9次。
这次迭代并没有增加太多的东西,只需要在主函数的while语句读取输入信息时,增加字符串长度符合实验课信息长度的情况即可,其他科目通过识别考核方式进行权重评分,而实验课则是多次实验的平均分,相比起来其实更好处理,只需要在录入实验课成绩时累加成绩,最后再除以做实验的次数。
此次迭代难度不大,其他部分的详细编程过程见课程成绩统计程序-1中介绍。
完成代码如下:

1 import java.text.Collator; 2 import java.util.*; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner scanner = new Scanner(System.in); 7 Choose choose = new Choose(); 8 while(true){ 9 String st = scanner.nextLine(); 10 String[] temp = st.split(" "); 11 int count = temp.length; 12 if(st.equals("end")) 13 break; 14 if(count == 3 || (count==2&&temp[1].equals("必修"))){//添加课程信息 15 if(count == 3){ 16 if(temp[1].matches("^[\\w\\W]{1,10}$") ){//课程名 17 choose.addCourse(new Course(temp[0],temp[1],temp[2])); 18 } 19 else System.out.println("wrong format"); 20 } 21 else { 22 if(temp[1].matches("^[\\w\\W]{1,10}$") ){//课程名 23 choose.addCourse(new Course(temp[0],temp[1],"考试")); 24 } 25 else System.out.println("wrong format"); 26 } 27 } 28 if(count == 5 || count == 4){//添加课程成绩信息 29 if(count == 5){ 30 if(temp[3].matches("^([1-9]\\d?|100|0)$")&&temp[4].matches("^([1-9]\\d?|100|0)$")//分数 31 &&temp[0].matches("\\d{8}")//ID 32 &&temp[1].matches("^[\\w\\W]{1,10}$") &&temp[2].matches("^[\\w\\W]{1,10}$"))//姓名与课程名 33 { 34 choose.addScore(new Score(st)); 35 } 36 else System.out.println("wrong format"); 37 } 38 else{ 39 if(temp[3].matches("^([1-9]\\d?|100|0)$")//分数 40 &&temp[0].matches("\\d{8}")//ID 41 &&temp[1].matches("^[\\w\\W]{1,10}$") &&temp[2].matches("^[\\w\\W]{1,10}$")){ 42 choose.addScore(new Score(st)); 43 } 44 else System.out.println("wrong format"); 45 } 46 } 47 else if(count >5){//添加实验课课程成绩 48 int k = 0; 49 if(temp[0].matches("\\d{8}")//ID 50 &&temp[1].matches("^[\\w\\W]{1,10}$") &&temp[2].matches("^[\\w\\W]{1,10}$")){//姓名与课程名 51 for(int i = 4; i<count;i++){ 52 if(!temp[i].matches("^([1-9]\\d?|100|0)$")){ 53 System.out.println("wrong format"); 54 k++; 55 break; 56 } 57 } 58 if(k==0){ 59 choose.addScore(new Score(st)); 60 } 61 } 62 else System.out.println("wrong format"); 63 } 64 } 65 choose.getStuScore(); 66 choose.getCouScore(); 67 choose.getClaScore(); 68 } 69 } 70 71 class Choose { 72 private ArrayList<Course> courses = new ArrayList<>(); 73 private ArrayList<Score> scores = new ArrayList<>(); 74 private ArrayList<Student> students = new ArrayList<>(); 75 public ArrayList<Classroom> classrooms = new ArrayList<>(); 76 int classnum = 0; 77 public void addCourse(Course course) {//添加课程信息 78 if (course.getNature().equals("必修")) {//课程性质考试形式冲突 79 if (!course.getEvaluation_mode().equals("考试")) { 80 System.out.println(course.getCourseName() + " : course type & access mode mismatch"); 81 return; 82 } 83 } 84 if (!this.courses.isEmpty()) { 85 int n = 0; 86 for (Course c : courses) { 87 if (c.getCourseName().equals(course.getCourseName())) {//课程重名 88 n++; 89 } 90 } 91 if(n==0){ 92 courses.add(course); 93 } 94 } 95 else courses.add(course); 96 } 97 public void addScore(Score score) {//添加课程成绩信息 98 if (!this.courses.isEmpty()) { 99 int n = 0;//判断课程是否存在 100 for (Course c : courses) { 101 if (c.getCourseName().equals(score.getCourseName())) { 102 n++;//课程存在 103 if ((c.getEvaluation_mode().equals("考试") && (score.getUsual_score() == 0 || score.getFinal_score() == 0)) 104 ||(c.getEvaluation_mode().equals("考察")&&(score.getUsual_score()!=0))) { 105 //成绩与考核方式不匹配 106 System.out.println(score.getStudentId() + " " + score.getStudentName() + " : access mode mismatch"); 107 int xx = 0; 108 students.add(new Student(score.getStudentName(), score.getStudentId())); 109 for (Classroom cl : classrooms) { 110 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 111 xx++; 112 break; 113 } 114 } 115 if (xx == 0) {//新班级 116 classrooms.add(new Classroom(0, score.getStudentId().substring(0, 6))); 117 } 118 } 119 120 // else if(c.getEvaluation_mode().equals("考察")&&(score.getUsual_score()!=0)){ 121 // System.out.println("wrong format"); 122 // } 123 else { 124 scores.add(score); 125 // if(c.getEvaluation_mode()=="实验"&&c.getNature()=="实验"){ 126 // c.addShiYanScore(score.getShiyan_score()); 127 // } 128 // else{ 129 c.addScore(score.getUsual_score(), score.getFinal_score(), score.thescore()); 130 // } 131 132 int k = 0;//判断是不是新学生 133 for (Student s : students) { 134 if (s.getID().equals(score.getStudentId())) {//之前就存在这个学生 135 k = 1; 136 s.addScores(score); 137 int yy = 0; 138 for (Classroom cl : classrooms) { 139 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 140 cl.score += score.thescore(); 141 cl.k++; 142 yy++; 143 break; 144 } 145 } 146 } 147 } 148 if (k == 0) {//新学生 149 int xx = 0; 150 students.add(new Student(score.getStudentName(), score.getStudentId(), score)); 151 for (Classroom cl : classrooms) { 152 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 153 cl.score += score.thescore(); 154 cl.k++; 155 xx++; 156 break; 157 } 158 } 159 if (xx == 0) {//新班级 160 classrooms.add(new Classroom(score.thescore(), score.getStudentId().substring(0, 6))); 161 classnum++; 162 } 163 } 164 165 166 167 168 } 169 } 170 } 171 if (n == 0) {//课程不存在 172 System.out.println(score.getCourseName() + " does not exist"); 173 174 int xx = 0; 175 students.add(new Student(score.getStudentName(), score.getStudentId())); 176 for (Classroom cl : classrooms) { 177 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 178 xx++; 179 break; 180 } 181 } 182 if (xx == 0) {//新班级 183 classrooms.add(new Classroom(0, score.getStudentId().substring(0, 6))); 184 } 185 } 186 187 } 188 else{ 189 System.out.println(score.getCourseName() + " does not exist"); 190 191 int xx = 0; 192 students.add(new Student(score.getStudentName(), score.getStudentId())); 193 for (Classroom cl : classrooms) { 194 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 195 xx++; 196 break; 197 } 198 } 199 if (xx == 0) {//新班级 200 classrooms.add(new Classroom(0, score.getStudentId().substring(0, 6))); 201 } 202 } 203 } 204 205 public void getStuScore(){//学生所有课程总成绩平均分 206 sortStu(); 207 for(Student s : students){ 208 if(s.getPjf() == 0){ 209 System.out.println(s.getID()+" "+s.getName() + " did not take any exams"); 210 211 } 212 else { 213 System.out.println(s.getID() +" "+s.getName()+ " "+s.getPjf()); 214 } 215 } 216 } 217 218 public void getCouScore(){ 219 Collections.sort(courses); 220 for(Course c: courses){ 221 if(c.getScore()==0){ 222 System.out.println(c.getCourseName()+" has no grades yet"); 223 } 224 else{ 225 if(c.getEvaluation_mode().equals("实验")){ 226 System.out.println(c.getCourseName()+" "+c.getScore()/c.getK()); 227 } 228 else if(c.getUsualscore()==0){ 229 System.out.println(c.getCourseName()+" "+c.getFinalscore()/c.getK()+" "+c.getScore()/c.getK()); 230 } 231 else if(c.getUsualscore()!=-1&&c.getUsualscore()!=0&&c.getFinalscore()!=-1){ 232 System.out.println(c.getCourseName()+" "+c.getUsualscore()/c.getK()+" "+c.getFinalscore()/c.getK()+" "+c.getScore()/c.getK()); 233 } 234 } 235 } 236 } 237 public void getClaScore(){//班级平均分 238 sortCla(); 239 for(Classroom c:classrooms){ 240 c.getCScore(); 241 } 242 } 243 244 public void sortStu(){ 245 Collections.sort(students, new Comparator<Student>() { 246 @Override 247 public int compare(Student o1, Student o2) { 248 return o1.getID().compareTo(o2.getID()); 249 } 250 }); 251 } 252 253 public void sortCla(){ 254 Collections.sort(classrooms, new Comparator<Classroom>() { 255 @Override 256 public int compare(Classroom o1, Classroom o2) { 257 return o1.cID.compareTo(o2.cID); 258 } 259 }); 260 } 261 262 public ArrayList<Course> getCourses() { 263 return courses; 264 } 265 266 public void setCourses(ArrayList<Course> courses) { 267 this.courses = courses; 268 } 269 270 public ArrayList<Score> getScores() { 271 return scores; 272 } 273 274 public void setScores(ArrayList<Score> scores) { 275 this.scores = scores; 276 } 277 278 public ArrayList<Student> getStudents() { 279 return students; 280 } 281 282 public void setStudents(ArrayList<Student> students) { 283 this.students = students; 284 } 285 286 } 287 288 class Course implements Comparable<Course>{ 289 private String courseName ; //课程名称 290 private String nature = "必修"; //课程性质 291 private String access_mode = "考试"; //考核模式 292 private int score = 0; 293 private int usualscore = 0; 294 private int finalscore = 0; 295 private int k = 0; 296 private int c = 0; 297 //构造方法 298 public Course() { 299 300 } 301 public Course(String courseName,String nature,String access_mode) { 302 this.courseName = courseName; 303 this.nature = nature; 304 this.access_mode = access_mode; 305 c++; 306 } 307 public void addScore(int us,int fs,int s){ 308 score += s; 309 usualscore+= us; 310 finalscore+= fs; 311 k++; 312 } 313 public void addShiYanScore(int score){ 314 score += score; 315 k++; 316 } 317 //getset方法 318 319 public int getC() { 320 return c; 321 } 322 323 public void setC(int c) { 324 this.c = c; 325 } 326 327 public String getCourseName() { 328 return courseName; 329 } 330 public void setCourseName(String courseName) { 331 this.courseName = courseName; 332 } 333 public String getNature() { 334 return nature; 335 } 336 public void setNature(String nature) { 337 this.nature = nature; 338 } 339 public String getEvaluation_mode() { 340 return access_mode; 341 } 342 public void setEvaluation_mode(String evaluation_mode) { 343 this.access_mode = evaluation_mode; 344 } 345 346 public String getAccess_mode() { 347 return access_mode; 348 } 349 350 public void setAccess_mode(String access_mode) { 351 this.access_mode = access_mode; 352 } 353 354 public int getScore() { 355 return score; 356 } 357 358 public void setScore(int score) { 359 this.score = score; 360 } 361 362 public int getUsualscore() { 363 return usualscore; 364 } 365 366 public void setUsualscore(int usualscore) { 367 this.usualscore = usualscore; 368 } 369 370 public int getFinalscore() { 371 return finalscore; 372 } 373 374 public void setFinalscore(int finalscore) { 375 this.finalscore = finalscore; 376 } 377 378 public int getK() { 379 return k; 380 } 381 382 public void setK(int k) { 383 this.k = k; 384 } 385 386 @Override 387 public int compareTo(Course o) { 388 Comparator<Object> c = Collator.getInstance(Locale.CHINA); 389 return ((Collator) c).compare(this.courseName,o.courseName); 390 } 391 } 392 393 class Score{ 394 private String studentId; 395 private String studentName; 396 private String courseName; 397 private int usual_score;//平时成绩 398 private int final_score;//期末成绩 399 private int shiyan_time = 0; 400 private int shiyan_score;//实验平均分 401 public Score(String line) { 402 String[] parts = line.split(" "); 403 studentId = parts[0]; 404 studentName = parts[1]; 405 courseName = parts[2]; 406 if(parts.length<=5){ 407 usual_score = parts.length > 4 ? Integer.parseInt(parts[3]) : 0; 408 final_score = Integer.parseInt(parts[parts.length - 1]); 409 } 410 else{ 411 usual_score = -1; 412 final_score = -1; 413 shiyan_time = Integer.parseInt(parts[3]); 414 if(shiyan_time+4 == parts.length){ 415 for(int i = 0; i<shiyan_time;i++){ 416 shiyan_score += Integer.parseInt(parts[i+4]); 417 } 418 shiyan_score = shiyan_score/shiyan_time; 419 } 420 else{ 421 System.out.println(studentId+" "+studentName+" : access mode mismatch"); 422 } 423 } 424 425 426 427 } 428 429 public int thescore(){ 430 if(shiyan_time!=0){ 431 return shiyan_score; 432 } 433 else if(getUsual_score()==0) 434 return getFinal_score(); 435 else return (int) (getUsual_score()*0.3+getFinal_score()*0.7); 436 } 437 438 public int getShiyan_score() { 439 return shiyan_score; 440 } 441 442 public int getShiyan_time() { 443 return shiyan_time; 444 } 445 446 public String getStudentId() { 447 return studentId; 448 } 449 450 public void setStudentId(String studentId) { 451 this.studentId = studentId; 452 } 453 454 public String getStudentName() { 455 return studentName; 456 } 457 458 public void setStudentName(String studentName) { 459 this.studentName = studentName; 460 } 461 462 public String getCourseName() { 463 return courseName; 464 } 465 466 public void setCourseName(String courseName) { 467 this.courseName = courseName; 468 } 469 470 public int getUsual_score() { 471 return usual_score; 472 } 473 474 public void setUsual_score(int usual_score) { 475 this.usual_score = usual_score; 476 } 477 478 public int getFinal_score() { 479 return final_score; 480 } 481 482 public void setFinal_score(int final_score) { 483 this.final_score = final_score; 484 } 485 } 486 class Student{ 487 private String name; 488 private String ID; 489 private ArrayList<Score> scores = new ArrayList<>(); 490 public Student(String name, String ID, Score scores) { 491 this.name = name; 492 this.ID = ID; 493 this.scores.add(scores); 494 } 495 public Student(String name,String ID){ 496 this.name = name; 497 this.ID = ID; 498 } 499 public void addScores(Score scores){ 500 this.scores.add(scores); 501 } 502 public int getPjf(){ 503 int pjf = 0; 504 for(Score s : scores){ 505 pjf += s.thescore(); 506 } 507 if(!scores.isEmpty()) 508 pjf = pjf/ scores.size(); 509 return pjf; 510 } 511 512 public String getName() { 513 return name; 514 } 515 516 public void setName(String name) { 517 this.name = name; 518 } 519 520 public String getID() { 521 return ID; 522 } 523 524 public void setID(String ID) { 525 this.ID = ID; 526 } 527 528 public ArrayList<Score> getScores() { 529 return scores; 530 } 531 public void setScores(ArrayList<Score> scores) { 532 this.scores = scores; 533 } 534 } 535 class Classroom{ 536 public int score = 0; 537 public String cID; 538 public int k = 0; 539 540 public Classroom(int score, String cID) { 541 this.score = score; 542 this.cID = cID; 543 if(score!=0){ 544 k++; 545 } 546 } 547 548 public void getCScore(){ 549 if( k == 0){ 550 System.out.println(cID+" has no grades yet"); 551 } 552 else{ 553 System.out.println(cID+" "+(int)(score/k)); 554 } 555 } 556 }
题目集十一
课程成绩统计程序-3
题目信息如下:

7-2 课程成绩统计程序-3 分数 64 作者 蔡轲 单位 南昌航空大学 课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式, 要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。 完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。 题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。 某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。 考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。 考察的总成绩直接等于期末成绩 实验的总成绩等于课程每次实验成绩乘以权重后累加而得。 课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1) 必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。 1、输入: 包括课程、课程成绩两类信息。 课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。 考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重 考察课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式 实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重 实验次数至少4次,不超过9次 课程性质输入项:必修、选修、实验 考核方式输入选项:考试、考察、实验 考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩 考试/考查课程成绩信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩 实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致} 实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩 以上信息的相关约束: 1)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】 2)学号由8位数字组成 3)姓名不超过10个字符 4)课程名称不超过10个字符 5)不特别输入班级信息,班级号是学号的前6位。 2、输出: 输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。 为避免四舍五入误差, 计算单个成绩时,分项成绩乘以权重后要保留小数位,计算总成绩时,累加所有分项成绩的权重分以后,再去掉小数位。 学生总成绩/整个班/课程平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。 1)学生课程总成绩平均分按学号由低到高排序输出 格式:学号+英文空格+姓名+英文空格+总成绩平均分 如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams" 2)单门课程成绩按课程名称的字符顺序输出 课程成绩输出格式:课程名称+英文空格+总成绩平均分 如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet" 3)班级所有课程总成绩平均分按班级由低到高排序输出 格式:班级号+英文空格+总成绩平均分 如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet" 异常情况: 1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist" 2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch" 以上两种情况如果同时出现,按第一种情况输出结果。 3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch" 4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format" 5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。 6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match" 7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error" 信息约束: 1)成绩平均分只取整数部分,小数部分丢弃 参考类图(与第一次相同,其余内容自行补充): fdada4ca193119ee30531ab82ffebbfa_9dbcf4e8-1627-4cf6-8764-cccf44947e2a.png 输入样例1: 在这里给出一组输入。例如: java 实验 实验 4 0.2 0.3 0.2 0.3 end 输出样例1: 在这里给出相应的输出。例如: java has no grades yet 输入样例2: 在这里给出一组输入。例如: java 实验 实验 4 0.2 0.3 0.2 end 输出样例2: 在这里给出相应的输出。例如: java : number of scores does not match 输入样例3: 在这里给出一组输入。例如: java 实验 实验 4 0.2 0.3 0.2 0.1 end 输出样例3: 在这里给出相应的输出。例如: java : weight value error 输入样例4: 在这里给出一组输入。例如: java 实验 实验 4 0.2 0.3 0.2 0.3 20201116 张三 java 70 80 90 100 end 输出样例4: 在这里给出相应的输出。例如: 20201116 张三 86 java 86 202011 86 输入样例5: 在这里给出一组输入。例如: java 实验 实验 4 0.2 0.3 0.2 0.3 20201116 张三 java 70 80 90 100 80 end 输出样例5: 在这里给出相应的输出。例如: 20201116 张三 : access mode mismatch 20201116 张三 did not take any exams java has no grades yet 202011 has no grades yet
本次迭代修改了计算总成绩的方式,并且要求修改类结构,将继承关系改为组合关系。成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。
为了实现迭代功能,我新建了ItemScore分项成绩类,此类中包含两个属性:grade分项成绩分值和weight成绩权重,以及一个方法getGradeByWeight()用来根据权重计算得分。
修改Score类中部分代码,使得Score类组合ItemScore类。首先,Score类中包含属性:private List<ItemScore> itemList = new ArrayList<>(); // 分项成绩列表,并在Score类中添加方法getTotalGrade()用来计算总成绩。
double total = 0;
for (ItemScore item : itemList) {
total += item.getGradeByWeight();
}
return total;
}
由于新增了权重值的概念,在录入课程信息和课程成绩信息时在主函数匹配的字符串长度需要进行改变,并且在录入课程信息时要录入权重值信息,由于录入课程信息是通过Choose类的addCourse(Course course)方法,因此我的改进思路是在Course类中再增加课程权重的List链并改变Course的构造方法,多添加传进去的参数,使之变成:public Course(String courseName,String nature,String access_mode,List<Double> weight),这样便可以将成绩权重作为有序的链存在Course中。录入课程成绩信息时,使用Score类的List<ItemScore> Itemlist属性对成绩进行权重计算,通过getTotalGrade()方法遍历 itemlist 进行计算总成绩。
String[] parts = line.split("");
studentId = parts[0];
studentName = parts[1];
courseName = parts[2];
if(parts.length<=5){
int u = parts.length > 4 ? Integer.parseInt(parts[3]) : 0;
itemList.get(0).setWeight(weight.get(0));
itemList.get(0).setGrade(u);
int f = Integer.parseInt(parts[parts.length - 1]);
itemList.get(1).setWeight(weight.get(1));
itemList.get(1).setGrade(f);
}
else{
int j = 0;
if(parts.length==weight.size()+3){
for(int i=3;i< parts.length;i++){
itemList.add(new ItemScore());
itemList.get(j).setWeight(weight.get(j));
itemList.get(j).setGrade(Integer.parseInt(parts[i]));
j++;
}
} else {
System.out.println(studentId+" "+studentName+" : access mode mismatch");
}
}
}
程序完整代码如下:

1 import java.text.Collator; 2 import java.util.*; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner scanner = new Scanner(System.in); 7 Choose choose = new Choose(); 8 while(true){ 9 String st = scanner.nextLine(); 10 String[] temp = st.split(" "); 11 int count = temp.length; 12 if(st.equals("end")) 13 break; 14 if(temp[1].equals("选修")||temp[1].equals("必修")||temp[1].equals("实验")){//添加课程信息 15 if(temp[1].matches("^[\\w\\W]{1,10}$") ){//课程名 16 int n = Integer.parseInt(temp[3]); 17 if((n+4)!=count){ 18 System.out.println(temp[0]+" : number of scores does not match"); 19 return; 20 } 21 List<Double> list = new ArrayList<>(); 22 for(int i=4;i<n+4;i++){ 23 list.add(Double.parseDouble(temp[i])); 24 } 25 choose.addCourse(new Course(temp[0],temp[1],temp[2],list)); 26 } 27 else System.out.println("wrong format"); 28 } 29 else if(count == 5 || count == 4){//添加课程成绩信息 30 if(count == 5){ 31 if(temp[3].matches("^([1-9]\\d?|100|0)$")&&temp[4].matches("^([1-9]\\d?|100|0)$")//分数 32 &&temp[0].matches("\\d{8}")//ID 33 &&temp[1].matches("^[\\w\\W]{1,10}$") &&temp[2].matches("^[\\w\\W]{1,10}$"))//姓名与课程名 34 { 35 for(Course c : choose.getCourses()){ 36 if(c.getCourseName().equals(temp[2])){ 37 choose.addScore(new Score(st,c.getWeight())); 38 } 39 } 40 } 41 else System.out.println("wrong format"); 42 } 43 else{ 44 if(temp[3].matches("^([1-9]\\d?|100|0)$")//分数 45 &&temp[0].matches("\\d{8}")//ID 46 &&temp[1].matches("^[\\w\\W]{1,10}$") &&temp[2].matches("^[\\w\\W]{1,10}$")){ 47 for(Course c : choose.getCourses()){ 48 if(c.getCourseName().equals(temp[2])){ 49 choose.addScore(new Score(st,c.getWeight())); 50 } 51 } 52 } 53 else System.out.println("wrong format"); 54 } 55 } 56 else if(count >5){//添加实验课课程成绩 57 int k = 0; 58 if(temp[0].matches("\\d{8}")//ID 59 &&temp[1].matches("^[\\w\\W]{1,10}$") &&temp[2].matches("^[\\w\\W]{1,10}$")){//姓名与课程名 60 for(int i = 4; i<count;i++){ 61 if(!temp[i].matches("^([1-9]\\d?|100|0)$")){ 62 System.out.println("wrong format"); 63 k++; 64 break; 65 } 66 } 67 if(k==0){ 68 for(Course c : choose.getCourses()){ 69 if(c.getCourseName().equals(temp[2])){ 70 choose.addScore(new Score(st,c.getWeight())); 71 } 72 } 73 } 74 } 75 else System.out.println("wrong format"); 76 } 77 } 78 choose.getStuScore(); 79 choose.getCouScore(); 80 choose.getClaScore(); 81 } 82 } 83 84 class Choose { 85 private ArrayList<Course> courses = new ArrayList<>(); 86 private ArrayList<Score> scores = new ArrayList<>(); 87 private ArrayList<Student> students = new ArrayList<>(); 88 public ArrayList<Classroom> classrooms = new ArrayList<>(); 89 int classnum = 0; 90 public void addCourse(Course course) {//添加课程信息 91 if (course.getNature().equals("必修")) {//课程性质考试形式冲突 92 if (!course.getEvaluation_mode().equals("考试")) { 93 System.out.println(course.getCourseName() + " : course type & access mode mismatch"); 94 return; 95 } 96 } 97 if(!course.quan()){ 98 System.out.println(course.getCourseName()+" : number of scores does not match"); 99 // return; 100 } 101 if (!this.courses.isEmpty()) { 102 int n = 0; 103 for (Course c : courses) { 104 if (c.getCourseName().equals(course.getCourseName())) {//课程重名 105 n++; 106 } 107 } 108 if(n==0){ 109 courses.add(course); 110 } 111 } 112 else courses.add(course); 113 } 114 public void addScore(Score score) {//添加课程成绩信息 115 if (!this.courses.isEmpty()) { 116 int n = 0;//判断课程是否存在 117 for (Course c : courses) { 118 if (c.getCourseName().equals(score.getCourseName())) { 119 n++;//课程存在 120 if ((c.getEvaluation_mode().equals("考试") && (score.getItemList().size()!=2) 121 ||(c.getEvaluation_mode().equals("考察")&&(score.getItemList().size()!=1)))) { 122 //成绩与考核方式不匹配 123 System.out.println(score.getStudentId() + " " + score.getStudentName() + " : access mode mismatch"); 124 int xx = 0; 125 students.add(new Student(score.getStudentName(), score.getStudentId())); 126 for (Classroom cl : classrooms) { 127 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 128 xx++; 129 break; 130 } 131 } 132 if (xx == 0) {//新班级 133 classrooms.add(new Classroom(0, score.getStudentId().substring(0, 6))); 134 } 135 } 136 else { 137 scores.add(score); 138 c.addScore(score.thescore()); 139 140 int k = 0;//判断是不是新学生 141 for (Student s : students) { 142 if (s.getID().equals(score.getStudentId())) {//之前就存在这个学生 143 k = 1; 144 s.addScores(score); 145 int yy = 0; 146 for (Classroom cl : classrooms) { 147 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 148 cl.score += score.thescore(); 149 cl.k++; 150 yy++; 151 break; 152 } 153 } 154 } 155 } 156 if (k == 0) {//新学生 157 int xx = 0; 158 students.add(new Student(score.getStudentName(), score.getStudentId(), score)); 159 for (Classroom cl : classrooms) { 160 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 161 cl.score += score.thescore(); 162 cl.k++; 163 xx++; 164 break; 165 } 166 } 167 if (xx == 0) {//新班级 168 classrooms.add(new Classroom(score.thescore(), score.getStudentId().substring(0, 6))); 169 classnum++; 170 } 171 } 172 } 173 } 174 } 175 if (n == 0) {//课程不存在 176 System.out.println(score.getCourseName() + " does not exist"); 177 178 int xx = 0; 179 students.add(new Student(score.getStudentName(), score.getStudentId())); 180 for (Classroom cl : classrooms) { 181 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 182 xx++; 183 break; 184 } 185 } 186 if (xx == 0) {//新班级 187 classrooms.add(new Classroom(0, score.getStudentId().substring(0, 6))); 188 } 189 } 190 191 } 192 else{ 193 System.out.println(score.getCourseName() + " does not exist"); 194 195 int xx = 0; 196 students.add(new Student(score.getStudentName(), score.getStudentId())); 197 for (Classroom cl : classrooms) { 198 if (cl.cID.equals(score.getStudentId().substring(0, 6))) {//同一班级 199 xx++; 200 break; 201 } 202 } 203 if (xx == 0) {//新班级 204 classrooms.add(new Classroom(0, score.getStudentId().substring(0, 6))); 205 } 206 } 207 } 208 209 public void getStuScore(){//学生所有课程总成绩平均分 210 sortStu(); 211 for(Student s : students){ 212 if(s.getPjf() == 0){ 213 System.out.println(s.getID()+" "+s.getName() + " did not take any exams"); 214 215 } 216 else { 217 System.out.println(s.getID() +" "+s.getName()+ " "+s.getPjf()); 218 } 219 } 220 } 221 222 public void getCouScore(){ 223 Collections.sort(courses); 224 for(Course c: courses){ 225 if(c.getScore()==0){ 226 System.out.println(c.getCourseName()+" has no grades yet"); 227 } 228 else{ 229 if(c.getEvaluation_mode().equals("实验")){ 230 System.out.println(c.getCourseName()+" "+c.getScore()/c.getK()); 231 } 232 else if(c.getEvaluation_mode().equals("考察")){ 233 System.out.println(c.getCourseName()+" "+c.getScore()/c.getK()); 234 } 235 else { 236 System.out.println(c.getCourseName()+" "+c.getScore()/c.getK()); 237 } 238 } 239 } 240 } 241 public void getClaScore(){//班级平均分 242 sortCla(); 243 for(Classroom c:classrooms){ 244 c.getCScore(); 245 } 246 } 247 248 public void sortStu(){ 249 Collections.sort(students, new Comparator<Student>() { 250 @Override 251 public int compare(Student o1, Student o2) { 252 return o1.getID().compareTo(o2.getID()); 253 } 254 }); 255 } 256 257 public void sortCla(){ 258 Collections.sort(classrooms, new Comparator<Classroom>() { 259 @Override 260 public int compare(Classroom o1, Classroom o2) { 261 return o1.cID.compareTo(o2.cID); 262 } 263 }); 264 } 265 266 public ArrayList<Course> getCourses() { 267 return courses; 268 } 269 270 public void setCourses(ArrayList<Course> courses) { 271 this.courses = courses; 272 } 273 274 public ArrayList<Score> getScores() { 275 return scores; 276 } 277 278 public void setScores(ArrayList<Score> scores) { 279 this.scores = scores; 280 } 281 282 public ArrayList<Student> getStudents() { 283 return students; 284 } 285 286 public void setStudents(ArrayList<Student> students) { 287 this.students = students; 288 } 289 290 } 291 292 class Course implements Comparable<Course>{ 293 private String courseName ; //课程名称 294 private String nature = "必修"; //课程性质 295 private String access_mode = "考试"; //考核模式 296 private List<Double> weight = new ArrayList<>(); 297 private int score = 0; 298 private int k = 0; 299 private int c = 0; 300 //构造方法 301 public Course() { 302 303 } 304 public Course(String courseName,String nature,String access_mode,List<Double> weight) { 305 this.courseName = courseName; 306 this.nature = nature; 307 this.access_mode = access_mode; 308 this.weight = weight; 309 c++; 310 } 311 public void addScore(int s){ 312 score += s; 313 k++; 314 } 315 public void addShiYanScore(int score){ 316 score += score; 317 k++; 318 } 319 //getset方法 320 321 public List<Double> getWeight() { 322 return weight; 323 } 324 public boolean quan(){ 325 double x=0; 326 for(int i=0;i<weight.size();i++){ 327 x+=weight.get(i); 328 } 329 if(x==1){ 330 return true; 331 } 332 return false; 333 } 334 public void setWeight(List<Double> weight) { 335 this.weight = weight; 336 } 337 338 public int getC() { 339 return c; 340 } 341 342 public void setC(int c) { 343 this.c = c; 344 } 345 346 public String getCourseName() { 347 return courseName; 348 } 349 public void setCourseName(String courseName) { 350 this.courseName = courseName; 351 } 352 public String getNature() { 353 return nature; 354 } 355 public void setNature(String nature) { 356 this.nature = nature; 357 } 358 public String getEvaluation_mode() { 359 return access_mode; 360 } 361 public void setEvaluation_mode(String evaluation_mode) { 362 this.access_mode = evaluation_mode; 363 } 364 365 public String getAccess_mode() { 366 return access_mode; 367 } 368 369 public void setAccess_mode(String access_mode) { 370 this.access_mode = access_mode; 371 } 372 373 public int getScore() { 374 return score; 375 } 376 377 public void setScore(int score) { 378 this.score = score; 379 } 380 381 public int getK() { 382 return k; 383 } 384 385 public void setK(int k) { 386 this.k = k; 387 } 388 389 @Override 390 public int compareTo(Course o) { 391 Comparator<Object> c = Collator.getInstance(Locale.CHINA); 392 return ((Collator) c).compare(this.courseName,o.courseName); 393 } 394 } 395 class ItemScore{//分项成绩类 396 private double grade; // 成绩分值 397 private double weight; // 成绩权重 398 399 public double getGrade() { 400 return grade; 401 } 402 403 public void setGrade(double grade) { 404 this.grade = grade; 405 } 406 407 public double getWeight() { 408 return weight; 409 } 410 411 public void setWeight(double weight) { 412 this.weight = weight; 413 } 414 415 public double getGradeByWeight() { // 根据权重计算得分 416 return grade * weight; 417 } 418 } 419 class Score{ 420 private List<ItemScore> itemList = new ArrayList<>(); // 分项成绩列表 421 private String studentId; 422 private String studentName; 423 private String courseName; 424 public double getTotalGrade() { // 计算总成绩 425 double total = 0; 426 for (ItemScore item : itemList) { 427 total += item.getGradeByWeight(); 428 } 429 return total; 430 } 431 public Score(String line,List<Double> weight) { 432 String[] parts = line.split(" "); 433 studentId = parts[0]; 434 studentName = parts[1]; 435 courseName = parts[2]; 436 if(parts.length<=5){ 437 int u = parts.length > 4 ? Integer.parseInt(parts[3]) : 0; 438 itemList.get(0).setWeight(weight.get(0)); 439 itemList.get(0).setGrade(u); 440 int f = Integer.parseInt(parts[parts.length - 1]); 441 itemList.get(1).setWeight(weight.get(1)); 442 itemList.get(1).setGrade(f); 443 } 444 else{ 445 int j = 0; 446 if(parts.length==weight.size()+3){ 447 for(int i=3;i< parts.length;i++){ 448 itemList.add(new ItemScore()); 449 itemList.get(j).setWeight(weight.get(j)); 450 itemList.get(j).setGrade(Integer.parseInt(parts[i])); 451 j++; 452 } 453 } else { 454 System.out.println(studentId+" "+studentName+" : access mode mismatch"); 455 } 456 } 457 } 458 459 public int thescore(){ 460 return (int)getTotalGrade(); 461 } 462 463 public List<ItemScore> getItemList() { 464 return itemList; 465 } 466 467 public void setItemList(List<ItemScore> itemList) { 468 this.itemList = itemList; 469 } 470 471 public String getStudentId() { 472 return studentId; 473 } 474 public void setStudentId(String studentId) { 475 this.studentId = studentId; 476 } 477 public String getStudentName() { 478 return studentName; 479 } 480 public void setStudentName(String studentName) { 481 this.studentName = studentName; 482 } 483 public String getCourseName() { 484 return courseName; 485 } 486 public void setCourseName(String courseName) { 487 this.courseName = courseName; 488 } 489 } 490 class Student{ 491 private String name; 492 private String ID; 493 private ArrayList<Score> scores = new ArrayList<>(); 494 public Student(String name, String ID, Score scores) { 495 this.name = name; 496 this.ID = ID; 497 this.scores.add(scores); 498 } 499 public Student(String name,String ID){ 500 this.name = name; 501 this.ID = ID; 502 } 503 public void addScores(Score scores){ 504 this.scores.add(scores); 505 } 506 public int getPjf(){ 507 int pjf = 0; 508 for(Score s : scores){ 509 pjf += s.thescore(); 510 } 511 if(!scores.isEmpty()) 512 pjf = pjf/ scores.size(); 513 return pjf; 514 } 515 516 public String getName() { 517 return name; 518 } 519 520 public void setName(String name) { 521 this.name = name; 522 } 523 524 public String getID() { 525 return ID; 526 } 527 528 public void setID(String ID) { 529 this.ID = ID; 530 } 531 532 public ArrayList<Score> getScores() { 533 return scores; 534 } 535 public void setScores(ArrayList<Score> scores) { 536 this.scores = scores; 537 } 538 } 539 class Classroom{ 540 public int score = 0; 541 public String cID; 542 public int k = 0; 543 544 public Classroom(int score, String cID) { 545 this.score = score; 546 this.cID = cID; 547 if(score!=0){ 548 k++; 549 } 550 } 551 552 public void getCScore(){ 553 if( k == 0){ 554 System.out.println(cID+" has no grades yet"); 555 } 556 else{ 557 System.out.println(cID+" "+(int)(score/k)); 558 } 559 } 560 }
三、总结反思
四、课程建议与看法
1、本门课程的教学方法采用边讲边练的教学方式,老师在讲授知识的同时,也会辅以实例演示和练习,以帮助学生更好地掌握并运用所学知识。
2、本门课程采用线上线下混合式教学,能够同时兼顾线上、线下两方面的教学方式。但针对混合式教学,应当更加注重线上部分的教学质量和实时性。如果大家课前学习通视频观看完成率、线上交互较少,会影响学生的学习效果和体验,线上学习不到位会导致线下学习效率低,进而恶性循环。
3、本门课程采用PTA题目集驱动的教学过程,但是我们老师没有给我们讲解PTA题目或是对每次的题目编程情况进行知道,有可能导致学生不断犯错。在学生提交题目后,教师可以针对问题进行详讲和解答。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结