前言

本次博客針對面向?qū)ο蟪绦蛟O(shè)計的課程所發(fā)的PTA作業(yè)7,8以及期末考試中的面向?qū)ο缶幊填}的分析和總結(jié),重點介紹課程成績統(tǒng)計程序系列題目以及期末考試的編程題。

PTA第七次作業(yè)

在這次作業(yè)中7-1、7-2內(nèi)容和考點相同,在此我分析一下7-2Hashmap的排序這個問題。

7-2 容器-HashMap-排序
分數(shù) 10
作者 蔡軻
單位 南昌航空大學

輸入多個學生的成績信息,包括:學號、姓名、成績。

學號是每個學生的唯一識別號,互不相同。

姓名可能會存在重復(fù)。

要求:使用HashMap存儲學生信息。

輸入格式:

輸入多個學生的成績信息,每個學生的成績信息格式:學號+英文空格+姓名+英文空格+成績

以“end”為輸入結(jié)束標志

輸出格式:

按學號從大到小的順序輸出所有學生信息,每個學生信息的輸出格式:學號+英文空格+姓名+英文空格+成績

輸入樣例:

在這里給出一組輸入。例如:

20201124 張少軍 83
20201136 李四 78
20201118 鄭覺先 80
end

輸出樣例:

在這里給出相應(yīng)的輸出。例如:

20201136 李四 78
20201124 張少軍 83
20201118 鄭覺先 80
這道題目的考點在于Hashmap容器的使用以及排序函數(shù)的使用,我的源代碼如下:
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        HashMap<String,String> hashMap = new HashMap<String,String>();
        while(true)
        {
            String str  =  input.nextLine();
            if(str.equals("end"))
            {
                break;
            }
            String str1[] = str.split(" ");
            String no = str1[0];
            String name = str1[1];
            String grade = str1[2];
            hashMap.put(no,name+" "+grade);
        }
        List<String> studentIds = new ArrayList<>(hashMap.keySet());

        // 按學號從大到小排序
        Collections.sort(studentIds, (s1, s2) -> Integer.parseInt(s2) - Integer.parseInt(s1));

        // 輸出學生信息
        for (String studentId : studentIds) {
            String studentInfo = hashMap.get(studentId);
            System.out.println(studentId + " " + studentInfo);
        }
    }
}
排序
 

  本次的代碼較短且復(fù)雜度很低,在此不贅述其類圖以及圈復(fù)雜度分析。

這次作業(yè)中難度較大的是課程成績統(tǒng)計程序-2,下面是這道題目的介紹和分析。

7-3 課程成績統(tǒng)計程序-2
分數(shù) 60
作者 蔡軻
單位 南昌航空大學

課程成績統(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ì)輸入項:必修、選修、實驗

考核方式輸入選項:考試、考察、實驗

考試/考查課程成績信息包括:學號、姓名、課程名稱、平時成績(可選)、期末成績

考試/考查課程信息格式:學號+英文空格+姓名+英文空格+課程名稱+英文空格+平時成績+英文空格+期末成績

實驗課程成績信息包括:學號、姓名、課程名稱、實驗次數(shù)、每次成績

實驗次數(shù)至少4次,不超過9次

實驗課程信息格式:學號+英文空格+姓名+英文空格+課程名稱+英文空格+實驗次數(shù)+英文空格+第一次實驗成績+...+英文空格+最后一次實驗成績

以上信息的相關(guān)約束:

1)平時成績和期末成績的權(quán)重默認為0.3、0.7

2)成績是整數(shù),不包含小數(shù)部分,成績的取值范圍是【0,100】

3)學號由8位數(shù)字組成

4)姓名不超過10個字符

5)課程名稱不超過10個字符

6)不特別輸入班級信息,班級號是學號的前6位。

2、輸出:

輸出包含三個部分,包括學生所有課程總成績的平均分、單門課程成績平均分、單門課程總成績平均分、班級所有課程總成績平均分。

為避免誤差,平均分的計算方法為累加所有符合條件的單個成績,最后除以總數(shù)。

1)學生課程總成績平均分按學號由低到高排序輸出

格式:學號+英文空格+姓名+英文空格+總成績平均分

如果某個學生沒有任何成績信息,輸出:學號+英文空格+姓名+英文空格+"did not take any exams"

2)單門課程成績平均分分為三個分值:平時成績平均分(可選)、期末考試平均分、總成績平均分,按課程名稱的字符順序輸出

考試/考察課程成績格式:課程名稱+英文空格+平時成績平均分+英文空格+期末考試平均分+英文空格+總成績平均分

實驗課成績格式:課程名稱+英文空格+總成績平均分

如果某門課程沒有任何成績信息,輸出:課程名稱+英文空格+"has no grades yet"

3)班級所有課程總成績平均分按班級由低到高排序輸出

格式:班級號+英文空格+總成績平均分

如果某個班級沒有任何成績信息,輸出:班級名稱+英文空格+ "has no grades yet"

異常情況:

1)如果解析某個成績信息時,課程名稱不在已輸入的課程列表中,輸出:學號+英文空格+姓名+英文空格+":"+課程名稱+英文空格+"does not exist"

2)如果解析某個成績信息時,輸入的成績數(shù)量和課程的考核方式不匹配,輸出:學號+英文空格+姓名+英文空格+": 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)容自行補充):


e724fa4193aa9ee32e78a68cd96fd6df_22401e04-c501-4b28-bb65-dabe39d374e7.png

 

輸入樣例1:

在這里給出一組輸入。例如:

java 實驗 實驗
20201103 張三 java 4 70 80 90
end

輸出樣例1:

在這里給出相應(yīng)的輸出。例如:

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:

在這里給出相應(yīng)的輸出。例如:

wrong format
java has no grades yet

輸入樣例3:

在這里給出一組輸入。例如:

java 必修 實驗
20201103 張三 java 3 70 80 90 100
end

輸出樣例3:

在這里給出相應(yīng)的輸出。例如:

java : course type & access mode mismatch
wrong format

輸入樣例4:

在這里給出一組輸入。例如:

java 必修 實驗
20201103 張三 java 4 70 80 90 105
end

輸出樣例4:

在這里給出相應(yīng)的輸出。例如:

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:

在這里給出相應(yīng)的輸出。例如:

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

