前言
這是第三次博客作業(yè),總結(jié)了近三次PTA大作業(yè)的完成情況,作業(yè)7、8次的大作業(yè)的小題目圍繞著HashMap、ArrayList和自定義接口來展開,大題目則是課程成績程序的第二次第三次迭代,因為第一次課程成績的程序?qū)懙慕Y(jié)構(gòu)不太好,于是重新寫的,第三次迭代并沒有拿到滿分,后面也沒有時間改了。期末考試則是由29個選擇題和四個編程題組成。
關(guān)于類和整個程序的設(shè)計:
類是面向?qū)ο缶幊讨械暮诵母拍?,通過類可以定義一組數(shù)據(jù)和與之相關(guān)的操作。在設(shè)計程序時,通常需要先考慮需要哪些對象和它們的屬性和行為,然后將這些信息組織成類的結(jié)構(gòu)。在類的設(shè)計中,需要考慮類的名稱、屬性、方法、訪問權(quán)限等方面。
除了類的設(shè)計,程序的整體設(shè)計也非常重要。程序的整體設(shè)計涉及到程序的架構(gòu)、模塊劃分、代碼組織方式、代碼風(fēng)格等方面。程序的整體設(shè)計需要遵循一些基本原則,如低耦合、高內(nèi)聚、模塊化等,以確保程序的可維護性、擴展性和可重用性。
在設(shè)計程序時,還需要考慮程序的性能、安全性、可靠性等方面。這些方面的考慮需要在程序開發(fā)的不同階段進行,例如在編碼階段需要考慮程序的性能優(yōu)化,而在測試階段需要考慮程序的安全性和可靠性。
三次題目集的知識點、題量、難度等情況:
(對于重難點題目將會給出完整題目)
第七次大作業(yè):
容器-HashMap:
HashMap是Java中常用的容器類之一,它實現(xiàn)了Map接口,用于存儲鍵值對。下面是HashMap的用法:
-
創(chuàng)建HashMap對象:
HashMap<Key類型, Value類型> hashMap = new HashMap<>();
-
添加元素:
hashMap.put(key, value);
-
獲取元素:
Value value = hashMap.get(key);
-
刪除元素:
hashMap.remove(key);
-
判斷鍵是否存在:
boolean containsKey = hashMap.containsKey(key);
-
判斷值是否存在:
boolean containsValue = hashMap.containsValue(value);
-
獲取HashMap的大?。?/p>
int size = hashMap.size();
-
遍歷HashMap:
// 遍歷鍵 for (Key key : hashMap.keySet()) { // 根據(jù)鍵獲取值 Value value = hashMap.get(key); // 處理值 } // 遍歷值 for (Value value : hashMap.values()) { // 處理值 } // 遍歷鍵值對 for (Map.Entry<Key, Value> entry : hashMap.entrySet()) { Key key = entry.getKey(); Value value = entry.getValue(); // 處理鍵值對 }
需要注意的是,HashMap中的鍵是唯一的,如果重復(fù)添加相同的鍵,后面的值會替代前面的值;值可以重復(fù)。此外,HashMap是無序的,元素的順序不保證一致。
除了基本的用法,還可以使用其他方法和構(gòu)造函數(shù)來滿足不同的需求,例如通過構(gòu)造函數(shù)指定初始容量和負載因子,使用putAll()方法將另一個Map中的元素添加到當(dāng)前HashMap中,使用isEmpty()方法判斷HashMap是否為空等。
7-3 課程成績統(tǒng)計程序-2
課程成績統(tǒng)計程序-2在第一次的基礎(chǔ)上增加了實驗課,以下加粗字體顯示為本次新增的內(nèi)容。
某高校課程從性質(zhì)上分為:必修課、選修課、實驗課,從考核方式上分為:考試、考察、實驗。
考試的總成績由平時成績、期末成績分別乘以權(quán)重值得出,比如平時成績權(quán)重0.3,期末成績權(quán)重0.7,總成績=平時成績*0.3+期末成績*0.7。
考察的總成績直接等于期末成績
實驗的總成績等于課程每次實驗成績的平均分
必修課的考核方式必須為考試,選修課可以選擇考試、考察任一考核方式。實驗課的成績必須為實驗。
1、輸入:
包括課程、課程成績兩類信息。
課程信息包括:課程名稱、課程性質(zhì)、考核方式(可選,如果性質(zhì)是必修課,考核方式可以沒有)三個數(shù)據(jù)項。
課程信息格式:課程名稱+英文空格+課程性質(zhì)+英文空格+考核方式
課程性質(zhì)輸入項:必修、選修、實驗
考核方式輸入選項:考試、考察、實驗
考試/考查課程成績信息包括:學(xué)號、姓名、課程名稱、平時成績(可選)、期末成績
考試/考查課程信息格式:學(xué)號+英文空格+姓名+英文空格+課程名稱+英文空格+平時成績+英文空格+期末成績
實驗課程成績信息包括:學(xué)號、姓名、課程名稱、實驗次數(shù)、每次成績
實驗次數(shù)至少4次,不超過9次
實驗課程信息格式:學(xué)號+英文空格+姓名+英文空格+課程名稱+英文空格+實驗次數(shù)+英文空格+第一次實驗成績+...+英文空格+最后一次實驗成績
以上信息的相關(guān)約束:
1)平時成績和期末成績的權(quán)重默認為0.3、0.7
2)成績是整數(shù),不包含小數(shù)部分,成績的取值范圍是【0,100】
3)學(xué)號由8位數(shù)字組成
4)姓名不超過10個字符
5)課程名稱不超過10個字符
6)不特別輸入班級信息,班級號是學(xué)號的前6位。
2、輸出:
輸出包含三個部分,包括學(xué)生所有課程總成績的平均分、單門課程成績平均分、單門課程總成績平均分、班級所有課程總成績平均分。
為避免誤差,平均分的計算方法為累加所有符合條件的單個成績,最后除以總數(shù)。
1)學(xué)生課程總成績平均分按學(xué)號由低到高排序輸出
格式:學(xué)號+英文空格+姓名+英文空格+總成績平均分
如果某個學(xué)生沒有任何成績信息,輸出:學(xué)號+英文空格+姓名+英文空格+"did not take any exams"
2)單門課程成績平均分分為三個分值:平時成績平均分(可選)、期末考試平均分、總成績平均分,按課程名稱的字符順序輸出
考試/考察課程成績格式:課程名稱+英文空格+平時成績平均分+英文空格+期末考試平均分+英文空格+總成績平均分
實驗課成績格式:課程名稱+英文空格+總成績平均分
如果某門課程沒有任何成績信息,輸出:課程名稱+英文空格+"has no grades yet"
3)班級所有課程總成績平均分按班級由低到高排序輸出
格式:班級號+英文空格+總成績平均分
如果某個班級沒有任何成績信息,輸出:班級名稱+英文空格+ "has no grades yet"
異常情況:
1)如果解析某個成績信息時,課程名稱不在已輸入的課程列表中,輸出:學(xué)號+英文空格+姓名+英文空格+":"+課程名稱+英文空格+"does not exist"
2)如果解析某個成績信息時,輸入的成績數(shù)量和課程的考核方式不匹配,輸出:學(xué)號+英文空格+姓名+英文空格+": access mode mismatch"
以上兩種情況如果同時出現(xiàn),按第一種情況輸出結(jié)果。
3)如果解析某個課程信息時,輸入的課程性質(zhì)和課程的考核方式不匹配,輸出:課程名稱+" : course type & access mode mismatch"
4)格式錯誤以及其他信息異常如成績超出范圍等,均按格式錯誤處理,輸出"wrong format"
5)若出現(xiàn)重復(fù)的課程/成績信息,只保留第一個課程信息,忽略后面輸入的。
信息約束:
1)成績平均分只取整數(shù)部分,小數(shù)部分丟棄
參考類圖(與第一次相同,其余內(nèi)容自行補充):
?
第八次大作業(yè):
容器-ArrayList:
ArrayList是Java中常用的動態(tài)數(shù)組類,它實現(xiàn)了List接口,用于存儲一組有序的元素。下面是ArrayList的用法:
-
創(chuàng)建ArrayList對象:
ArrayList<ElementType> arrayList = new ArrayList<>();
-
添加元素:
arrayList.add(element);
元素將會被添加到ArrayList的尾部。
-
獲取元素:
ElementType element = arrayList.get(index);
使用索引位置來獲取ArrayList中指定位置的元素,索引從0開始。
-
修改元素:
arrayList.set(index, newElement);
使用索引位置來替換ArrayList中指定位置的元素。
-
刪除元素:
arrayList.remove(index);
使用索引位置來刪除ArrayList中指定位置的元素。
-
判斷元素是否存在:
boolean containsElement = arrayList.contains(element);
使用contains()方法來判斷ArrayList中是否包含指定元素。
-
獲取ArrayList的大小:
int size = arrayList.size();
使用size()方法來獲取ArrayList的大小。
-
遍歷ArrayList:
for (ElementType element : arrayList) { // 處理元素 }
需要注意的是,ArrayList可以存儲任意類型的元素,包括基本類型的包裝類和自定義類型。ArrayList的容量會根據(jù)需要進行自動擴容,以適應(yīng)元素的添加。
除了上述基本用法,ArrayList還提供了許多其他方法,如addAll()方法可以將另一個集合中的元素添加到當(dāng)前ArrayList中,使用isEmpty()方法判斷ArrayList是否為空,使用clear()方法清空ArrayList中的所有元素等。
7-2 課程成績統(tǒng)計程序-3
課程成績統(tǒng)計程序-3在第二次的基礎(chǔ)上修改了計算總成績的方式,
要求:修改類結(jié)構(gòu),將成績類的繼承關(guān)系改為組合關(guān)系,成績信息由課程成績類和分項成績類組成,課程成績類組合分項成績類,分項成績類由成績分值和權(quán)重兩個屬性構(gòu)成。
完成課程成績統(tǒng)計程序-2、3兩次程序后,比較繼承和組合關(guān)系的區(qū)別。思考一下哪一種關(guān)系運用上更靈活,更能夠適應(yīng)變更。
題目最后的參考類圖未做修改,大家根據(jù)要求自行調(diào)整,以下內(nèi)容加粗字體顯示的內(nèi)容為本次新增的內(nèi)容。
某高校課程從性質(zhì)上分為:必修課、選修課、實驗課,從考核方式上分為:考試、考察、實驗。
考試的總成績由平時成績、期末成績分別乘以權(quán)重值得出,比如平時成績權(quán)重0.3,期末成績權(quán)重0.7,總成績=平時成績*0.3+期末成績*0.7。
考察的總成績直接等于期末成績
實驗的總成績等于課程每次實驗成績乘以權(quán)重后累加而得。
課程權(quán)重值在錄入課程信息時輸入。(注意:所有分項成績的權(quán)重之和應(yīng)當(dāng)?shù)扔?)
必修課的考核方式必須為考試,選修課可以選擇考試、考察任一考核方式。實驗課的成績必須為實驗。
1、輸入:
包括課程、課程成績兩類信息。
課程信息包括:課程名稱、課程性質(zhì)、考核方式、分項成績數(shù)量、每個分項成績的權(quán)重。
考試課信息格式:課程名稱+英文空格+課程性質(zhì)+英文空格+考核方式+英文空格+平時成績的權(quán)重+英文空格+期末成績的權(quán)重
考察課信息格式:課程名稱+英文空格+課程性質(zhì)+英文空格+考核方式
實驗課程信息格式:課程名稱+英文空格+課程性質(zhì)+英文空格+考核方式+英文空格+分項成績數(shù)量n+英文空格+分項成績1的權(quán)重+英文空格+。。。+英文空格+分項成績n的權(quán)重
實驗次數(shù)至少4次,不超過9次
課程性質(zhì)輸入項:必修、選修、實驗
考核方式輸入選項:考試、考察、實驗
考試/考查課程成績信息包括:學(xué)號、姓名、課程名稱、平時成績(可選)、期末成績
考試/考查課程成績信息格式:學(xué)號+英文空格+姓名+英文空格+課程名稱+英文空格+平時成績+英文空格+期末成績
實驗課程成績信息包括:學(xué)號、姓名、課程名稱、每次成績{在系列-2的基礎(chǔ)上去掉了(實驗次數(shù)),實驗次數(shù)要和實驗課程信息中輸入的分項成績數(shù)量保持一致}
實驗課程信息格式:學(xué)號+英文空格+姓名+英文空格+課程名稱+英文空格+第一次實驗成績+...+英文空格+最后一次實驗成績
以上信息的相關(guān)約束:
1)成績是整數(shù),不包含小數(shù)部分,成績的取值范圍是【0,100】
2)學(xué)號由8位數(shù)字組成
3)姓名不超過10個字符
4)課程名稱不超過10個字符
5)不特別輸入班級信息,班級號是學(xué)號的前6位。
2、輸出:
輸出包含三個部分,包括學(xué)生所有課程總成績的平均分、單門課程總成績平均分、班級所有課程總成績平均分。
為避免四舍五入誤差,
計算單個成績時,分項成績乘以權(quán)重后要保留小數(shù)位,計算總成績時,累加所有分項成績的權(quán)重分以后,再去掉小數(shù)位。
學(xué)生總成績/整個班/課程平均分的計算方法為累加所有符合條件的單個成績,最后除以總數(shù)。
1)學(xué)生課程總成績平均分按學(xué)號由低到高排序輸出
格式:學(xué)號+英文空格+姓名+英文空格+總成績平均分
如果某個學(xué)生沒有任何成績信息,輸出:學(xué)號+英文空格+姓名+英文空格+"did not take any exams"
2)單門課程成績按課程名稱的字符順序輸出
課程成績輸出格式:課程名稱+英文空格+總成績平均分
如果某門課程沒有任何成績信息,輸出:課程名稱+英文空格+"has no grades yet"
3)班級所有課程總成績平均分按班級由低到高排序輸出
格式:班級號+英文空格+總成績平均分
如果某個班級沒有任何成績信息,輸出:班級名稱+英文空格+ "has no grades yet"
異常情況:
1)如果解析某個成績信息時,課程名稱不在已輸入的課程列表中,輸出:學(xué)號+英文空格+姓名+英文空格+":"+課程名稱+英文空格+"does not exist"
2)如果解析某個成績信息時,輸入的成績數(shù)量和課程的考核方式不匹配,輸出:學(xué)號+英文空格+姓名+英文空格+": access mode mismatch"
以上兩種情況如果同時出現(xiàn),按第一種情況輸出結(jié)果。
3)如果解析某個課程信息時,輸入的課程性質(zhì)和課程的考核方式不匹配,輸出:課程名稱+" : course type & access mode mismatch"
4)格式錯誤以及其他信息異常如成績超出范圍等,均按格式錯誤處理,輸出"wrong format"
5)若出現(xiàn)重復(fù)的課程/成績信息,只保留第一個課程信息,忽略后面輸入的。
6)如果解析實驗課程信息時,輸入的分項成績數(shù)量值和分項成績權(quán)重的個數(shù)不匹配,輸出:課程名稱+" : number of scores does not match"
7)如果解析考試課、實驗課時,分項成績權(quán)重值的總和不等于1,輸出:課程名稱+" : weight value error"
信息約束:
1)成績平均分只取整數(shù)部分,小數(shù)部分丟棄
期末考試:
(這里只分析編程題)
前三題均為關(guān)于正方形、正三棱錐及其魔方的迭代問題:
在魔方問題的基礎(chǔ)上,
重構(gòu)類設(shè)計,實現(xiàn)列表內(nèi)魔方的排序功能(按照魔方的體積進行排序)。
提示:題目中RubikCube類要實現(xiàn)Comparable接口。
其中,Main類源碼如下(可直接拷貝使用):
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
String color;
int layer;
double side;
RubikCube cube;
ArrayList<RubikCube> list = new ArrayList<>();
int choice = input.nextInt();
while(choice != 0) {
switch(choice) {
case 1://SquareCube
color = input.next();
layer = input.nextInt();
side = input.nextDouble();
cube = new SquareCube(color, layer,new Cube(side));
list.add(cube);
break;
case 2://RegularPyramidCube
color = input.next();
layer = input.nextInt();
side = input.nextDouble();
cube = new RegularPyramidCube(color, layer,new RegularPyramid(side));
list.add(cube);
break;
}
choice = input.nextInt();
}
list.sort(Comparator.naturalOrder());//正向排序
for(int i = 0; i < list.size(); i++) {
System.out.print(list.get(i).getColor() + " " +
String.format("%.2f", list.get(i).getArea()) + " " +
String.format("%.2f", list.get(i).getVolume()) );
System.out.println("");
}
}
}
輸入格式:
輸入魔方類型(1:正方體魔方;2:正三棱錐魔方;0:結(jié)束輸入)
魔方顏色、魔方階數(shù)、魔方單元正方體、正三棱錐邊長
..循環(huán)..
輸出格式:
按魔方體積升序輸出列表中各魔方的信息(實型數(shù)均保留兩位小數(shù)),輸出樣式參見輸出樣例。
輸入樣例:
在這里給出一組輸入。例如:
1 blue 3 4.5
2 red 4 2.1
1 yellow 5 2.3
2 black 4 9.42
1 white 4 5.4423
0
輸出樣例:
在這里給出相應(yīng)的輸出。例如:
red 122.21 69.85
yellow 793.50 1520.88
blue 1093.50 2460.38
black 2459.14 6304.73
white 2843.39 10316.38
7-4 銷售步槍問題(附加題)
前亞利桑那州境內(nèi)的一位步槍銷售商銷售密蘇里州制造的步槍機(lock)、槍托(stock)和槍管(barrel)。槍機賣45美元,槍托賣30美元,槍管賣25美元。銷售商每月至少要售出一支完整的步槍,且生產(chǎn)限額是銷售商在一個月內(nèi)可銷售70個槍機、80個槍托和90個槍管。
根據(jù)每個月的銷售情況,計算銷售商的傭金(提成)算法如下:
-
不到(含)1000美元的部分為10%;
-
1000(含)~1800美元的部分為15%;
-
超過1800美元的部分為20%。
傭金程序生成月份銷售報告,匯總銷售商的銷售總額和傭金。
編程要求:必須符合面向?qū)ο缶幊?,且保證類設(shè)計的單一職責(zé)模式,使用面向過程編程判定0分。
提示:可以設(shè)置一個銷售訂單類。參考類圖如下:
輸入格式:輸入銷售商每個月售出槍機、槍托、槍管的數(shù)量,可以用空格或者回車分隔。
輸出格式:分別輸出銷售商在該月的銷售額和傭金,中間用空格分開。
輸入樣例1:
在這里給出一組輸入。例如:30 40 50
輸出樣例1:
在這里給出相應(yīng)的輸出。例如:3800.00 620.00
輸入樣例2:
在這里給出一組輸入。例如:88 56 98
輸出樣例2:
在這里給出相應(yīng)的輸出。例如:Wrong Format
設(shè)計與分析與主要問題和其解決方法
(這里只會提供重點題目的代碼)
第七次大作業(yè):
課程成績2:


