目錄: 1.前言 2.設計與分析 3.BUG與修正 4.缺陷與改進 5.總結 一、前言 題目集1的題目都是比較基礎的題,不需要用到其他的類,而且所有的題代碼行數都不超過40行。知識點集中在分支選擇和浮點數的處理上,題量適中,難度也較小。比較適合初學Java的學生來熟悉java,瞭解java與之前所學 ...
目錄:
1.前言
2.設計與分析
3.BUG與修正
4.缺陷與改進
5.總結
一、前言
題目集1的題目都是比較基礎的題,不需要用到其他的類,而且所有的題代碼行數都不超過40行。知識點集中在分支選擇和浮點數的處理上,題量適中,難度也較小。比較適合初學Java的學生來熟悉java,瞭解java與之前所學的c的區別。
題目集2的題目開始要求學生接觸Java的核心——類。部分題的代碼行數也超過100行。知識點集中在類的使用、字元的判斷上,題量適中,難度有些許上升。
題目集3的題目中除第二題外都較簡單,代碼行數都不超過160行。第二題難度較高,程式的邏輯比較複雜,對輸入異常的處理也較多,代碼行數超過350行。知識點較多,有多種類的配合使用、正則表達式、對輸入字元的分析。題量小,難度較大。
二、設計與分析
1.題目集2-7-1 成績計算-1-類、數組的基本運用
創建學生類,包含
屬性:學號(String)、姓名(String)、語文成績(int)、數學成績(int)、物理成績(int)
方法:計算總分、計算平均分
輸入5個學生的信息,將每個學生的信息封裝在一個學生對象中。
按輸入順序依次輸出5個學生的總分、平均分(精確到小數點後兩位,捨去部分按四捨五入規則計入最後一位)。
代碼如下:
1 import java.util.Scanner; 2 import java.text.DecimalFormat; 3 4 class Student{ 5 String ID; 6 String name; 7 int s1,s2,s3; 8 int all; 9 double average; 10 } 11 12 public class Main{ 13 public static void main(String args[]) 14 { 15 Scanner input = new Scanner(System.in); 16 Student stus[]= new Student[5]; 17 for(int i=0;i<5;i++) 18 { 19 stus[i] = new Student(); 20 21 stus[i].ID=input.next(); 22 stus[i].name=input.next(); 23 stus[i].s1=input.nextInt(); 24 stus[i].s2=input.nextInt(); 25 stus[i].s3=input.nextInt(); 26 27 stus[i].all=stus[i].s1+stus[i].s2+stus[i].s3; 28 stus[i].average=(double)stus[i].all/3; 29 DecimalFormat df = new DecimalFormat("#.00"); 30 31 System.out.println(stus[i].ID+" "+stus[i].name+" "+stus[i].all+" "+df.format(stus[i].average)); 32 } 33 } 34 }
分析:
此題較為簡單,只需要使用一個Student類便可解決,題目也沒要求輸入異常的判斷。值得註意的是題目要求輸出的數字格式為精確到小數點後兩位,捨去部分按四捨五入規則計入最後一位。因此需要java.text.DecimalFormat來對最後的輸出進行處理。
Student類中按照題目中的提示,擁有屬性學號、名字、三項成績,此外還記錄了總成績、和平均成績。類中沒有計算的方法,計算的過程全在主函數中。
2.題目集2-7-2 成績計算-2-關聯類
創建成績類,包含:
屬性:平時成績(int)、期末成績(int)
方法:計算總成績(計算規則:平時成績*0.4+期末成績*0.6,保留整數部分,小數部分直接丟棄)
創建學生類,包含:
屬性:學號(String)、姓名(String)、語文成績(成績類)、數學成績(成績類)、物理成績(成績類)
方法:計算總分、計算平均分
輸入3個學生的信息,將每個學生的信息封裝在一個學生對象中。
按輸入順序依次輸出3個學生的總分、平均分(精確到小數點後兩位,捨去部分按四捨五入規則計入最後一位)。
代碼如下:
1 import java.util.Scanner; 2 import java.text.DecimalFormat; 3 4 class Scores{ 5 int usual; 6 int fin; 7 8 int grades(){ 9 double gra; 10 gra = (double)usual*0.4 + (double)fin*0.6; 11 int res = (int)gra; 12 return res; 13 } 14 } 15 16 class Student{ 17 String ID; 18 String name; 19 Scores c = new Scores(); 20 Scores m = new Scores(); 21 Scores p = new Scores(); 22 23 int all() 24 { 25 int res; 26 res = c.grades()+m.grades()+p.grades(); 27 return res; 28 } 29 30 double usuaver() 31 { 32 double res; 33 res = (double)(c.usual+m.usual+p.usual)/3; 34 return res; 35 } 36 double finaver() 37 { 38 double res; 39 res = (double)(c.fin+m.fin+p.fin)/3; 40 return res; 41 } 42 double average() 43 { 44 double res; 45 res = (double)all()/3; 46 return res; 47 } 48 } 49 50 public class Main{ 51 public static void main(String args[]){ 52 Scanner input = new Scanner(System.in); 53 Student stus[] = new Student[3]; 54 55 for(int i=0;i<3;i++){ 56 String s; 57 stus[i] = new Student(); 58 for(int j=0;j<3;j++){ 59 stus[i].ID = input.next(); 60 stus[i].name = input.next(); 61 s = input.next(); 62 if(s.compareTo("語文")==0){ 63 stus[i].c.usual = input.nextInt(); 64 stus[i].c.fin = input.nextInt(); 65 } 66 if(s.compareTo("數學")==0){ 67 stus[i].m.usual = input.nextInt(); 68 stus[i].m.fin = input.nextInt(); 69 } 70 if(s.compareTo("物理")==0){ 71 stus[i].p.usual = input.nextInt(); 72 stus[i].p.fin = input.nextInt(); 73 } 74 } 75 DecimalFormat df = new DecimalFormat("#.00"); 76 System.out.println(stus[i].ID+" "+stus[i].name+" "+stus[i].all()+" "+df.format(stus[i].usuaver())+" "+df.format(stus[i].finaver())+" "+df.format(stus[i].average())); 77 } 78 } 79 }
分析:
此題是上一題的升級版,其他條件不變的前提下要求我們至少使用學生類和成績類,輸出也要求輸出總成績、平時成績、考試成績、平均成績。值得註意的是,題目之中只要求輸出總成績和平均成績,但測試用例和最後的提交都表明瞭還需要輸出平時成績和考試成績才是正確答案。
類圖:
Scores類負責記錄平時成績和考試成績,並且有一個計算最終成績的方法。Student類負責記錄一個學生的學號、姓名、成績信息,並且有計算四種成績的方法。
3.題目集3-7-2 課程成績統計程式-1
某高校課程從性質上分為:必修課、選修課,從考核方式上分為:考試、考察。
考試的總成績由平時成績、期末成績分別乘以權重值得出,比如平時成績權重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)成績平均分只取整數部分,小數部分丟棄
代碼如下:
1 import java.util.Scanner; 2 import java.util.Arrays; 3 import java.util.Comparator; 4 import java.text.Collator; 5 import java.util.regex.Pattern; 6 import java.util.regex.Matcher; 7 8 public class Main{ 9 public static void main(String[] args){ 10 Scanner input = new Scanner(System.in); 11 Class cla[] = new Class[100]; 12 Course cou[] = new Course[100]; 13 CS cs = new CS(); 14 int classnum=0; 15 int coursenum=0; 16 String[] s; 17 18 String s0 = input.nextLine(); 19 20 while(!s0.equals("end")) 21 { 22 if(!isLegal(s0)) 23 { 24 System.out.println("wrong format"); 25 s0 = input.nextLine(); 26 continue; 27 } 28 29 s =s0.split(" "); 30 if(s.length==3) 31 { 32 boolean isE = false; 33 boolean isM = false; 34 if(s[1].equals("必修")) isM = true; 35 if(s[2].equals("考試")) isE = true; 36 37 if(isM&&!isE) 38 { 39 System.out.println(s[0]+" : course type & access mode mismatch"); 40 s0 = input.nextLine(); 41 continue; 42 } 43 44 boolean isfindC = false; 45 for(int i=0;i<coursenum&&!isfindC;i++) 46 if(cou[i].name.equals(s[0])) 47 isfindC = true; 48 49 if(!isfindC) 50 { 51 cou[coursenum] = new Course(s[0],isM,isE); 52 coursenum++; 53 } 54 } 55 if(s.length>=4) 56 { 57 int Escore=0; 58 int Uscore=0; 59 int score=0; 60 if(s.length == 4) 61 { 62 63 Escore = Integer.parseInt(s[3]); 64 score = Escore; 65 } 66 if(s.length ==5) 67 { 68 Uscore = Integer.parseInt(s[3]); 69 Escore = Integer.parseInt(s[4]); 70 score = (int)(Escore*0.7+Uscore*0.3); 71 } 72 73 if(Uscore<0||Uscore>100||Escore<0||Escore>100) 74 { 75 System.out.println("wrong format"); 76 s0 = input.nextLine(); 77 continue; 78 } 79 80 int i; 81 boolean isfindC = false; 82 for(i=0;i<coursenum&&!isfindC;i++) 83 if(cou[i].name.equals(s[2])) 84 isfindC = true; 85 i=i-1; 86 87 if(!isfindC) 88 System.out.println(s[2]+" does not exist"); 89 90 boolean Snum = false; 91 if(isfindC) 92 { 93 if(cou[i].isExam&&s.length == 5||!cou[i].isExam&&s.length == 4) 94 Snum = true; 95 else System.out.println(s[0]+" "+s[1]+" : access mode mismatch"); 96 } 97 98 boolean isFindCS = false; 99 isFindCS = cs.isfind(s[1],s[2]); 100 101 if(!isfindC||!Snum||isFindCS); 102 else if(cou[i].isExam) 103 { 104 cou[i].addS(Escore,Uscore); 105 cs.addCS(s[1],s[2]); 106 } 107 else 108 { 109 cou[i].addS(Escore); 110 cs.addCS(s[1],s[2]); 111 } 112 113 114 115 boolean isfind = false; 116 for(i=0;i<classnum&&!isfind;i++) 117 if(cla[i].ID.equals(s[0].substring(0,6))) 118 isfind = true; 119 i=i-1; 120 121 if(!isfind) 122 { 123 cla[classnum] = new Class(s[0].substring(0,6)); 124 classnum++; 125 i=classnum-1; 126 } 127 128 if(!isFindCS) 129 cla[i].addS(s[0],s[1]); 130 if(isfindC&&Snum&&!isFindCS) 131 { 132 cla[i].addCS(s[0],score); 133 } 134 } 135 136 s0 = input.nextLine(); 137 } 138 139 Arrays.sort(cla,0,classnum,new Comparator<Class>() { 140 public int compare(Class a, Class b) { 141 return a.compareTo(b); 142 } 143 }); 144 145 Arrays.sort(cou,0,coursenum,new Comparator<Course>() { 146 public int compare(Course a, Course b) { 147 return a.compareTo(b); 148 } 149 }); 150 151 152 for(int i=0;i<classnum;i++) 153 cla[i].outputAllStu(); 154 155 for(int i=0;i<coursenum;i++) 156 cou[i].outputCourse(); 157 158 for(int i=0;i<classnum;i++) 159 cla[i].outputClass(); 160 161 162 input.close(); 163 } 164 165 public static boolean isLegal(String s) 166 { 167 String[] s0 =s.split(" "); 168 169 if(s0.length==3) 170 { 171 if(s.matches("[\\S]{1,10} (必修|選修) (考試|考察)")) 172 return true; 173 else return false; 174 } 175 if(s0.length==4) 176 { 177 if(s.matches("[0-9]{8} [\\S]{1,10} [\\S]{1,10} [0-9][0-9]?[0-9]?[0-9]?")) 178 return true; 179 else return false; 180 } 181 if(s0.length==5) 182 { 183 if(s.matches("[0-9]{8} [\\S]{1,10} [\\S]{1,10} [0-9][0-9]?[0-9]?[0-9]? [0-9][0-9]?[0-9]?[0-9]?")) 184 return true; 185 else return false; 186 } 187 188 return false; 189 } 190 } 191 192 class Student{ 193 String ID; 194 String name; 195 int allScores; 196 int Cnum; 197 198 Student(String ID,String name) 199 { 200 this.ID = ID; 201 this.name = name; 202 this.allScores = 0; 203 this.Cnum = 0; 204 } 205 206 void addC(int scores) 207 { 208 this.allScores += scores; 209 this.Cnum++; 210 } 211 212 void outputStu() 213 { 214 if(Cnum == 0) System.out.println(ID+" "+name+" did not take any exams"); 215 else System.out.println(ID+" "+name+" "+allScores/Cnum); 216 } 217 218 public int compareTo(Student stu) 219 { 220 return this.ID.compareTo(stu.ID); 221 } 222 } 223 224 class Class{ 225 Student[] stus; 226 String ID; 227 int allScores; 228 int CSnum; 229 int Snum; 230 231 Class(String ID) 232 { 233 stus = new Student[100]; 234 this.ID = ID; 235 allScores = 0; 236 CSnum = 0; 237 Snum = 0; 238 } 239 240 void addCS(String SID,int scores) 241 { 242 boolean isfind = false; 243 int i; 244