這個題目是課程成績統(tǒng)計程序-1的升級,添加了實驗課的部分,修改了一部分輸入輸出以及錯誤的輸出,總體來說相比較第一次改動不大,以下是我的代碼:
  1 import java.util.*;
  2 import java.text.Collator;
  3 class Crouse{
  4     String name;
  5     String nature;
  6     String fangshi;
  7     ArrayList<Integer> pgrade = new ArrayList<>();
  8     ArrayList<Integer> qgrade = new ArrayList<>();
  9   ArrayList<Integer> grade = new ArrayList<>();
 10     public Crouse(String name, String nature, String fangshi) {
 11         this.name = name; // 將參數(shù)賦值給成員變量
 12         this.nature = nature; // 將參數(shù)賦值給成員變量
 13         this.fangshi = fangshi; // 將參數(shù)賦值給成員變量
 14     }
 15     public int average()
 16     {
 17         int total=0;
 18         for (int i:grade)
 19         {
 20             total+=i;
 21         }
 22         return total/grade.size();
 23     }
 24     public int average1()
 25     {
 26         int total=0;
 27         for (int i:pgrade)
 28         {
 29             total+=i;
 30         }
 31         return total/pgrade.size();
 32     }
 33     public int average2()
 34     {
 35         int total=0;
 36         for (int i:qgrade)
 37         {
 38             total+=i;
 39         }
 40         return total/qgrade.size();
 41     }
 42 
 43 }
 44 class Student {
 45     String id;
 46     String name;
 47     HashMap<String,Integer> crouse;
 48     public Student(String id, String name) {
 49         this.id = id; // 將參數(shù)賦值給成員變量
 50         this.name = name; // 將參數(shù)賦值給成員變量
 51         this.crouse = new HashMap<>();
 52     }
 53     public int averagegrade()
 54     {
 55         int total=0;
 56         for (Integer grade:crouse.values()) {
 57             total += grade;
 58         }
 59         return total/ crouse.size();
 60     }
 61 }
 62 class Class{
 63     String cid;
 64     ArrayList<Student> students = new ArrayList<>();
 65     public Class(String cid)
 66     {
 67         this.cid=cid;
 68     }
 69     public int average()
 70     {
 71         int total=0;
 72         for (Student s:students)
 73         {
 74             total+=s.averagegrade();
 75         }
 76         return total/students.size();
 77     }
 78 }
 79 class Holder{
 80     ArrayList<Crouse> clist = new ArrayList<>();
 81     ArrayList<Student> slist = new ArrayList<>();
 82     ArrayList<Class> Clist = new ArrayList<>();
 83 
 84     public Crouse searth(String name)
 85     {
 86         int falg =0;
 87         int i;
 88         for ( i = 0; i < clist.size(); i++) {
 89             if(clist.get(i).name.equals(name))
 90             {
 91                 falg++;
 92                 break;
 93             }
 94         }
 95         if(falg!=0)
 96         {
 97             return clist.get(i);
 98         }
 99         else return null;
100     }
101 }
102 public class Main {
103     public static void main(String[] args) {
104         Scanner input = new Scanner(System.in);
105         Holder holder = new Holder();
106         while (true) {
107             try {
108                 String str = input.nextLine();
109                 if (str.equals("end")) {
110                     break;
111                 }
112                 String[] str1 = str.split(" ");
113                 if (str1.length == 3) {
114                     if (str1[1].equals("必修")) {
115                         if (str1[2].equals("考試")) {
116                             String name = str1[0];
117                             String nature = str1[1];
118                             String fangshi = str1[2];
119                             Crouse crouse = null;
120                             for (Crouse c:holder.clist)
121                             {
122                                 if(c.name.equals(name)) {
123                                     crouse = c;
124                                     break;
125                                 }
126                             }
127                             if(crouse==null) {
128                                 crouse = new Crouse(name, nature, fangshi);
129                                 holder.clist.add(crouse);
130                             }
131                         } else {
132                             System.out.println(str1[0] + " : course type & access mode mismatch");
133                         }
134                     } else if (str1[1].equals("選修")) {
135                         if (str1[2].equals("考試")) {
136                             String name = str1[0];
137                             String nature = str1[1];
138                             String fangshi = str1[2];
139                             Crouse crouse = null;
140                             for (Crouse c:holder.clist)
141                             {
142                                 if(c.name.equals(name)) {
143                                     crouse = c;
144                                     break;
145                                 }
146                             }
147                             if(crouse==null) {
148                                 crouse = new Crouse(name, nature, fangshi);
149                                 holder.clist.add(crouse);
150                             }
151                         } else if (str1[2].equals("考察")) {
152                             String name = str1[0];
153                             String nature = str1[1];
154                             String fangshi = str1[2];
155                             Crouse crouse = null;
156                             for (Crouse c:holder.clist)
157                             {
158                                 if(c.name.equals(name)) {
159                                     crouse = c;
160                                     break;
161                                 }
162                             }
163                             if(crouse==null) {
164                                 crouse = new Crouse(name, nature, fangshi);
165                                 holder.clist.add(crouse);
166                             }
167                         } else {
168                             System.out.println(str1[0] + " : course type & access mode mismatch");
169                         }
170                     } else if (str1[1].equals("實驗")) {
171                         if (str1[2].equals("實驗")) {
172                             String name = str1[0];
173                             String nature = str1[1];
174                             String fangshi = str1[2];
175                             Crouse crouse = null;
176                             for (Crouse c:holder.clist)
177                             {
178                                 if(c.name.equals(name)) {
179                                     crouse = c;
180                                     break;
181                                 }
182                             }
183                             if(crouse==null) {
184                                 crouse = new Crouse(name, nature, fangshi);
185                                 holder.clist.add(crouse);
186                             }
187                         } else {
188                             System.out.println(str1[0] + " : course type & access mode mismatch");
189                         }
190                     }
191                 } else if (str1.length == 4)//選修,考察
192                 {
193                     if (Integer.parseInt(str1[3]) > 0 && Integer.parseInt(str1[3]) < 100) {
194                         if (holder.searth(str1[2]) != null) {
195                             String stuid = str1[0];
196                             String sname = str1[1];
197                             if (holder.searth(str1[2]).nature.equals("選修")) {
198                                 Student student = null;
199                                 for (Student s:holder.slist)
200                                 {
201                                     if(s.name.equals(sname))
202                                     {
203                                         student = s;
204                                         break;
205                                     }
206                                 }
207                                 String cid = stuid.substring(0, 6);
208                                 Class cla = null;
209                                 for (Class c : holder.Clist) {
210                                     if (c.cid.equals(cid)) {
211                                         cla = c;
212                                         break;
213                                     }
214                                 }
215                                 if (cla == null) {
216                                     cla = new Class(cid);
217                                     holder.Clist.add(cla);
218                                 }
219                                 if(student==null) {
220                                     student = new Student(stuid,sname);
221                                     student.crouse.put(str1[2], Integer.parseInt(str1[3]));
222                                     cla.students.add(student);
223                                     holder.slist.add(student);
224                                     holder.searth(str1[2]).grade.add(Integer.parseInt(str1[3]));
225                                 }
226                                 else {
227                                     student.crouse.put(str1[2], Integer.parseInt(str1[3]));
228                                     holder.searth(str1[2]).grade.add(Integer.parseInt(str1[3]));
229                                 }
230                             } else
231                                 System.out.println(stuid + " " + sname + " " + ": access mode mismatch");
232                         } else
233                             System.out.println(str1[0] + " " + str1[1] + " " + ":" + str1[2] + " " + "does not exist");
234                     } else System.out.println("wrong format");
235                 } else if (str1.length == 5)//必修或選修考試
236                 {
237                     if (holder.searth(str1[2]) != null) {
238                         String stuid = str1[0];
239                         String sname = str1[1];
240                         int grade = (int) (Integer.parseInt(str1[3]) * 0.3 + Integer.parseInt(str1[4]) * 0.7);
241                         Student student = null;
242                         for (Student s:holder.slist)
243                         {
244                             if(s.name.equals(sname))
245                             {
246                                 student = s;
247                                 break;
248                             }
249                         }
250 
251                         String cid = stuid.substring(0, 6);
252                         Class cla = null;
253                         for (Class c : holder.Clist) {
254                             if (c.cid.equals(cid)) {
255                                 cla = c;
256                                 break;
257                             }
258                         }
259                         if (cla == null) {
260                             cla = new Class(cid);
261                             holder.Clist.add(cla);
262                         }
263                         if(student==null) {
264                             student = new Student(stuid,sname);
265                             student.crouse.put(str1[2], grade);
266                             cla.students.add(student);
267                             holder.slist.add(student);
268                             holder.searth(str1[2]).grade.add(grade);
269                             holder.searth(str1[2]).pgrade.add(Integer.parseInt(str1[3]));
270                             holder.searth(str1[2]).qgrade.add(Integer.parseInt(str1[4]));
271                         }
272                         else {
273                             student.crouse.put(str1[2], grade);
274                             holder.searth(str1[2]).grade.add(grade);
275                             holder.searth(str1[2]).pgrade.add(Integer.parseInt(str1[3]));
276                             holder.searth(str1[2]).qgrade.add(Integer.parseInt(str1[4]));
277                         }
278                     } else
279                         System.out.println(str1[0] + " " + str1[1] + " " + ":" + str1[2] + " " + "does not exist");
280                 } else if (Integer.parseInt(str1[3]) > 3 && Integer.parseInt(str1[3]) < 10)//實驗
281                 {
282                     int num = Integer.parseInt(str1[3]);
283                     int falg = 0;
284                     for (int i = 4; i < str1.length; i++) {
285                         if (Integer.parseInt(str1[i]) < 0 || Integer.parseInt(str1[i]) > 100)
286                             falg++;
287                     }
288                     if (falg == 0) {
289                         if (holder.searth(str1[2]) != null) {
290                             String stuid = str1[0];
291                             String sname = str1[1];
292                             int grade = 0;
293                             if (str1.length == 4 + num) {
294                                 for (int i = 4; i < 4 + num; i++) {
295                                     grade += Integer.parseInt(str1[i]);
296                                 }
297                                 grade = grade / 4;
298                                 Student student = null;
299                                 for (Student s:holder.slist)
300                                 {
301                                     if(s.name.equals(sname))
302                                     {
303                                         student = s;
304                                         break;
305                                     }
306                                 }
307                                 String cid = stuid.substring(0, 6);
308                                 Class cla = null;
309                                 for (Class c : holder.Clist) {
310                                     if (c.cid.equals(cid)) {
311                                         cla = c;
312                                         break;
313                                     }
314                                 }
315                                 if (cla == null) {
316                                     cla = new Class(cid);
317                                     holder.Clist.add(cla);
318                                 }
319                                 if(student==null) {
320                                     student = new Student(stuid,sname);
321                                     student.crouse.put(str1[2], grade);
322                                     cla.students.add(student);
323                                     holder.slist.add(student);
324                                     holder.searth(str1[2]).grade.add(grade);
325                                 }
326                                 else {
327                                     student.crouse.put(str1[2], grade);
328                                     holder.searth(str1[2]).grade.add(grade);
329                                 }
330                             } else {
331                                 Student student = new Student(stuid, sname);
332                                 String cid = stuid.substring(0, 6);
333                                 Class cla = null;
334                                 for (Class c : holder.Clist) {
335                                     if (c.cid.equals(cid)) {
336                                         cla = c;
337                                         break;
338                                     }
339                                 }
340                                 if (cla == null) {
341                                     cla = new Class(cid);
342                                     holder.Clist.add(cla);
343                                 }
344                                 holder.slist.add(student);
345                                 System.out.println(stuid + " " + sname + " " + ": access mode mismatch");
346                             }
347                         } else
348                             System.out.println(str1[0] + " " + str1[1] + " " + ":" + str1[2] + " " + "does not exist");
349                     } else System.out.println("wrong format");
350                 } else
351                     System.out.println("wrong format");
352             }
353             catch (NumberFormatException e)
354             {
355                 System.out.println("wrong format");
356             }
357         }
358 
359         holder.slist.sort(Comparator.comparing(s -> s.id));
360         for(Student student:holder.slist)
361         {
362             if(student.crouse.isEmpty())
363             {
364                 System.out.println(student.id+" "+student.name+" "+"did not take any exams");
365             }
366             else  System.out.println(student.id+" "+student.name+" "+student.averagegrade());
367         }
368 
369         Collator collator = Collator.getInstance();
370         holder.clist.sort(Comparator.comparing(c -> c.name, collator));
371         for(Crouse crouse:holder.clist)
372         {
373             if(crouse.grade.isEmpty())
374             {
375                 System.out.println(crouse.name+" "+"has no grades yet");
376             }
377             else if(crouse.nature.equals("選修")&&crouse.fangshi.equals("考察"))
378                 System.out.println(crouse.name+" "+crouse.average()+" "+crouse.average());
379             else if(crouse.nature.equals("選修")&&crouse.fangshi.equals("考試"))
380                 System.out.println(crouse.name+" "+crouse.average1()+" "+crouse.average2()+" "+crouse.average());
381             else if(crouse.nature.equals("必修"))
382                 System.out.println(crouse.name+" "+crouse.average1()+" "+crouse.average2()+" "+crouse.average());
383             else if(crouse.nature.equals("實驗"))
384                 System.out.println(crouse.name+" "+crouse.average());
385         }
386         holder.Clist.sort(Comparator.comparing(c -> c.cid));
387         for(Class c:holder.Clist)
388         {
389             int falg=0;
390             for (Student s: c.students)
391             {
392                 if(s.averagegrade()==0)
393                 {
394                     falg++;
395                 }
396             }
397             if(falg==c.students.size())
398             {
399                 System.out.println(c.cid+" "+ "has no grades yet");
400             }
401             else
402                 System.out.println(c.cid+" "+c.average());
403         }
404     }
405 }

  Crouse類表示課程,包含課程名稱、課程性質(zhì)、考核方式以及成績列表。Student類表示學生,包含學號、姓名和課程成績的映射關(guān)系。Class類表示班級,包含班級號和學生列表。我用了一個holder類儲存課程鏈表、成績鏈表、以及班級鏈表,進而在Main類中通過循環(huán)輸出課程的平均成績、學生的平均成績、班級的平均成績以及對無成績的情況輸出。