1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStreamReader; 4 import java.text.Collator; 5 import java.util.*; 6 import java.util.Comparator; 7 import java.util.Locale; 8 import java.util.regex.PatternSyntaxException; 9 import java.util.stream.Collectors; 10 import java.util.stream.IntStream; 11 import java.util.List; 12 import java.util.ArrayList; 13 14 15 public class Main { 16 public static void main(String[] args) { 17 try (BufferedReader in = new BufferedReader(new InputStreamReader(System.in))) { 18 MessageGetAndPrint messageGetAndPrint = new MessageGetAndPrint(); 19 messageGetAndPrint.print = new Print(); 20 21 in.lines().takeWhile(line -> !line.equals("end")).forEach(messageGetAndPrint::getMessage); 22 23 messageGetAndPrint.print.personPrint(messageGetAndPrint.students, messageGetAndPrint.courseSelections); 24 messageGetAndPrint.print.coursePrint(messageGetAndPrint.courses, messageGetAndPrint.courseSelections); 25 messageGetAndPrint.print.classPrint(messageGetAndPrint.classes, messageGetAndPrint.courseSelections); 26 } catch (IOException e) { 27 e.printStackTrace(); 28 } 29 } 30 } 31 class Class { 32 private String classNum; 33 HashMap<String , Student> students; 34 Class(String classNum) { 35 setClassNum(classNum); 36 } 37 public void setClassNum(String classNum) { 38 this.classNum = classNum; 39 } 40 public String getClassNum() { 41 return classNum; 42 } 43 public void addStudent(Student student) { 44 students.put(student.getStudentNum() , student); 45 } 46 } 47 class Student { 48 private String name; 49 private String studentNum; 50 Student(String name , String studentNum) { 51 setName(name); 52 setStudentNum(studentNum); 53 } 54 public String getName() { 55 return name; 56 } 57 public void setName(String name) { 58 this.name = name; 59 } 60 public String getStudentNum() { 61 return studentNum; 62 } 63 public void setStudentNum(String studentNum) { 64 this.studentNum = studentNum; 65 } 66 } 67 class Course { 68 private String className; 69 private int classQuality; 70 private int assessmentMethodology; 71 Course(String className , int classQuality , int assessmentMethodology) { 72 setClassName(className); 73 setClassQuality(classQuality); 74 setAssessmentMethodology(assessmentMethodology); 75 } 76 public String getClassName() { 77 return className; 78 } 79 public void setClassName(String className) { 80 this.className = className; 81 } 82 public int getClassQuality() { 83 return classQuality; 84 } 85 public void setClassQuality(int classQuality) { 86 this.classQuality = classQuality; 87 } 88 public int getAssessmentMethodology() { 89 return assessmentMethodology; 90 } 91 public void setAssessmentMethodology(int assessmentMethodology) { 92 this.assessmentMethodology = assessmentMethodology; 93 } 94 } 95 class CourseSelection { 96 Student student; 97 Course course; 98 Grade grade; 99 } 100 abstract class Grade { 101 int allGrade; 102 abstract void getAllGrade(); 103 } 104 class GradeA extends Grade {//考試 105 private int finalGrade; 106 private int usualGrade; 107 GradeA(int finalGrade , int usualGrade) { 108 setFinalGrade(finalGrade); 109 setUsualGrade(usualGrade); 110 } 111 public void setFinalGrade(int finalGrade) { 112 this.finalGrade = finalGrade; 113 } 114 public int getFinalGrade() { 115 return finalGrade; 116 } 117 public void setUsualGrade(int usualGrade) { 118 this.usualGrade = usualGrade; 119 } 120 public int getUsualGrade() { 121 return usualGrade; 122 } 123 @Override 124 void getAllGrade() { 125 allGrade = (int) (finalGrade*0.7+usualGrade*0.3); 126 } 127 } 128 class GradeB extends Grade {//考察 129 private int finalGrade; 130 GradeB(int finalGrade) { 131 setFinalGrade(finalGrade); 132 } 133 public void setFinalGrade(int finalGrade) { 134 this.finalGrade = finalGrade; 135 } 136 public int getFinalGrade() { 137 return finalGrade; 138 } 139 @Override 140 void getAllGrade() { 141 allGrade = finalGrade; 142 } 143 } 144 class GradeC extends Grade {//實驗 145 ArrayList<Integer> usualGrades; 146 GradeC(ArrayList<Integer> usualGrades) { 147 this.usualGrades = usualGrades; 148 } 149 @Override 150 void getAllGrade() { 151 allGrade = 0; 152 for(int x:usualGrades){ 153 allGrade+=x; 154 } 155 allGrade = allGrade/usualGrades.size(); 156 } 157 } 158 class Print { 159 public void personPrint(HashMap<String , Student> students, ArrayList<CourseSelection> courseSelections) { 160 students.keySet().stream() 161 .sorted() 162 .forEach(key -> { 163 Student student = students.get(key); // 獲取當(dāng)前學(xué)生信息 164 int[] gradeData = courseSelections.stream() 165 .filter(cs -> cs.student.getStudentNum().equals(student.getStudentNum())) 166 .mapToInt(cs -> { 167 cs.grade.getAllGrade(); // 更新成績狀態(tài) 168 return cs.grade.allGrade; // 提取當(dāng)前的總成績 169 }) 170 .toArray(); 171 if (gradeData.length == 0) { // 沒有成績數(shù)據(jù) 172 System.out.println(student.getStudentNum() + " " + student.getName() + " did not take any exams"); 173 } else { 174 // 計算平均分并打印 175 int averageGrade = Arrays.stream(gradeData).sum() / gradeData.length; 176 System.out.println(student.getStudentNum() + " " + student.getName() + " " + averageGrade); 177 } 178 }); 179 } 180 public void coursePrint(HashMap<String, Course> courses, ArrayList<CourseSelection> courseSelections) { 181 courses.keySet().stream() 182 .sorted(new SoftName()) 183 .forEach(key -> { 184 Course course = courses.get(key); 185 // 根據(jù)課程篩選相關(guān)的選課記錄 186 List<CourseSelection> selected = new ArrayList<>(); 187 for (CourseSelection cs : courseSelections) { 188 if (cs.course.getClassName().equals(course.getClassName())) { 189 selected.add(cs); 190 } 191 } 192 193 if (selected.isEmpty()) { 194 System.out.println(course.getClassName() + " has no grades yet"); 195 return; 196 } 197 // 計算總分和平均分 198 double allGradesSum = 0; 199 double finalGradeSum = 0; 200 double usualGradeSum = 0; 201 int gradesCount = 0; 202 int usualGradesCount = 0; 203 204 for (CourseSelection cs : selected) { 205 cs.grade.getAllGrade(); 206 allGradesSum += cs.grade.allGrade; 207 if (cs.grade instanceof GradeA) { 208 finalGradeSum += ((GradeA) cs.grade).getFinalGrade(); // Final grade for GradeA 209 usualGradeSum += ((GradeA) cs.grade).getUsualGrade(); // Usual grade for GradeA 210 usualGradesCount++; 211 } else if (cs.grade instanceof GradeB) { 212 finalGradeSum += ((GradeB) cs.grade).getFinalGrade(); // Final grade for GradeB 213 } 214 gradesCount++; 215 } 216 double average = gradesCount > 0 ? allGradesSum / gradesCount : 0; 217 double averageFinal = gradesCount > 0 ? finalGradeSum / gradesCount : 0; 218 double averageUsual = usualGradesCount > 0 ? usualGradeSum / usualGradesCount : 0; 219 String output; 220 if (course.getAssessmentMethodology() == 3) { 221 output = String.format("%s %d", course.getClassName(), (int) average); 222 } else if (usualGradesCount == 0) { 223 output = String.format("%s %d %d", course.getClassName(), (int) averageFinal, (int) average); 224 } else { 225 output = String.format("%s %d %d %d", course.getClassName(), (int) averageUsual, (int) averageFinal, (int) average); 226 } 227 System.out.println(output); 228 }); 229 } 230 public void classPrint(HashMap<String, Class> classes, ArrayList<CourseSelection> courseSelections) { 231 classes.keySet().stream().sorted().forEach(classKey -> { 232 Class c = classes.get(classKey); 233 double average = courseSelections.stream() 234 .filter(cs -> c.students.containsKey(cs.student.getStudentNum())) 235 .mapToInt(cs -> cs.grade.allGrade) 236 .average() 237 .orElse(-1); // 使用 -1 來表示沒有成績的情況 238 239 String output = average == -1 ? 240 c.getClassNum() + " has no grades yet" : 241 c.getClassNum() + " " + (int) average; 242 243 System.out.println(output); 244 }); 245 } 246 public void wrongFormat() { 247 System.out.println("wrong format"); 248 } 249 public void course_not_Exist(String name) { 250 System.out.println(name+" does not exist"); 251 } 252 public void course_not_Match(String studentNum , String studentName) { 253 System.out.println(studentNum+" "+studentName+" : access mode mismatch"); 254 } 255 public void course_not_Match(String name) { 256 System.out.println(name+" : course type & access mode mismatch"); 257 } 258 static class SoftName implements Comparator<String> { 259 private static final Comparator<Object> localeComparator = Collator.getInstance(Locale.CHINA); 260 @Override 261 public int compare(String name1 , String name2) { 262 return localeComparator.compare(name1, name2); 263 } 264 } 265 } 266 class MessageGetAndPrint { 267 Print print; 268 HashMap<String , Class> classes = new HashMap<>(); 269 HashMap<String , Student> students = new HashMap<>(); 270 HashMap<String , Course> courses = new HashMap<>(); 271 ArrayList<CourseSelection> courseSelections = new ArrayList<>(); 272 public void getMessage(String getInput) { 273 String[] input = getInput.split(" "); 274 try { 275 if (input.length == 2 && input[1].equals("必修")) { 276 String courseName = input[0]; 277 if(!courses.containsKey(courseName)) { 278 int i = 1, j = 1; // 保留原代碼中的變量和邏輯 279 Course course = new Course(courseName, i, j); 280 courses.put(courseName, course); 281 } 282 } 283 } catch (PatternSyntaxException e) { 284 // 此處可以處理正則表達式的語法錯誤,但按照題設(shè)這里應(yīng)該沒有異常發(fā)生, 285 // 所以可以忽略。 286 } 287 if(getInput.matches("^(\\S{1,10})( )(必修|選修|實驗)( )(考試|考察|實驗)$")) { 288 String[] courseTypes = {"", "必修", "選修", "實驗"}; 289 String[] examTypes = {"", "考試", "考察", "實驗"}; 290 int courseTypeIndex = -1, examTypeIndex = -1; 291 for (int k = 1; k <= 3; k++) { 292 if (input[1].equals(courseTypes[k])) { 293 courseTypeIndex = k; 294 break; 295 } 296 } 297 for (int k = 1; k <= 3; k++) { 298 if (input[2].equals(examTypes[k])) { 299 examTypeIndex = k; 300 break; 301 } 302 } 303 if (courseTypeIndex == -1 || examTypeIndex == -1) { 304 // 未知的課程類型或考試類型,拋出異?;蛘吣J值 305 print.wrongFormat(); 306 } 307 if (!((courseTypeIndex == 1 && examTypeIndex == 1) // 必修+考試 308 || (courseTypeIndex == 2 && examTypeIndex == 2) // 選修+考察 309 || (courseTypeIndex == 3 && examTypeIndex == 3))) { // 實驗+實驗 310 print.course_not_Match(input[0]); 311 return; 312 } 313 if(courses.containsKey(input[0])) { 314 return; 315 } 316 Course course = new Course(input[0], courseTypeIndex, examTypeIndex); 317 courses.put(input[0], course); 318 return; 319 } 320 321 if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)( )([0-9]|[1-9][0-9]|100)$")) { 322 if (courseSelections.stream().anyMatch(cs -> cs.student.getStudentNum().equals(input[0]) 323 && cs.student.getName().equals(input[1]) 324 && cs.course.getClassName().equals(input[2]))) 325 return; 326 327 Student student = new Student(input[1], input[0]); 328 students.put(input[0], student); 329 330 String classNum = input[0].substring(0, 6); 331 classes.computeIfAbsent(classNum, key -> { 332 Class aClass = new Class(key); 333 aClass.students = new HashMap<>(); 334 return aClass; 335 }).students.put(input[0], student); 336 337 if (!courses.containsKey(input[2])) { 338 print.course_not_Exist(input[2]); 339 return; 340 } 341 342 if (courses.get(input[2]).getAssessmentMethodology() != 1) { 343 print.course_not_Match(input[0], input[1]); 344 return; 345 } 346 347 Course course = courses.get(input[2]); 348 CourseSelection courseSelection = new CourseSelection(); 349 courseSelection.student = student; 350 courseSelection.course = course; 351 courseSelection.grade = new GradeA(Integer.parseInt(input[4]), Integer.parseInt(input[3])); 352 courseSelections.add(courseSelection); 353 return; 354 } 355 356 if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|10{2})$")) { 357 if (courseSelections.stream().anyMatch(cs -> 358 cs.student.getStudentNum().equals(input[0]) && 359 cs.student.getName().equals(input[1]) && 360 cs.course.getClassName().equals(input[2]))) 361 return; 362 363 Student student = new Student(input[1], input[0]); 364 students.put(input[0], student); 365 366 String classNum = input[0].substring(0, 6); 367 classes.computeIfAbsent(classNum, key -> { 368 Class aClass = new Class(key); 369 aClass.students = new HashMap<>(); 370 return aClass; 371 }).addStudent(student); 372 373 if (!courses.containsKey(input[2])) { 374 print.course_not_Exist(input[2]); 375 return; 376 } 377 378 if (courses.get(input[2]).getAssessmentMethodology() != 2) { 379 print.course_not_Match(input[0], input[1]); 380 return; 381 } 382 383 Course course = courses.get(input[2]); 384 CourseSelection courseSelection = new CourseSelection(); 385 courseSelection.student = student; 386 courseSelection.course = course; 387 int finalGrade = Integer.parseInt(input[3]); 388 courseSelection.grade = new GradeB(finalGrade); 389 courseSelections.add(courseSelection); 390 return; 391 } 392 if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([4-9])( )((([0-9]|[1-9][0-9]|100)( ))+)([0-9]|[1-9][0-9]|100)$")) { 393 boolean selectionExists = courseSelections.stream().anyMatch(courseSelection -> 394 courseSelection.student.getStudentNum().equals(input[0]) && 395 courseSelection.student.getName().equals(input[1]) && 396 courseSelection.course.getClassName().equals(input[2]) 397 ); 398 if (selectionExists) { 399 return; 400 } 401 402 Student student = students.computeIfAbsent(input[0], num -> new Student(input[1], num)); 403 String classNum = input[0].substring(0, 6); 404 Class aClass = classes.computeIfAbsent(classNum, num -> { 405 Class newClass = new Class(num); 406 newClass.students = new HashMap<>(); 407 return newClass; 408 }); 409 aClass.addStudent(student); 410 411 Course course = courses.get(input[2]); 412 if (course == null) { 413 print.course_not_Exist(input[2]); 414 return; 415 } 416 417 if (course.getAssessmentMethodology() != 3) { 418 print.course_not_Match(input[0], input[1]); 419 return; 420 } 421 422 int usualNum = Integer.parseInt(input[3]); 423 if (input.length - 4 != usualNum) { 424 print.course_not_Match(input[0], input[1]); 425 return; 426 } 427 CourseSelection courseSelection = new CourseSelection(); 428 courseSelection.student = student; 429 courseSelection.course = courses.get(input[2]); 430 431 ArrayList<Integer> usualGrades = IntStream.rangeClosed(1, usualNum) 432 .mapToObj(t -> Integer.parseInt(input[3 + t])) 433 .collect(Collectors.toCollection(ArrayList::new)); 434 435 courseSelection.grade = new GradeC(usualGrades); 436 courseSelections.add(courseSelection); 437 return; 438 } 439 print.wrongFormat(); 440 } 441 }
類圖如下:
?
?設(shè)計思路:
-
創(chuàng)建必要的類(Course、Grade、Student、Class)來表示課程和成績相關(guān)的信息,定義合適的屬性和方法。
-
解析輸入的課程信息和成績信息:
- 通過字符串分割和正則表達式等方式,將輸入的信息解析為課程名稱、課程性質(zhì)、考核方式等課程信息。
- 根據(jù)課程性質(zhì)和考核方式,判斷成績信息應(yīng)該屬于哪種類型(考試、考察、實驗)的成績。
- 將成績信息解析為學(xué)號、姓名、課程名稱、平時成績、期末成績等成績信息。
-
根據(jù)課程信息和成績信息的約束,進行合法性檢查:
- 檢查課程信息中的課程性質(zhì)和考核方式是否匹配。
- 檢查成績是否超出范圍,例如平時成績和期末成績的取值范圍是[0,100]。
- 檢查學(xué)號、姓名等信息的合法性。
-
根據(jù)解析的數(shù)據(jù)構(gòu)建對象并進行數(shù)據(jù)處理:
- 創(chuàng)建Course對象,將課程信息存儲到HashMap或ArrayList中,用于后續(xù)處理和輸出。
- 創(chuàng)建Grade對象,將成績信息存儲到HashMap或ArrayList中,用于后續(xù)處理和輸出。
- 創(chuàng)建Student對象,根據(jù)成績信息計算總成績平均分并存儲到學(xué)生對象中。
- 創(chuàng)建Class對象,根據(jù)學(xué)生信息計算班級總成績平均分并存儲到班級對象中。
-
處理數(shù)據(jù)并輸出結(jié)果:
- 遍歷學(xué)生列表,按學(xué)號排序,并輸出每個學(xué)生的學(xué)號、姓名、總成績平均分。
- 遍歷課程列表,按課程名稱排序,并輸出每門課程的平時成績平均分、期末考試平均分、總成績平均分。
- 遍歷班級列表,按班級號排序,并輸出每個班級的班級號、總成績平均分。
-
處理異常情況:
- 如果遇到格式錯誤、數(shù)據(jù)不合法或者其他異常情況,輸出相應(yīng)的錯誤提示信息。
第八次大作業(yè):
課程成績3:


import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.concurrent.atomic.AtomicReference; public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); MessageGetAndPrint messageGetAndPrint = new MessageGetAndPrint(); messageGetAndPrint.print = new Print(); while (true) { String message = in.readLine(); if ("end".equals(message)) { messageGetAndPrint.print.personPrint(messageGetAndPrint.students, messageGetAndPrint.courseSelections); messageGetAndPrint.print.coursePrint(messageGetAndPrint.courses, messageGetAndPrint.courseSelections); messageGetAndPrint.print.classPrint(messageGetAndPrint.classes, messageGetAndPrint.courseSelections); break; } messageGetAndPrint.getMessage(message); } } } class Class { private String classNum; HashMap<String , Student> students; Class(String classNum) { setClassNum(classNum); } public void setClassNum(String classNum) { this.classNum = classNum; } public String getClassNum() { return classNum; } public void addStudent(Student student) { students.put(student.getStudentNum() , student); } } class Student { private String name; private String studentNum; Student(String name , String studentNum) { setName(name); setStudentNum(studentNum); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStudentNum() { return studentNum; } public void setStudentNum(String studentNum) { this.studentNum = studentNum; } } class Course { private String className; private int classQuality; private int assessmentMethodology; ArrayList<Float> weightFunction = new ArrayList<>(); Course(String className , int classQuality , int assessmentMethodology) { setClassName(className); setClassQuality(classQuality); setAssessmentMethodology(assessmentMethodology); } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public int getClassQuality() { return classQuality; } public void setClassQuality(int classQuality) { this.classQuality = classQuality; } public int getAssessmentMethodology() { return assessmentMethodology; } public void setAssessmentMethodology(int assessmentMethodology) { this.assessmentMethodology = assessmentMethodology; } } class CourseSelection { Student student; Course course; Grade grade; } class Grade { SubItemGrades subItemGrades = new SubItemGrades(); public int getGrade() { AtomicReference<Float> allGrades = new AtomicReference<>(0.0f); IntStream.range(0, subItemGrades.subItem.size()).forEach(i -> allGrades.updateAndGet(v -> v + subItemGrades.subItem.get(i) * subItemGrades.grades.get(i))); return allGrades.get().intValue(); } } class SubItemGrades { ArrayList<Integer> grades = new ArrayList<>(); ArrayList<Float> subItem = new ArrayList<>(); } class Print { public void personPrint(HashMap<String, Student> students, ArrayList<CourseSelection> courseSelections) { Map<String, List<CourseSelection>> courseSelectionsByStudent = courseSelections.stream() .collect(Collectors.groupingBy(cs -> cs.student.getStudentNum())); List<String> sortedStudentKeys = new ArrayList<>(students.keySet()); Collections.sort(sortedStudentKeys); sortedStudentKeys.forEach(key -> { StringBuilder output = new StringBuilder(students.get(key).getStudentNum() + " " + students.get(key).getName()); List<CourseSelection> studentCourseSelections = courseSelectionsByStudent.get(key); if (studentCourseSelections == null || studentCourseSelections.isEmpty()) { output.append(" did not take any exams"); } else { int averageGrade = studentCourseSelections.stream() .mapToInt(cs -> cs.grade.getGrade()) .sum() / studentCourseSelections.size(); output.append(" ").append(averageGrade); } System.out.println(output); }); } public void coursePrint(HashMap<String, Course> courses, ArrayList<CourseSelection> courseSelections) { Map<String, List<CourseSelection>> courseGrades = courseSelections.stream() .collect(Collectors.groupingBy(cs -> cs.course.getClassName())); courses.values().stream() .sorted(Comparator.comparing(Course::getClassName)) .map(Course::getClassName) .forEach(key -> { List<CourseSelection> gradeList = courseGrades.computeIfAbsent(key, k -> new ArrayList<>()); int averageGrade; if (!gradeList.isEmpty()) { averageGrade = gradeList.stream() .mapToInt(cs -> cs.grade.getGrade()) .sum() / gradeList.size(); System.out.printf("%s %d%n", key, averageGrade); } else { System.out.printf("%s has no grades yet%n", key); } }); } public void classPrint(HashMap<String, Class> classes, ArrayList<CourseSelection> courseSelections) { Map<String, List<CourseSelection>> classGrades = courseSelections.stream() .filter(cs -> classes.values().stream() .anyMatch(c -> c.students.containsKey(cs.student.getStudentNum()))) .collect(Collectors.groupingBy(cs -> classes.values().stream() .filter(c -> c.students.containsKey(cs.student.getStudentNum())) .findFirst().get().getClassNum())); classes.values().stream() .sorted(Comparator.comparing(Class::getClassNum)) .map(Class::getClassNum) .forEach(key -> { List<CourseSelection> gradeList = classGrades.computeIfAbsent(key, k -> new ArrayList<>()); int averageGrade; if (!gradeList.isEmpty()) { averageGrade = gradeList.stream() .mapToInt(cs -> cs.grade.getGrade()) .sum() / gradeList.size(); System.out.printf("%s %d%n", key, averageGrade); } else { System.out.printf("%s has no grades yet%n", key); } }); } public void wrongFormat() { System.out.println("wrong format"); } public void courseExist(String name) { System.out.println(name+" does not exist"); } public void courseMatch(String studentNum , String studentName) { System.out.println(studentNum+" "+studentName+" : access mode mismatch"); } public void courseMatch(String name) { System.out.println(name+" : course type & access mode mismatch"); } public void numMatch(String name) { System.out.println(name+" : number of scores does not match"); } public void weightValue(String name) { System.out.println(name+" : weight value error"); } } class MessageGetAndPrint { Print print; HashMap<String , Class> classes = new HashMap<>(); HashMap<String , Student> students = new HashMap<>(); HashMap<String , Course> courses = new HashMap<>(); ArrayList<CourseSelection> courseSelections = new ArrayList<>(); public void getMessage(String getInput) { String[] message = getInput.split(" "); if(getInput.matches("^(\\S{1,10})( )(必修|選修|實驗)( )(考試|考察|實驗)$") || getInput.matches("^(\\S{1,10})( )(必修|選修|實驗)( )(考試|考察|實驗)( )((0.(0)+[1-9]|0.[1-9][0-9]*)( )(0.(0)+[1-9]|0.[1-9][0-9]*)$)") || getInput.matches("^(\\S{1,10})( )(必修|選修|實驗)( )(考試|考察|實驗)( )([4-9])((( )(0.(0)+[1-9]|0.[1-9][0-9]*|1))*)(( )(0.(0)+[1-9]|0.[1-9][0-9]*))$") ) { int i=0,j=0; if (!courses.containsKey(message[0])) { switch (message[1]) { case "必修" : i = 1; case "選修" : i = 2; case "實驗" : i = 3; } switch (message[2]) { case "考試": j = 1; break; case "考察": j = 2; break; case "實驗": j = 3; break; } boolean mismatch = (i == 1 && j != 1) || (i == 3 && j != 3) || (i != 3 && j == 3); boolean invalidLength = (j == 1 && message.length != 5) || (j == 2 && message.length != 3) || (j == 3 && message.length - 4 != Integer.parseInt(message[3])); if (mismatch) { print.courseMatch(message[0]); } else if (invalidLength) { print.numMatch(message[0]); } else { Course course = new Course(message[0], i, j); float sumWeight = 0; if (j == 1 || j == 3) { for (int k = 0; k < (j == 1 ? 2 : Integer.parseInt(message[3])); k++) { float weight = Float.parseFloat(message[4 + k]); sumWeight += weight; course.weightFunction.add(weight); } } else { course.weightFunction.add(1F); sumWeight = 1; } if (Math.abs(sumWeight - 1) > 0.001) { print.weightValue(message[0]); } else { courses.put(message[0], course); } } } } else if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)$") || getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)( )([0-9]|[1-9][0-9]|100)$") || getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )((([0-9]|[1-9][0-9]|100)( ))*)([0-9]|[1-9][0-9]|100)$") ) { boolean courseSelectionExists = courseSelections.stream() .anyMatch(courseSelection -> courseSelection.student.getStudentNum().equals(message[0]) && courseSelection.student.getName().equals(message[1]) && courseSelection.course.getClassName().equals(message[2])); if (courseSelectionExists) { return; } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if (!classes.containsKey(classNum)) { Class aClass = new Class(classNum); aClass.students = new HashMap<>(); classes.put(classNum , aClass); } classes.get(classNum).addStudent(student); if (!(courses.containsKey(message[2]))) { print.courseExist(message[2]); } else { if (message.length - 3 != courses.get(message[2]).weightFunction.size()) { print.courseMatch(message[0], message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); Grade grade = new Grade(); IntStream.range(0, message.length - 3) .forEach(i -> grade.subItemGrades.grades.add(Integer.parseInt(message[3 + i]))); grade.subItemGrades.subItem = courses.get(message[2]).weightFunction; courseSelection.grade = grade; courseSelections.add(courseSelection); } } else print.wrongFormat(); } }
類圖如下:
?我并沒有通過所有的測試點,以下測試點并沒有通過:
題目的分析如下:
這道題目要求修改成績類的繼承關(guān)系為組合關(guān)系,使用組合關(guān)系將課程成績類和分項成績類組合起來。還新增了分項成績的權(quán)重屬性,并根據(jù)權(quán)重計算每個分項成績的總成績。
首先,需修改類結(jié)構(gòu)如下:
-
定義一個"Course"類,包含課程名稱、課程性質(zhì)、考核方式和分項成績數(shù)量等屬性,并提供相應(yīng)的構(gòu)造方法和訪問方法。
-
定義一個"GradeComponent"類,包含分項成績的分值和權(quán)重屬性,并提供相應(yīng)的構(gòu)造方法和訪問方法。
-
定義一個"CourseGrade"類,包含該門課程的所有分項成績和所屬的課程對象,通過組合關(guān)系與"Course"和"GradeComponent"類建立關(guān)聯(lián)。
-
定義一個"Grade"類,包含學(xué)號、姓名、成績列表(包含"CourseGrade"對象)等屬性,并提供相應(yīng)的構(gòu)造方法和訪問方法。
-
定義一個"Student"類,包含學(xué)號、姓名、成績列表(包含"CourseGrade"對象)等屬性,并提供添加成績、計算總成績平均分等方法。
-
定義一個"Class"類,包含班級號、學(xué)生列表等屬性,并提供按學(xué)號排序、計算班級總成績平均分等方法。
其次,修改計算總成績的方式:
-
考試課總成績的計算方法不變,仍然為將平時成績乘以平時成績的權(quán)重再加上期末成績乘以期末成績的權(quán)重。
-
實驗課總成績的計算方法變?yōu)閷⒚總€實驗成績乘以實驗成績的權(quán)重,并累加所有分項成績的總和。
期末考試:
?7-3 魔方排序問題