該代碼的類圖如下:

 

用source moniter分析圈復(fù)雜度情況如下:

從圈復(fù)雜度以及代碼深度分析圖可以看出,我的代碼最大復(fù)雜性為91,平均復(fù)雜度為10.90,根據(jù)基維亞特圖可以看出我的代碼復(fù)雜度較高,平均運行時間長。

 


PTA第八次作業(yè)

 

7-2 課程成績統(tǒng)計程序-3
分數(shù) 64
作者 蔡軻
單位 南昌航空大學

課程成績統(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)當?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ì)輸入項:必修、選修、實驗

考核方式輸入選項:考試、考察、實驗

考試/考查課程成績信息包括:學號、姓名、課程名稱、平時成績(可選)、期末成績

考試/考查課程成績信息格式:學號+英文空格+姓名+英文空格+課程名稱+英文空格+平時成績+英文空格+期末成績

實驗課程成績信息包括:學號、姓名、課程名稱、每次成績{在系列-2的基礎(chǔ)上去掉了(實驗次數(shù)),實驗次數(shù)要和實驗課程信息中輸入的分項成績數(shù)量保持一致}

實驗課程信息格式:學號+英文空格+姓名+英文空格+課程名稱+英文空格+第一次實驗成績+...+英文空格+最后一次實驗成績

以上信息的相關(guān)約束:

1)成績是整數(shù),不包含小數(shù)部分,成績的取值范圍是【0,100】

2)學號由8位數(shù)字組成

3)姓名不超過10個字符

4)課程名稱不超過10個字符

5)不特別輸入班級信息,班級號是學號的前6位。

2、輸出:

輸出包含三個部分,包括學生所有課程總成績的平均分、單門課程總成績平均分、班級所有課程總成績平均分。

為避免四舍五入誤差,

計算單個成績時,分項成績乘以權(quán)重后要保留小數(shù)位,計算總成績時,累加所有分項成績的權(quán)重分以后,再去掉小數(shù)位。

學生總成績/整個班/課程平均分的計算方法為累加所有符合條件的單個成績,最后除以總數(shù)。

1)學生課程總成績平均分按學號由低到高排序輸出

格式:學號+英文空格+姓名+英文空格+總成績平均分

如果某個學生沒有任何成績信息,輸出:學號+英文空格+姓名+英文空格+"did not take any exams"

2)單門課程成績按課程名稱的字符順序輸出

課程成績輸出格式:課程名稱+英文空格+總成績平均分

如果某門課程沒有任何成績信息,輸出:課程名稱+英文空格+"has no grades yet"

3)班級所有課程總成績平均分按班級由低到高排序輸出

格式:班級號+英文空格+總成績平均分

如果某個班級沒有任何成績信息,輸出:班級名稱+英文空格+ "has no grades yet"

異常情況:

1)如果解析某個成績信息時,課程名稱不在已輸入的課程列表中,輸出:學號+英文空格+姓名+英文空格+":"+課程名稱+英文空格+"does not exist"

2)如果解析某個成績信息時,輸入的成績數(shù)量和課程的考核方式不匹配,輸出:學號+英文空格+姓名+英文空格+": 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ù)部分丟棄

參考類圖(與第一次相同,其余內(nèi)容自行補充):

fdada4ca193119ee30531ab82ffebbfa_9dbcf4e8-1627-4cf6-8764-cccf44947e2a.png

輸入樣例1:

在這里給出一組輸入。例如:

java 實驗 實驗 4 0.2 0.3 0.2 0.3
end

輸出樣例1:

在這里給出相應(yīng)的輸出。例如:

java has no grades yet

輸入樣例2:

在這里給出一組輸入。例如:

java 實驗 實驗 4 0.2 0.3 0.2
end

輸出樣例2:

在這里給出相應(yīng)的輸出。例如:

java : number of scores does not match

輸入樣例3:

在這里給出一組輸入。例如:

java 實驗 實驗 4 0.2 0.3 0.2 0.1
end

輸出樣例3:

在這里給出相應(yīng)的輸出。例如:

java : weight value error

輸入樣例4:

在這里給出一組輸入。例如:

java 實驗 實驗 4 0.2 0.3 0.2 0.3
20201116 張三 java 70 80 90 100
end

輸出樣例4:

在這里給出相應(yīng)的輸出。例如:

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:

在這里給出相應(yīng)的輸出。例如:

20201116 張三 : access mode mismatch
20201116 張三 did not take any exams
java has no grades yet
202011 has no grades yet

這道題目是對課程成績統(tǒng)計程序-2的升級,主要添加了實驗課的成績權(quán)重部分,將原來的平均模式改為了加權(quán)平均算法,并且改成了在課程信息中輸入實驗次數(shù)及權(quán)重,修改
了一部分輸入輸出以及錯誤的輸出。
我的代碼如下:
  1 import java.util.*;
  2 import java.text.*;
  3 public class Main {
  4     public static void main(String[] args) {
  5         Scanner scanner = new Scanner(System.in);
  6         Input_Format inputFormat = new Input_Format();//輸入
  7         Output_Format outputFormat = new Output_Format();//輸出
  8         Data_storage data_storage = new Data_storage();
  9         while (inputFormat.isEnd){
 10             String inputLine = scanner.nextLine();
 11             if(inputLine.equals("end")){
 12                 inputFormat.isEnd = false;
 13                 break;
 14             }
 15             inputFormat.inputProcessing(inputLine,data_storage);
 16         }
 17         PersonOverride student1 = new PersonOverride();
 18         outputFormat.outputProcessing(data_storage);
 19         outputFormat.output_all(data_storage);
 20     }
 21 }
 22 class Calculate_grades {
 23     int stu_all_grades(Data_storage data_storage,String num){//單個學生總課程平均分計算  返回一個分數(shù) 1)
 24         int count =0;//這個學生有幾門課
 25         int sum = 0;
 26         for (Map.Entry<String, Score> entry : data_storage.stu__st_cour.get(num).gradeMap.entrySet()) {
 27             Score value = entry.getValue();
 28             if(Integer.parseInt(value.total_scores)>=0) {
 29                 count++;
 30                 sum += Integer.parseInt(value.total_scores);
 31             }
 32         }
 33         if(count!=0)
 34             return sum/count;
 35         else
 36             return -100;//沒有參加任何考試
 37     }
 38     int[] single_course_grades(Data_storage data_storage,String name){ //2) 課程名
 39         int count = 0;
 40         int[] aver_grade = new int[3];//0:平時成績 1:期末考試 2:總分平均
 41         for (Map.Entry<String, StudentsAll_mes> e : data_storage.stu__st_cour.entrySet()) {//遍歷選課類:num-選課類
 42             StudentsAll_mes value = e.getValue();
 43             for (Map.Entry<String, Score> entry : value.gradeMap.entrySet()) {//遍歷選課類:course.name-Score
 44                 String key1 = entry.getKey();
 45                 Score value1 = entry.getValue();
 46                 if (key1.equals(name)) {
 47                     if(Integer.parseInt(value1.total_scores)>=0) {//總分為- 說明算成績無效
 48                         count++;
 49                         aver_grade[2] += Integer.parseInt(value1.total_scores);
 50                         if (value1 instanceof Test_Score) {
 51                             if (Integer.parseInt(value1.total_scores) >= 0) {
 52                                 aver_grade[0] += Integer.parseInt(((Test_Score) value1).normal_score);
 53                                 aver_grade[1] += Integer.parseInt(((Test_Score) value1).end_score);
 54                             }
 55                         } else if (value1 instanceof Inspect_Score){
 56                             if (Integer.parseInt(value1.total_scores) >= 0) {
 57                                 aver_grade[0] = -100;//不需要平時成績
 58                                 aver_grade[1] += Integer.parseInt(((Inspect_Score) value1).end_score);
 59                             }
 60                         }else if(value1 instanceof Lab_Score){
 61                             if(Integer.parseInt(value1.total_scores)>=0){
 62                                 aver_grade[0] = -100;
 63                                 aver_grade[1] += aver_grade[1] += Integer.parseInt(value1.total_scores);
 64                             }
 65                         }
 66                     }
 67                 }
 68             }
 69         }
 70         if(count!=0) {
 71             for (int i = 0; i < 3; i++) {
 72                 aver_grade[i] = aver_grade[i] / count;
 73             }
 74         }else {
 75             for (int i = 0; i < 3; i++) {
 76                 aver_grade[i] = -100;
 77             }
 78         }
 79         return aver_grade;
 80     }
 81     int Class_grades(Data_storage data_storage,String num){//3)
 82         int sum = 0;
 83         int count = 0;
 84         for (Map.Entry<String, Student> mapEntry : data_storage.classes.get(num).students.entrySet()) {//班級號-Student類
 85             Student value = mapEntry.getValue();//遍歷這個班級的所有學生
 86             for (Map.Entry<String, StudentsAll_mes> e : data_storage.stu__st_cour.entrySet()) {//stu_num-選課類
 87                 String key1 = e.getKey();//遍歷學生的選課類 學號
 88                 StudentsAll_mes value1 = e.getValue();
 89                 if (key1.equals(value.num)) {//選課類中 跟輸入的學號一樣
 90                     for (Map.Entry<String, Score> entry : value1.gradeMap.entrySet()) {//該num所有成績遍歷
 91                         Score gra = entry.getValue();
 92                         if(Integer.parseInt(gra.total_scores)>=0) {//有效才算
 93                             sum += Integer.parseInt(gra.total_scores);
 94                             count++;
 95                         }
 96                     }
 97                 }
 98             }
 99         }
100         if(count!=0)
101             return sum/count;
102         else
103             return -100;
104     }
105     void final_score(Data_storage data_storage,String num){//計算沒門課的成績 學號
106         data_storage.stu__st_cour.get(num).gradeMap.forEach((key,value)->{//學號  成績
107             if(value instanceof Test_Score&&((Test_Score) value).normal_score.matches("\\d+")&&((Test_Score) value).end_score.matches("\\d+")) {
108                 double tem = ((Test_Course) data_storage.courses.get(key)).normal_weight*Integer.parseInt(((Test_Score) value).normal_score);
109                 double tem1 = ((Test_Course) data_storage.courses.get(key)).end_weight*Integer.parseInt(((Test_Score) value).end_score);
110                 value.total_scores = String.valueOf((int)(tem+tem1));
111             }else if(value instanceof Inspect_Score&&((Inspect_Score) value).end_score.matches("\\d+")){
112                 value.total_scores = ((Inspect_Score) value).end_score;
113             }else if(value instanceof Lab_Score&&((Lab_Score) value).lab_num.matches("\\d+")){
114                 float sum = 0;
115                 int i=0;
116                 for (Integer score : ((Lab_Score) value).scores) {
117                     sum+= score* ((Lab_Course) data_storage.courses.get(key)).weights.get(i);
118                     i++;
119                 }
120                 value.total_scores = String.valueOf((int)sum);
121             }
122         });
123     }
124 }
125 class PersonOverride {
126     private String name;
127     private int age;
128     private boolean gender;
129 
130     public PersonOverride() {
131         this("default", 1, true);
132     }
133 
134     public PersonOverride(String name, int age, boolean gender) {
135         this.name = name;
136         this.age = age;
137         this.gender = gender;
138     }
139 
140     @Override
141     public String toString() {
142         return name + "-" + age + "-" + gender;
143     }
144 }
145 class Class {
146     String num;
147     TreeMap<String, Student> students = new TreeMap<>(); //班級里的學生 學號 學生
148     Class(String num){
149         this.num = num;
150     }
151 }
152 class Course {
153     String type;
154     String test_way;
155     String name;
156     Course(String name,String type, String test_way){
157         this.type = type;
158         this.name = name;
159         this.test_way = test_way;
160     }
161 }
162 class Inspect_Course extends Course{
163     Inspect_Course(String name, String type, String test_way) {
164         super(name, type, test_way);
165     }
166 }
167 
168 class Test_Course extends Course{
169     double normal_weight;
170     double end_weight;
171 
172     Test_Course(String name, String type, String test_way,String normal_weight,String end_weight) {
173         super(name, type, test_way);
174         this.normal_weight = Float.parseFloat(normal_weight);
175         this.end_weight = Float.parseFloat(end_weight);
176     }
177 }
178 class Lab_Course extends Course{
179     int sub_scores_num;
180     ArrayList<Float> weights = new ArrayList<>();
181     Lab_Course(String name, String type, String test_way,String line) {
182         super(name, type, test_way);
183         String[] lines = line.split(" ");
184         sub_scores_num = Integer.parseInt(lines[3]);
185         for(int i=4;i<lines.length; i++){
186             weights.add(Float.parseFloat(lines[i]));
187         }
188     }
189 }
190 class Data_storage {
191     TreeMap<String , Course> courses;//課程  k:課程名 v:課程
192     TreeMap<String, Class> classes = new TreeMap<>();//班級 k:班級號V:班級
193     TreeMap<String, StudentsAll_mes> stu__st_cour;//選課類學生類結(jié)合 k:學號 v:選課類
194     InAndOut_put output = new InAndOut_put();
195     Data_storage(){
196         //學生和選課類結(jié)合
197         stu__st_cour = new TreeMap<>(Data_storage::compare);//重寫排序
198         courses = new TreeMap<>(Data_storage::compare);
199     }
200 
201     private static int compare(String o1, String o2) {
202 
203         try {
204             Comparator<Object> comparator = Collator.getInstance(Locale.CHINA);
205             if (comparator.compare(o1, o2) < 0) {
206                 return -1;
207             } else if (comparator.compare(o1, o2) > 0) {
208                 return 1;
209             }
210         } catch (Exception ignored) {
211         }
212         return 0;
213     }
214 
215     void setInspectCourses(String name, String type, String test_way){
216         if(!courses.containsKey(name)) {
217             courses.put(name, new Inspect_Course(name, type, test_way));
218         }
219     }
220     void setTestCourses(String name, String type, String test_way,String normal_weight, String end_weight){
221         if(!courses.containsKey(name)) {
222             courses.put(name, new Test_Course(name, type, test_way,normal_weight, end_weight));
223         }
224     }
225     void setLabCourses(String name, String type, String test_way,String line){
226         if(!courses.containsKey(name)) {
227             courses.put(name, new Lab_Course(name, type, test_way,line));
228         }
229     }
230     void setClasses(String num){
231         if(!classes.containsKey(num)) {
232             classes.put(num, new Class(num));
233         }
234     }
235     void setStudents(String clas_num, String name, String num){//班級號 姓名 學號
236         if(classes.containsKey(clas_num)){
237             if(!classes.get(clas_num).students.containsKey(num))
238                 classes.get(clas_num).students.put(num,new Student(name,num));
239         }
240     }
241     void setStu__st_courAndMap(String num,String course,String normal_score,String end_score){//添加選課類  學生姓名 課程名稱 分數(shù)
242         if(!stu__st_cour.containsKey(num)){
243             stu__st_cour.put(num,new StudentsAll_mes(num,course,normal_score,end_score));
244         }
245         else{
246             stu__st_cour.get(num).setGradeMap(course,normal_score,end_score);
247         }
248     }
249     void setStu__st_courAndMap(String num,String course,String end_score){
250         if(!stu__st_cour.containsKey(num)){
251             stu__st_cour.put(num,new StudentsAll_mes(num,course,end_score));
252         }
253         else{
254             stu__st_cour.get(num).setGradeMap(course,end_score);
255         }
256     }
257     void set_lab_grades(String stu_num,String course,String lab_num,String grades){
258         ArrayList<Integer> scores = new ArrayList<>();
259         String[] tem = grades.split(" ");
260         for(int i=3;i<tem.length;i++){
261             if(tem[i].matches("\\d+"))
262                 scores.add(Integer.parseInt(tem[i]));
263         }
264         if(!stu__st_cour.containsKey(stu_num)){
265             StudentsAll_mes tem_stu_mes = new StudentsAll_mes();
266             tem_stu_mes.set_lab_stu_mes(stu_num,course,lab_num,scores);
267             stu__st_cour.put(stu_num,tem_stu_mes);
268         }else{
269             stu__st_cour.get(stu_num).set_lab_gradeMap(course,lab_num,scores);
270         }
271     }
272 }
273 class Input_Format {
274     String regex_c_test = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|選修)\\s考試\\s((0.\\d{1,2})|(1-9?))\\s((0.\\d{1,2})|(1-9?))$";
275     String regex_c_inspect = "[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s選修\\s考察$";
276     String regex_c_lab = "^[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s實驗\\s實驗\\s[4-9]\\s((0.\\d{1,2})|(1-9?))(\\s((0.\\d{1,2})|(1-9?))){3,9}$";
277     String regex_CS = "^\\d{8}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s+[\\u4E00-\\u9FA5A-Za-z0-9]{1,10}\\s*((100)|(\\d{1,2})|(0))?\\s+((100)|(\\d{1,2})|(0))$";
278     String regex_lab = "^\\d{8}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s((100)|([1-9]\\d)|\\d)(\\s((100)|([1-9]\\d)|\\d)){2,9}$";
279     boolean isEnd = true;//結(jié)束標志
280     String[] strings;
281     void inputProcessing(String line,Data_storage data_storage) {
282         lineProcessing(line);//分割
283         data_storage.output.add_input(line);//存儲
284         if(line.matches(regex_c_inspect)){
285             data_storage.setInspectCourses(strings[0],strings[1],strings[2]);
286         }else if(line.matches(regex_c_lab)){
287             data_storage.setLabCourses(strings[0],strings[1],strings[2],line);
288         }else if(line.matches(regex_c_test)){
289             data_storage.setTestCourses(strings[0],strings[1],strings[2],strings[3],strings[4]);//成績信息
290         } else if(line.matches(regex_CS)||line.matches(regex_lab)){
291             data_storage.setClasses(strings[0].substring(0,6));
292             data_storage.setStudents(strings[0].substring(0, 6), strings[1], strings[0]);//學生的添加
293             if (data_storage.courses.containsKey(strings[2])) {//課程里有這個課
294                 if (data_storage.courses.get(strings[2]).type.equals("選修")) {//
295                     if (data_storage.courses.get(strings[2]).test_way.equals("考試")&&strings.length == 5) {
296                         data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3], strings[4]);
297                     }else if(data_storage.courses.get(strings[2]).test_way.equals("考察")&&strings.length==4){
298                         data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3]);
299                     } else {
300                         data_storage.setStu__st_courAndMap(strings[0], strings[2], "no access", "no access");
301                     }
302                 } else if (data_storage.courses.get(strings[2]).type.equals("必修")) {//
303                     if (strings.length == 5) {
304                         data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3],strings[4]);
305                     } else {//無效
306                         data_storage.setStu__st_courAndMap(strings[0], strings[2], "no access", "no access");
307                     }
308                 } else if(data_storage.courses.get(strings[2]).type.equals("實驗")){
309                     if(strings.length == 3+((Lab_Course) data_storage.courses.get(strings[2])).sub_scores_num){
310                         data_storage.set_lab_grades(strings[0],strings[2], String.valueOf(((Lab_Course) data_storage.courses.get(strings[2])).sub_scores_num),line);
311                     }else{
312                         data_storage.set_lab_grades(strings[0],strings[2],"num error","no access");
313                     }
314                 }
315             }else{
316                 data_storage.setStu__st_courAndMap(strings[0], strings[2], "not exist");
317             }
318         }
319     }
320     void lineProcessing(String line){
321         strings = line.split(" ");
322     }
323 }
324 class Inspect_Score extends Score{
325     String end_score;
326     Inspect_Score(String end_score) {
327         this.end_score = end_score;
328     }
329 }
330 class  Output_Format {
331     Calculate_grades calculate = new Calculate_grades();
332     String regex_c_test = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|選修|實驗)\\s(考試|考察|實驗)\\s((\\d{1,2})|(1-9?))\\s((\\d{1,2})|(1-9?))$";
333     String regex_c_test_e = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|選修|實驗)\\s(考試|考察|實驗)\\s((0.\\d{1,2})|(1-9?))\\s((0.\\d{1,2})|(1-9?))$";
334     String regex_c_inspect = "[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|選修|實驗)\\s(考試|考察|實驗)$";
335     String regex_c_lab = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|選修|實驗)\\s(考試|考察|實驗)\\s[4-9]\\s((0.\\d{1,2})|(1-9?))(\\s((0.\\d{1,2})|(1-9?))){1,10}$";
336     String regex_CS = "^\\d{8}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s*((100)|(\\d{1,2})|(0))?\\s+((100)|(\\d{1,2})|(0))$";
337     String regex_lab = "^\\d{8}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s((100)|([1-9]\\d)|\\d)(\\s((100)|([1-9]\\d)|\\d)){1,20}$";
338     void outputProcessing(Data_storage data) {
339         data.classes.forEach((num,Class)-> Class.students.forEach((name, student)-> calculate.final_score(data,student.num)));
340         for(String i:data.output.input){
341             String[] tem = i.split(" ");
342             if(i.matches(regex_c_test_e)||i.matches(regex_c_test)||i.matches(regex_c_inspect)||i.matches(regex_c_lab)){
343                 if(tem[1].equals("必修")&&(tem[2].equals("考察")||tem[2].equals("實驗"))){
344                     data.output.add_output(tem[0] + " : course type & access mode mismatch");
345                 }else if(tem[1].equals("實驗")&&!tem[2].equals("實驗")) {
346                     data.output.add_output(tem[0] + " : course type & access mode mismatch");
347                 }else if(tem[1].equals("選修")&&tem[2].equals("實驗")) {
348                     data.output.add_output(tem[0] + " : course type & access mode mismatch");
349                 }
350                 if(tem[1].equals("實驗")&&tem[2].equals("實驗")) {
351                     if(tem.length-4>=4&&tem.length - 4<=9) {
352                         if (Integer.parseInt(tem[3]) != tem.length - 4) {
353                             data.output.add_output(tem[0] + " : number of scores does not match");
354                             data.courses.remove(tem[0]);
355                             continue;
356                         }
357                         float tem_weight = 0;
358                         for (int j = 4; j < tem.length; j++) {
359                             tem_weight += Float.parseFloat(tem[j]);
360                         }
361                         if (Math.abs(tem_weight - 1) > 0.0001) {
362                             data.output.add_output(tem[0] + " : weight value error");
363                             data.courses.remove(tem[0]);
364                             continue;
365                         }
366                     }else{
367                         try {
368                             if (Integer.parseInt(tem[3]) != tem.length - 4) {
369                                 data.output.add_output(tem[0] + " : number of scores does not match");
370                                 data.courses.remove(tem[0]);
371                                 continue;
372                             }
373                         } catch (Exception ignored) {
374 
375                         }
376                     }
377                 }if((tem[1].equals("必修")||tem[1].equals("選修"))&&tem[2].equals("考試")){
378                     if(tem.length-3==2) {
379                         float tem_weight = Float.parseFloat(tem[3]) + Float.parseFloat(tem[4]);
380                         if (Math.abs(tem_weight - 1) > 0.0001) {
381                             data.output.add_output(tem[0] + " : weight value error");
382                             data.courses.remove(tem[0]);
383                         }
384                     }
385                 }
386             }else if(i.matches(regex_CS)||i.matches(regex_lab)) {
387                 if(!data.courses.containsKey(tem[2])){//不存在
388                     data.output.add_output(tem[2]+" does not exist");
389                     data.stu__st_cour.get(tem[0]).gradeMap.remove(tem[2]);
390                 }else{
391                     if(data.courses.get(tem[2]).type.equals("必修") && tem.length!=5) {//必修 但是只有期末成績
392                         data.output.add_output(tem[0]+" "+tem[1]+" : access mode mismatch");
393                     }else if(data.courses.get(tem[2]).type.equals("選修")) {
394                         if ((data.courses.get(tem[2]).test_way.equals("考試") && tem.length != 5) ||
395                                 (data.courses.get(tem[2]).test_way.equals("考察") && tem.length != 4))
396                             data.output.add_output(tem[0] + " " + tem[1] + " : access mode mismatch");
397                     }else if(data.courses.get(tem[2]).type.equals("實驗")){
398                         if(data.courses.get(tem[2]).test_way.equals("實驗")&&(tem.length-3<4||tem.length-3>9||tem.length-3!=((Lab_Course) data.courses.get(tem[2])).sub_scores_num))
399                             data.output.add_output(tem[0] + " " + tem[1] + " : access mode mismatch");
400                     }
401                 }
402             }else if(!i.equals("end")){
403                 data.output.add_output("wrong format");
404             }
405         }
406         data.classes.forEach((cla_num,Class1)->{//遍歷所有班級
407             Class1.students.forEach((stu_num,student)->{
408                 int tem=calculate.stu_all_grades(data,stu_num);
409                 if(tem>=0)
410                     data.output.add_output(stu_num+" "+Class1.students.get(stu_num).name+" "+tem);
411                 else
412                     data.output.add_output(stu_num+" "+Class1.students.get(stu_num).name+" "+"did not take any exams");
413             });
414         });
415         data.courses.forEach((key,value)-> {
416             int[] tem = calculate.single_course_grades(data, key);
417             if (tem[0] < 0 && tem[1] < 0 && tem[2] < 0) {//三個為- 則沒成績
418                 data.output.add_output(key + " has no grades yet");
419             }else {
420                 if (value.type.equals("選修") || value.type.equals("必修") || value.type.equals("實驗")) {
421                     data.output.add_output(key + " " + tem[2]);
422                 }
423             }
424         });
425         data.classes.forEach((num,Class)->{
426             int tem = calculate.Class_grades(data,num);
427             if(tem>=0) {
428                 data.output.add_output(num + " " + tem);
429             }else
430                 data.output.add_output(num+" has no grades yet");
431         });
432     }
433     void output_all(Data_storage data){
434         data.output.output.forEach(System.out::println);
435     }
436 }
437 abstract class Score {
438     String total_scores = "-100";
439 }
440 class Student {
441     String name;
442     String num;
443     Student(String name, String num) {
444         this.name = name;
445         this.num = num;
446     }
447 }
448 class StudentsAll_mes {
449     String num;//學生
450     TreeMap<String,Score> gradeMap =new TreeMap<>();
451     StudentsAll_mes(String stu_name, String course, String normal_score,String test_score){
452         this.num = stu_name;
453         gradeMap.put(course,new Test_Score(normal_score,test_score));
454     }
455     StudentsAll_mes(String stu_name, String course, String test_score){
456         this.num = stu_name;
457         gradeMap.put(course,new Inspect_Score(test_score));
458     }
459 
460     public StudentsAll_mes() {
461 
462     }
463     void set_lab_stu_mes(String stu_num,String course,String lab_num,ArrayList<Integer> scores){
464         this.num = stu_num;
465         gradeMap.put(course,new Lab_Score(lab_num,scores));
466     }
467     void set_lab_gradeMap(String course,String lab_num,ArrayList<Integer> scores){
468         if(!gradeMap.containsKey(course))
469             gradeMap.put(course,new Lab_Score(lab_num,scores));
470     }
471     void setGradeMap(String course, String normal_score,String test_score){
472         if(!gradeMap.containsKey(course))
473             gradeMap.put(course, new Test_Score(normal_score,test_score));
474     }
475     void setGradeMap(String course,String test_score){
476         if(!gradeMap.containsKey(course))
477             gradeMap.put(course,new Inspect_Score(test_score));
478     }
479 }
480 class Test_Score extends Score{
481     String normal_score;
482     String end_score;
483     Test_Score(String normal_score,String end_score) {
484         this.normal_score = normal_score;
485         this.end_score = end_score;
486     }
487 }
488 class Lab_Score extends Score {
489     String lab_num;//試驗次數(shù)
490     ArrayList<Integer> scores;
491     Lab_Score(String lab_num,ArrayList<Integer> scores){
492         this.lab_num = lab_num;
493         this.scores = scores;
494     }
495 }
496 class InAndOut_put {
497     List<String> output = new ArrayList<>();
498     List<String> input = new ArrayList<>();
499     void add_output(String out){
500         output.add(out);
501     }
502     void add_input(String out){
503         input.add(out);
504     }
505 }
課程成績統(tǒng)計程序-3

  