1 import java.util.Scanner; 2 import java.util.ArrayList; 3 import java.util.Comparator; 4 import java.math.BigDecimal; 5 import java.math.RoundingMode; 6 7 abstract class RubikCube implements Comparable<RubikCube>{ 8 protected String Color; 9 protected int layer; 10 Solid solid; 11 @Override 12 public int compareTo(RubikCube other) { 13 return this.getVolume().compareTo(other.getVolume()); 14 } 15 public RubikCube() { 16 } 17 public RubikCube(String Color,int layer,Solid solid){ 18 this.Color = Color; 19 this.layer = layer; 20 this.solid = solid; 21 } 22 23 public void setColor(String color) { 24 Color = color; 25 } 26 27 public String getColor() { 28 return Color; 29 } 30 31 public void setLayer(int layer) { 32 this.layer = layer; 33 } 34 35 public int getLayer() { 36 return layer; 37 } 38 39 public void setSolid(Solid solid) { 40 this.solid = solid; 41 } 42 43 public Solid getSolid() { 44 return solid; 45 } 46 public abstract double getArea(); 47 public abstract BigDecimal getVolume(); 48 49 } 50 51 class SquareCube extends RubikCube { 52 53 public SquareCube(String color, int layer, Solid solid) { 54 super(color, layer, solid); 55 } 56 57 @Override 58 public double getArea() { 59 double unitArea = solid.getArea(); 60 return unitArea * Math.pow(getLayer(), 2); // Total surface area 61 } 62 63 @Override 64 public BigDecimal getVolume() { 65 double unitVolume = solid.getVolume(); 66 BigDecimal value = new BigDecimal(unitVolume * Math.pow(getLayer(), 3)); 67 BigDecimal rounded = value.setScale(2, RoundingMode.HALF_UP); 68 return rounded; // Total volume 69 } 70 } 71 72 class RegularPyramidCube extends RubikCube { 73 74 public RegularPyramidCube(String color, int layer, Solid solid) { 75 super(color, layer, solid); 76 } 77 78 @Override 79 public double getArea() { 80 double unitArea = solid.getArea(); 81 return unitArea * getLayer() * getLayer(); 82 } 83 84 @Override 85 public BigDecimal getVolume() { 86 double unitVolume = solid.getVolume(); 87 return BigDecimal.valueOf(unitVolume * getLayer() * getLayer()*getLayer()); 88 } 89 } 90 abstract class Solid { 91 protected double side; 92 public Solid(){ 93 } 94 95 public void setSide(double side) { 96 this.side = side; 97 } 98 99 public double getSide() { 100 return side; 101 } 102 public Solid(double side) { 103 this.side = side; 104 } 105 106 public abstract double getArea(); 107 108 public abstract double getVolume(); 109 } 110 111 class Cube extends Solid { 112 public Cube(){ 113 } 114 public Cube(double side) { 115 super(side); 116 } 117 118 @Override 119 public double getArea() { 120 return 6 * side * side; 121 } 122 123 @Override 124 public double getVolume() { 125 return side * side * side; 126 } 127 } 128 129 class RegularPyramid extends Solid { 130 public RegularPyramid(double side) { 131 super(side); 132 } 133 134 public RegularPyramid(){ 135 } 136 private double getHeight() { 137 return Math.sqrt(side * side - (side / 2) * (side / 2)); 138 } 139 @Override 140 public double getArea() { 141 return (0.5 * side * side * Math.sin(Math.PI / 3) + (3 * side * getHeight() / 2)); 142 } 143 144 @Override 145 public double getVolume() { 146 return (Math.pow(side, 3) * Math.sqrt(2)) / 12; 147 } 148 } 149 150 public class Main { 151 public static void main(String[] args) { 152 // TODO Auto-generated method stub 153 Scanner input = new Scanner(System.in); 154 155 String color; 156 int layer; 157 double side; 158 RubikCube cube; 159 160 ArrayList<RubikCube> list = new ArrayList<>(); 161 162 int choice = input.nextInt(); 163 164 while(choice != 0) { 165 switch(choice) { 166 case 1://SquareCube 167 color = input.next(); 168 layer = input.nextInt(); 169 side = input.nextDouble(); 170 cube = new SquareCube(color, layer,new Cube(side)); 171 list.add(cube); 172 break; 173 case 2://RegularPyramidCube 174 color = input.next(); 175 layer = input.nextInt(); 176 side = input.nextDouble(); 177 cube = new RegularPyramidCube(color, layer,new RegularPyramid(side)); 178 list.add(cube); 179 break; 180 } 181 choice = input.nextInt(); 182 } 183 184 list.sort(Comparator.naturalOrder());//正向排序 185 186 for(int i = 0; i < list.size(); i++) { 187 System.out.print(list.get(i).getColor() + " " + 188 String.format("%.2f", list.get(i).getArea()) + " " + 189 String.format("%.2f", list.get(i).getVolume()) ); 190 System.out.println(""); 191 } 192 } 193 }
這題我并沒有拿到滿分,后來與同學(xué)交流發(fā)現(xiàn)可能是因為數(shù)據(jù)用的double類型,如果將所有的數(shù)據(jù)類型改變?yōu)锽igDecimal,就能過了測試點。
? Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數(shù)進行精確的運算。雙精度浮點型變量double可以處理16位有效數(shù),但在實際應(yīng)用中,可能需要對更大或者更小的數(shù)進行運算和處理。一般情況下,對于那些不需要準(zhǔn)確計算精度的數(shù)字,我們可以直接使用Float和Double處理,但是Double.valueOf(String) 和Float.valueOf(String)會丟失精度。所以開發(fā)中,如果我們需要精確計算的結(jié)果,則必須使用BigDecimal類來操作。
? BigDecimal所創(chuàng)建的是對象,故我們不能使用傳統(tǒng)的+、-、*、/等算術(shù)運算符直接對其對象進行數(shù)學(xué)運算,而必須調(diào)用其相對應(yīng)的方法。方法中的參數(shù)也必須是BigDecimal的對象。構(gòu)造器是類的特殊方法,專門用來創(chuàng)建對象,特別是帶有參數(shù)的對象。
7-4 銷售步槍問題(附加題)


1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner in = new Scanner(System.in); 6 int lockQuantity = in.nextInt(); 7 int stockQuantity = in.nextInt(); 8 int barrelQuantity = in.nextInt(); 9 10 try { 11 SalesOrder order = new SalesOrder(lockQuantity, stockQuantity, barrelQuantity); 12 System.out.printf("%.2f %.2f\n", order.calculateTotalSales(), order.calculateCommission()); 13 } catch (IllegalArgumentException e) { 14 System.out.println(e.getMessage()); 15 } 16 } 17 } 18 class Barrel { 19 static double UNIT_PRICE = 25; 20 public Barrel(){ 21 } 22 public Barrel(double UNIT_PRICE){ 23 this.UNIT_PRICE = UNIT_PRICE; 24 } 25 26 public static double getUnitPrice() { 27 return UNIT_PRICE; 28 } 29 30 public static void setUnitPrice(double unitPrice) { 31 UNIT_PRICE = unitPrice; 32 } 33 34 static boolean checkOrder(int quantity) { 35 return quantity >= 0 && quantity <= 90; 36 } 37 38 static double calculatePrice(int quantity) { 39 return quantity * UNIT_PRICE; 40 } 41 } 42 43 class Stock { 44 static double UNIT_PRICE = 30; 45 public static double getUnitPrice() { 46 return UNIT_PRICE; 47 } 48 49 public Stock(){ 50 } 51 public Stock(double UNIT_PRICE){ 52 this.UNIT_PRICE = UNIT_PRICE; 53 } 54 public static void setUnitPrice(double unitPrice) { 55 UNIT_PRICE = unitPrice; 56 } 57 58 static boolean checkOrder(int quantity) { 59 return quantity >= 0 && quantity <= 80; 60 } 61 62 static double calculatePrice(int quantity) { 63 return quantity * UNIT_PRICE; 64 } 65 } 66 67 68 class Lock { 69 static double UNIT_PRICE = 45; 70 71 public static double getUnitPrice() { 72 return UNIT_PRICE; 73 } 74 75 public Lock(){ 76 } 77 public Lock(double UNIT_PRICE){ 78 this.UNIT_PRICE = UNIT_PRICE; 79 } 80 public static void setUnitPrice(double unitPrice) { 81 UNIT_PRICE = unitPrice; 82 } 83 static boolean checkOrder(int quantity) { 84 return quantity >= 0 && quantity <= 70; 85 } 86 87 static double calculatePrice(int quantity) { 88 return quantity * UNIT_PRICE; 89 } 90 } 91 92 93 class SalesOrder { 94 95 int lockQuantity, stockQuantity, barrelQuantity; 96 97 SalesOrder(int lockQuantity, int stockQuantity, int barrelQuantity) { 98 if (!Lock.checkOrder(lockQuantity) || !Stock.checkOrder(stockQuantity) || !Barrel.checkOrder(barrelQuantity)) { 99 throw new IllegalArgumentException("Wrong Format"); 100 } 101 this.lockQuantity = lockQuantity; 102 this.stockQuantity = stockQuantity; 103 this.barrelQuantity = barrelQuantity; 104 } 105 106 double calculateTotalSales() { 107 return Lock.calculatePrice(lockQuantity) + Stock.calculatePrice(stockQuantity) + Barrel.calculatePrice(barrelQuantity); 108 } 109 110 double calculateCommission() { 111 double totalSales = calculateTotalSales(); 112 if (totalSales <= 1000) { 113 return totalSales * 0.1; 114 } else if (totalSales <= 1800) { 115 return 1000 * 0.1 + (totalSales - 1000) * 0.15; 116 } else { 117 return 1000 * 0.1 + 800 * 0.15 + (totalSales - 1800) * 0.2; 118 } 119 } 120 }
這題我也沒拿得到滿分差了1分,后來結(jié)束之后多看了下,發(fā)現(xiàn)是槍機的數(shù)量范圍不應(yīng)該是0-70而應(yīng)該是1-70。
?這題的結(jié)構(gòu)照著給出的類圖寫就好了。文章來源:http://www.zghlxwxcb.cn/news/detail-748652.html
總結(jié)
Java大作業(yè)終于結(jié)束了啊啊啊!不用每個星期都受折磨了TAT。雖然學(xué)習(xí)Java的過程非常痛苦,但是也學(xué)到了很多。其實關(guān)于Java還有很多內(nèi)容沒有學(xué)習(xí),越學(xué)越發(fā)現(xiàn)Java真的是一個很好的開發(fā)工具,有很多庫函數(shù)和各種輔助的類。但是我本身感覺只學(xué)習(xí)到了一點面向?qū)ο笤O(shè)計程序的思想,還需要繼續(xù)努力理解掌握學(xué)到的知識和探索學(xué)習(xí)新的知識。文章來源地址http://www.zghlxwxcb.cn/news/detail-748652.html
?
到了這里,關(guān)于第三次博客作業(yè)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!