我的代碼中的主要類和功能如下:

  • Main類:包含程序的入口方法main,用于接收用戶輸入、處理數(shù)據(jù)和輸出結(jié)果。
  • Data_storage類:用于存儲數(shù)據(jù),包括課程、班級和學生的信息,以及學生的成績。
  • Input_Format類:用于處理用戶輸入的數(shù)據(jù),并根據(jù)輸入的格式解析和存儲相關(guān)信息。
  • Output_Format類:用于對數(shù)據(jù)進行計算和格式化輸出,包括計算學生平均成績、課程平均成績和班級平均成績等。
  • Calculate_grades類:用于計算學生、課程和班級的平均成績。
  • Class類:表示一個班級,包含班級號和學生信息。
  • Course類及其子類:表示一個課程,包含課程名稱、類型和考試方式等信息。
  • Score類及其子類:表示學生的成績,包括平時成績、期末考試成績和總分成績等。
代碼通過讀取用戶輸入的數(shù)據(jù),解析并存儲到相應(yīng)的數(shù)據(jù)結(jié)構(gòu)中。然后根據(jù)存儲的數(shù)據(jù)進行成績計算和格式化輸出。其中,成績計算部分涉及單個學生總課程平均分計算、單門課程成績計算和班級平均成績計算。
主要類圖如下:

  從類圖可以看出本次代碼非常復(fù)雜,我徹底改變了課程程序統(tǒng)計程序-2的邏輯結(jié)構(gòu),改變了原來的輸入輸出讀取方式以及字符匹配模式。

本次代碼的圈復(fù)雜度如下:

   從這個圖可以看出,本次代碼雖然類很多,但是結(jié)構(gòu)比第二次作業(yè)要清晰,代碼深度較高,平均的復(fù)雜度以及選擇分支減少,減少了內(nèi)存開銷。

期末考試

7-1 立體圖形問題
分數(shù) 10
作者 段喜龍
單位 南昌航空大學

編程求得正方體和正三棱錐的表面積和體積,要求必須體現(xiàn)擴展性(繼承)和多態(tài)性。

類結(jié)構(gòu)如下圖所示(參考):

image.png
試編程完成如上類設(shè)計,主方法源碼如下(可直接拷貝使用):

 
public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner input = new Scanner(System.in);
    double side = input.nextDouble();
        
    display(new Cube(side));
    display(new RegularPyramid(side));
}

其中,display(Solid solid)方法為定義在Main類中的靜態(tài)方法,作用為體現(xiàn)程序的多態(tài)性。

注:正三棱錐的體積計算公式為底面積*高/3。

輸入格式:

輸入一個實型數(shù),分別作為正方體的邊長和正三棱錐的邊長。

輸出格式:

分別輸出正方體的表面積、體積以及正棱錐的表面積和體積。保留兩位小數(shù),建議使用String.format(“%.2f”,value)

進行小數(shù)位數(shù)控制。


輸入樣例:

在這里給出一組輸入。例如:

2.5

輸出樣例:

在這里給出相應(yīng)的輸出。例如:

37.50
15.63
10.83
1.84
這個題目難度不大,主要在于三棱錐的體積與表面積的計算方法以及截斷整數(shù)那里讓我修改了一次。
我的代碼如下:
import java.util.Scanner;

abstract class Solid {
    protected double side;

    public Solid(double side) {
        this.side = side;
    }

    public abstract double getSurfaceArea();

    public abstract double getVolume();
}

class Cube extends Solid {
    public Cube(double side) {
        super(side);
    }

    public double getSurfaceArea() {
        return 6 * Math.pow(side, 2);
    }

    public double getVolume() {
        return Math.pow(side, 3);
    }
}

class RegularPyramid extends Solid {
    public RegularPyramid(double side) {
        super(side);
    }

    public double getSurfaceArea() {
        return Math.pow(side, 2) *Math.sqrt(3);
    }

    public double getVolume() {
        return Math.pow(side, 3) / (6 * Math.sqrt(2));
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double side = input.nextDouble();

        display(new Cube(side));
        display(new RegularPyramid(side));
    }

    public static void display(Solid solid) {
        System.out.println(String.format("%.2f", solid.getSurfaceArea()));
        System.out.println(String.format("%.2f", solid.getVolume()));
    }
}

  

  • Solid是一個抽象類,表示幾何體,包含一個受保護的成員變量side表示邊長,以及兩個抽象方法getSurfaceArea()getVolume()用于計算幾何體的表面積和體積。
  • CubeSolid的子類,表示立方體,通過繼承Solid類并實現(xiàn)抽象方法來計算立方體的表面積和體積。
  • RegularPyramid也是Solid的子類,表示正四面體,同樣通過繼承Solid類并實現(xiàn)抽象方法來計算正四面體的表面積和體積。
  • Main類包含了程序的入口方法main,在該方法中使用Scanner類獲取用戶輸入的邊長,然后創(chuàng)建一個立方體和一個正四面體對象,并調(diào)用display方法顯示它們的表面積和體積。
  • display方法接受一個Solid類型的參數(shù),根據(jù)傳入的具體幾何體對象調(diào)用相應(yīng)的方法來顯示它們的表面積和體積。
本次代碼的行數(shù)以及結(jié)構(gòu)很清晰明了,在此不貼出其類圖及復(fù)雜度分析。

問題描述:本問題中的魔方有兩種,一種是正方體魔方,一種是正三棱錐魔方,其中,正方體或正三棱錐魔方是由單元正方體或正三棱錐組成,單元正方體或正三棱錐的個數(shù)由階數(shù)(即層數(shù))決定,即魔方邊長=階數(shù)*單元邊長。魔方如下圖所示:


image.png

 

利用“立體圖形”問題源碼,實現(xiàn)如下功能:


魔方有三個屬性:顏色,階數(shù),類型(正方體魔方、正三棱錐魔方),程序要求輸出魔方的顏色、表面積和體積。參考設(shè)計類圖如下所示:


image.png


主方法部分可參考如下源碼(可拷貝直接使用):



 

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        String color = input.next();
        int layer = input.nextInt();
        double side = input.nextDouble();        
        
        RubikCube cube1 = new SquareCube(color, layer,new Cube(side)); 
                
        color = input.next();
        layer = input.nextInt();
        side = input.nextDouble();
        
        RubikCube cube2 = new RegularPyramidCube(color, layer,new RegularPyramid(side));
        display(cube1);
        display(cube2);
    }
}

其中,display(RubikCube cube)方法為Main類中定義的靜態(tài)方法,用戶輸出魔方的信息,用于體現(xiàn)多態(tài)性。


輸入格式:


第一部分:正方體魔方顏色、階數(shù)、單元正方體邊長,以空格或回車分隔;


第二部分:正三棱錐魔方顏色、階數(shù)、單元正三棱錐邊長,以空格或回車分隔。


輸出格式:


正方體魔方顏色


正方體魔方表面積


正方體魔方體積


正三棱錐魔方顏色


正三棱錐魔方表面積
正三棱錐魔方體積


注:小數(shù)點保留兩位


輸入樣例:


在這里給出一組輸入。例如:


red 3 4.5
black 4 2.1

輸出樣例:


在這里給出相應(yīng)的輸出。例如:


red
1093.50
2460.38
black
122.21
69.85
這道題目只需要在第一道的基礎(chǔ)上略微修改計算方式以及添加抽象魔方類即可解決。
代碼如下:
import java.util.Scanner;

abstract class Solid {
    protected double side;

    public Solid(double side) {
        this.side = side;
    }

    public abstract double getSurfaceArea();

    public abstract double getVolume();
}

class Cube extends Solid {
    public Cube(double side) {
        super(side);
    }

    public double getSurfaceArea() {
        return 6 * Math.pow(side, 2);
    }

    public double getVolume() {
        return Math.pow(side, 3);
    }
}

class RegularPyramid extends Solid {
    public RegularPyramid(double side) {
        super(side);
    }

    public double getSurfaceArea() {
        return Math.pow(side, 2) *Math.sqrt(3);
    }

    public double getVolume() {
        return Math.pow(side, 3) / (6 * Math.sqrt(2));
    }
}

abstract class RubikCube {
    protected String color;
    protected int layer;
    protected Solid solid;

    public RubikCube(String color, int layer, Solid solid) {
        this.color = color;
        this.layer = layer;
        this.solid = solid;
    }

    public String getColor() {
        return color;
    }

    public abstract double getSurfaceArea();

    public abstract double getVolume();
}

class SquareCube extends RubikCube {
    public SquareCube(String color, int layer, Solid solid) {
        super(color, layer, solid);
    }

    public double getSurfaceArea() {
        return 6 * Math.pow(layer * solid.side, 2);
    }

    public double getVolume() {
        return Math.pow(layer * solid.side, 3);
    }
}

class RegularPyramidCube extends RubikCube {
    public RegularPyramidCube(String color, int layer, Solid solid) {
        super(color, layer, solid);
    }

    public double getSurfaceArea() {
        return layer * layer * solid.getSurfaceArea();
    }

    public double getVolume() {
        return layer * layer * layer * solid.getVolume();
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        String color = input.next();
        int layer = input.nextInt();
        double side = input.nextDouble();

        RubikCube cube1 = new SquareCube(color, layer, new Cube(side));

        color = input.next();
        layer = input.nextInt();
        side = input.nextDouble();

        RubikCube cube2 = new RegularPyramidCube(color, layer, new RegularPyramid(side));
        display(cube1);
        display(cube2);
    }

    public static void display(RubikCube cube) {
        System.out.println(cube.getColor());
        System.out.println(String.format("%.2f", cube.getSurfaceArea()));
        System.out.println(String.format("%.2f", cube.getVolume()));
    }
}
View Code

  • RubikCube是一個抽象類,表示魔方,包含顏色、層數(shù)和幾何體對象的信息。它繼承自Solid類,并實現(xiàn)了抽象方法getSurfaceArea()getVolume()來計算魔方的表面積和體積。
  • SquareCubeRubikCube的子類,表示正方體魔方。通過繼承RubikCube類并實現(xiàn)抽象方法來計算正方體魔方的表面積和體積。
  • RegularPyramidCube也是RubikCube的子類,表示正四面體魔方。同樣通過繼承RubikCube類并實現(xiàn)抽象方法來計算正四面體魔方的表面積和體積。

Main類中,除了之前的功能外,添加了用戶輸入魔方的顏色、層數(shù)和邊長。根據(jù)用戶輸入創(chuàng)建一個正方體魔方對象和一個正四面體魔方對象,并調(diào)用display方法顯示它們的顏色、表面積和體積。

display方法接受一個RubikCube類型的參數(shù),根據(jù)傳入的魔方對象調(diào)用相應(yīng)的方法來顯示它們的顏色、表面積和體積。


7-3 魔方排序問題
分數(shù) 20

作者 段喜龍
單位 南昌航空大學

在魔方問題的基礎(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
這道題目是在魔方問題的基礎(chǔ)上,對用戶輸入的魔方數(shù)據(jù)的表面和體積進行排序。
我的代碼如下:
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Comparator;
abstract class Solid {
    protected double side;

    public Solid(double side) {
        this.side = side;
    }

    public abstract double getSurfaceArea();

    public abstract double getVolume();
}

class Cube extends Solid {
    public Cube(double side) {
        super(side);
    }

    public double getSurfaceArea() {
        return 6 * Math.pow(side, 2);
    }

    public double getVolume() {
        return Math.pow(side, 3);
    }
}

class RegularPyramid extends Solid {
    public RegularPyramid(double side) {
        super(side);
    }

    public double getSurfaceArea() {
        return Math.pow(side, 2) *Math.sqrt(3);
    }

    public double getVolume() {
        return Math.pow(side, 3) / (6 * Math.sqrt(2));
    }
}

abstract class RubikCube implements Comparable<RubikCube> {
    protected String color;
    protected int layer;
    protected Solid solid;

    public RubikCube(String color, int layer, Solid solid) {
        this.color = color;
        this.layer = layer;
        this.solid = solid;
    }

    public String getColor() {
        return color;
    }

    public abstract double getSurfaceArea();

    public abstract double getVolume();

    @Override
    public int compareTo(RubikCube other) {
        return Double.compare(this.getVolume(), other.getVolume());
    }
}
class SquareCube extends RubikCube {
    public SquareCube(String color, int layer, Solid solid) {
        super(color, layer, solid);
    }

    public double getSurfaceArea() {
        return 6 * Math.pow(layer * solid.side, 2);
    }

    public double getVolume() {
        return Math.pow(layer * solid.side, 3);
    }
}

class RegularPyramidCube extends RubikCube {
    public RegularPyramidCube(String color, int layer, Solid solid) {
        super(color, layer, solid);
    }

    public double getSurfaceArea() {
        return layer * layer * solid.getSurfaceArea();
    }

    public double getVolume() {
        return layer * layer * layer * solid.getVolume();
    }
}

public class Main {
    public static void main(String[] args) {
        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).getSurfaceArea()) + " " + 
        String.format("%.2f", list.get(i).getVolume()) );
            System.out.println("");
        }            
    }    
}
View Code

這段代碼中的類包括:

  • Solid:抽象基類,表示一個立體,包含邊長屬性和計算表面積和體積的抽象方法。
  • Cube:繼承自Solid,表示一個立方體,實現(xiàn)了計算表面積和體積的方法。
  • RegularPyramid:繼承自Solid,表示一個正四面體,實現(xiàn)了計算表面積和體積的方法。
  • RubikCube:抽象基類,表示一個魔方,包含顏色、層數(shù)和實際立體對象的屬性,以及計算表面積和體積的抽象方法和比較方法。
  • SquareCube:繼承自RubikCube,表示一個立方體魔方,實現(xiàn)了計算表面積和體積的方法。
  • RegularPyramidCube:繼承自RubikCube,表示一個金字塔魔方,實現(xiàn)了計算表面積和體積的方法。
  • Main:主類,包含main方法,用于接收用戶輸入、創(chuàng)建魔方對象、進行排序和打印結(jié)果。

用戶可以通過輸入數(shù)字選擇魔方類型(1表示立方體魔方,2表示金字塔魔方),然后依次輸入顏色、層數(shù)和邊長。輸入0表示結(jié)束輸入。

最后,程序?qū)⒏鶕?jù)魔方的體積對魔方列表進行排序,并打印每個魔方的顏色、表面積和體積。

我的代碼的類圖如下:

 

在原來的魔方問題代碼上,我添加了用戶選擇立體類型以及排序輸出部分。

7-4 銷售步槍問題(附加題)
分數(shù) 10

作者 段喜龍
單位 南昌航空大學

前亞利桑那州境內(nèi)的一位步槍銷售商銷售密蘇里州制造的步槍機(lock)、槍托(stock)和槍管(barrel)。槍機賣45美元,槍托賣30美元,槍管賣25美元。銷售商每月至少要售出一支完整的步槍,且生產(chǎn)限額是銷售商在一個月內(nèi)可銷售70個槍機、80個槍托和90個槍管。

根據(jù)每個月的銷售情況,計算銷售商的傭金(提成)算法如下:

  • 不到(含)1000美元的部分為10%;

  • 1000(含)~1800美元的部分為15%;

  • 超過1800美元的部分為20%。

傭金程序生成月份銷售報告,匯總銷售商的銷售總額和傭金。

編程要求:必須符合面向?qū)ο缶幊蹋冶WC類設(shè)計的單一職責模式,使用面向過程編程判定0分。

提示:可以設(shè)置一個銷售訂單類。參考類圖如下:

image.png

輸入格式:

輸入銷售商每個月售出槍機、槍托、槍管的數(shù)量,可以用空格或者回車分隔。

輸出格式:

分別輸出銷售商在該月的銷售額和傭金,中間用空格分開。

輸入樣例1:

在這里給出一組輸入。例如:

30 40 50

輸出樣例1:

在這里給出相應(yīng)的輸出。例如:

3800.00 620.00

輸入樣例2:
在這里給出一組輸入。例如:

88 56 98

輸出樣例2:
在這里給出相應(yīng)的輸出。例如:

Wrong Format

這是一道簡單的題目,我的代碼如下:

import java.util.Scanner;

class SalesOrder {
    private int lockCount;
    private int stockCount;
    private int barrelCount;

    private static final int LOCK_PRICE = 45;
    private static final int STOCK_PRICE = 30;
    private static final int BARREL_PRICE = 25;

    public SalesOrder(int lockCount, int stockCount, int barrelCount) {
        if ((lockCount > 70 || stockCount > 80 || barrelCount > 90)||(lockCount<1||stockCount<1||barrelCount<1)) {
            throw new IllegalArgumentException("Wrong Format");
        }
        this.lockCount = lockCount;
        this.stockCount = stockCount;
        this.barrelCount = barrelCount;
    }

    public double calculateTotalSales() {
        return lockCount * LOCK_PRICE + stockCount * STOCK_PRICE + barrelCount * BARREL_PRICE;
    }

    public double calculateCommission() {
        double totalSales = calculateTotalSales();
        if (totalSales <= 1000) {
            return totalSales * 0.10;
        } else if (totalSales <= 1800) {
            return 1000 * 0.10 + (totalSales - 1000) * 0.15;
        } else {
            return 1000 * 0.10 + 800 * 0.15 + (totalSales - 1800) * 0.20;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        int lockCount = input.nextInt();
        int stockCount = input.nextInt();
        int barrelCount = input.nextInt();

        try {
            SalesOrder order = new SalesOrder(lockCount, stockCount, barrelCount);
            System.out.printf("%.2f %.2f\n", order.calculateTotalSales(), order.calculateCommission());
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
    }
}

這是期末考試的附加題,難度不大,只要注意題目的條件控制好輸入輸出,基本不會出錯。

總結(jié):

  這階段的題目是PTA的最后一部分題目,題目難度相較于第二次也變小了,最后一階段的題目加入了很多面向?qū)ο骿ava的特點題目,加入了接口,繼承多態(tài)部分題目,這些題目讓我對面向?qū)ο骿ava這門語言更加熟悉和了解,PTA的題目讓我記憶猶新,我曾因為兩道題做出來而竊竊自喜,也曾因為菜單計價系列題目而痛不欲生,這些都使我受益良多,最后一階段的題目算是對java的學習到了一個新階段,我開始有意識地理清代碼結(jié)構(gòu)以及想辦法降低代碼復(fù)雜度,而不是像以前一樣只求做出來,我開始思考題目的需求和哪些方法匹配,字符匹配是否需要用到正則表達式,類的設(shè)計是應(yīng)該繼承還是組合,應(yīng)該用哪種方式來儲存數(shù)據(jù)(鏈表還是數(shù)組)……,這些思考使我的代碼能力和設(shè)計思維進一步提高,為我以后的工作和學習打下了良好的基礎(chǔ)。