主頁 > 後端開發 > PTA作業6-8電信系列總結

PTA作業6-8電信系列總結

2022-12-11 07:05:26 後端開發

一、6-8作業總結

(1)第六次作業:第一次作業分了兩個題,一個電信1題目非常長,給出了類圖,類很多作業量很大,還一個題以容器類為例展現了介面,多型的用處和效果,題目給出的提示非常多,按照題目來,再加上一些測驗代碼,可以運用equals類實作,

(2)第七次作業:第二次作業分了三個小題,第一個還是電信系列,在第六次作業的電信1基礎上加了手機計費,代碼將會更復雜,第二、三題比較簡單,題目都給出了大部分代碼,只需要修改,看仔細點就行,主要用到了Collection ,ArrayList,hash這些常用類,使用sort方法實作排序,其實電信系列也用到了這些類,

(3)第八次作業:也是分為三個小題,還是電信系列,不過這次是手機接收短信計費,比較簡單,在之前的代碼上加上短信計費的具體計費方式就行,第二小題主要考察內部類,第三個小題題目就叫動物聲音模擬器,和第六次作業中的容器類類似,考察多型,沒有什么復雜的演算法,掌握了多型的思想就會比較簡單,

二、設計與分析

1.第6次作業:7-1 電信計費系列1-座機計費

作者 蔡軻 單位 南昌航空大學

實作一個簡單的電信計費程式:
假設南昌市電信分公司針對市內座機用戶采用的計費方式:
月租20元,接電話免費,市內撥打電話0.1元/分鐘,省內長途0.3元/分鐘,國內長途撥打0.6元/分鐘,不足一分鐘按一分鐘計,
南昌市的區號:0791,江西省內各地市區號包括:0790~0799以及0701,

輸入格式:

輸入資訊包括兩種型別
1、逐行輸入南昌市用戶開戶的資訊,每行一個用戶,
格式:u-號碼 計費型別 (計費型別包括:0-座機 1-手機實時計費 2-手機A套餐)
例如:u-079186300001 0
座機號碼除區號外由是7-8位數字組成,
本題只考慮計費型別0-座機計費,電信系列2、3題會逐步增加計費型別,
2、逐行輸入本月某些用戶的通訊資訊,通訊資訊格式:
座機呼叫座機:t-主叫號碼 接聽號碼 起始時間 結束時間
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四項內容之間以一個英文空格分隔,
時間必須符合"yyyy.MM.dd HH:mm:ss"格式,提示:使用SimpleDateFormat類,
以上兩類資訊,先輸入所有開戶資訊,再輸入所有通訊資訊,最后一行以“end”結束,
注意:
本題非法輸入只做格式非法的判斷,不做內容是否合理的判斷(時間除外,否則無法計算),比如:
1、輸入的所有通訊資訊均認為是同一個月的通訊資訊,不做日期是否在同一個月還是多個月的判定,直接將通訊費用累加,因此月租只計算一次,
2、記錄中如果同一電話號碼的多條通話記錄時間出現重合,這種情況也不做判斷,直接 計算每條記錄的費用并累加,
3、用戶區號不為南昌市的區號也作為正常用戶處理,

輸出格式:

根據輸入的詳細通訊資訊,計算所有已開戶的用戶的當月費用(精確到小數點后2位,
單位元),假設每個用戶初始余額是100元,
每條通訊資訊單獨計費后累加,不是將所有時間累計后統一計費,
格式:號碼+英文空格符+總的話費+英文空格符+余額
每個用戶一行,用戶之間按號碼字符從小到大排序,

錯誤處理:
輸入資料中出現的不符合格式要求的行一律忽略,

建議類圖:
參見圖1、2、3,可根據理解自行調整:

image.png

                                    圖1
圖1中User是用戶類,包括屬性:
userRecords (用戶記錄)、balance(余額)、chargeMode(計費方式)、number(號碼),

ChargeMode是計費方式的抽象類:
chargeRules是計費方式所包含的各種計費規則的集合,ChargeRule類的定義見圖3,
getMonthlyRent()方法用于回傳月租(monthlyRent),

UserRecords是用戶記錄類,保存用戶各種通話、短信的記錄,    
各種計費規則將使用其中的部分或者全部記錄,
其屬性從上到下依次是:
市內撥打電話、省內(不含市內)撥打電話、省外撥打電話、
市內接聽電話、省內(不含市內)接聽電話、省外接聽電話的記錄
以及發送短信、接收短信的記錄,
 

image.png

                                     圖2
圖2中CommunicationRecord是抽象的通訊記錄類:
包含callingNumber撥打號碼、answerNumber接聽號碼兩個屬性,
CallRecord(通話記錄)、MessageRecord(短信記錄)是它的子類,

CallRecord(通話記錄類)包含屬性:
通話的起始、結束時間以及
撥號地點的區號(callingAddressAreaCode)、接聽地點的區號(answerAddressAreaCode),
區號用于記錄在哪個地點撥打和接聽的電話,座機無法移動,就是本機區號,如果是手機號,則會有差異,

image.png

                                        圖3
圖3是計費規則的相關類,這些類的核心方法是:
calCost(ArrayList<CallRecord> callRecords),
該方法針根據輸入引數callRecords中的所有記錄計算某用戶的某一項費用;如市話費,
輸入引數callRecords的約束條件:必須是某一個用戶的符合計費規則要求的所有記錄,

LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三個類分別是
座機撥打市內、省內、省外電話的計費規則類,用于實作這三種情況的費用計算,    
(提示:可以從UserRecords類中獲取各種型別的callRecords),

后續擴展說明:
后續題目集將增加手機用戶,手機用戶的計費方式中除了與座機計費類似的主叫通話費之外,還包含市外接聽電話的漫游費以及發短信的費用,在本題的設計時可統一考慮,
通話記錄中,手機需要額外記錄撥打/接聽的地點的區號,比如:
座機打手機:t-主叫號碼 接聽號碼 接聽地點區號 起始時間 結束時間
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手機互打:t-主叫號碼 撥號地點 接聽號碼 接聽地點區號 起始時間 結束時間
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
短信的格式:m-主叫號碼,接收號碼,短信內容
m-18907910010 13305862264 welcome to jiangxi
m-13305862264 18907910010 thank you

 

分析:本題要求比較多,但給出了類圖,需要先根據類圖建立好這些類,在考慮如何實作,最后測驗,根據結果作出適當調整,不過需要注意,最后輸出的通信記錄需要按電話這串字符從小到大排序的,還要寫一個類用來判斷格式,需要判斷閏年,

代碼如下:(代碼很長已全部折疊)

  1 import java.math.RoundingMode;
  2 import java.util.*;
  3 import java.text.SimpleDateFormat;
  4 import java.text.ParseException;
  5 import java.math.BigDecimal;
  6 
  7 public class Main {
  8 
  9     public static void main(String[] args) {
 10 
 11         InputDeal inputdeal = new InputDeal();
 12 
 13         ArrayList<User> users = new ArrayList<>();
 14 
 15         Scanner in = new Scanner(System.in);
 16 
 17         String input = in.nextLine();
 18         //格式正確,格式錯誤不管  0791,江西省內各地市區號包括:0790~0799以及0701
 19         // t-079186300001 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:25
 20         while (!input.equals("end")) {
 21             if (1 == inputdeal.check(input)) {
 22                 writeUser(users, input);
 23             } else if (2 == inputdeal.check(input)) {
 24                 writeRecord(users, input);
 25             }
 26             input = in.nextLine();
 27         }
 28         users.sort(new Comparator<User>() {
 29             @Override
 30             public int compare(User u1, User u2) {
 31                 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
 32                     return 1;
 33                 } else {
 34                     return -1;
 35                 }
 36             }
 37         });
 38         for (User u : users) {
 39             System.out.print(u.getNumber() + " ");
 40 
 41             double tip = u.calCost();
 42             output(u.calCost());
 43             System.out.print(" ");
 44             //System.out.printf("%.2f ",tip);
 45             double bal = u.calBalance();
 46             output(u.calBalance());
 47 
 48         }
 49 
 50     }
 51     public static void output(double out) {
 52 
 53         BigDecimal numb = new BigDecimal(out);
 54         out = numb.setScale(2, RoundingMode.HALF_UP).doubleValue();
 55         System.out.print(out);
 56     }
 57     public static void writeUser(ArrayList<User> users, String input) {
 58         User user1 = new User();
 59         String[] inputs = input.split(" ");
 60         String num = inputs[0].substring(2);
 61         for (User i : users) {
 62             if (i.getNumber().equals(num)) {
 63                 return;
 64             }
 65         }
 66         user1.setNumber(num);
 67         int mode = Integer.parseInt(inputs[1]);
 68         if (mode == 0) {
 69             user1.setChargeMode(new LandlinePhoneCharging());
 70         }
 71         users.add(user1);
 72     }
 73 
 74     public static void writeRecord(ArrayList<User> users, String input) {
 75         String[] inputs = input.split(" ");
 76         inputs[0] = inputs[0].replace("t-", "");
 77 
 78         User callu = null, answeru = null;
 79         CallRecord callrecord = new CallRecord(inputs);
 80 
 81         for (User i : users) {
 82             if (i.getNumber().equals(inputs[0])) {
 83                 callu = i;
 84             }
 85             if (i.getNumber().equals(inputs[1])) {
 86                 answeru = i;
 87             }
 88             if (callu != null && answeru != null) {
 89                 break;
 90             }
 91         }
 92 
 93         if (callu != null) {
 94             if (callrecord.getCallType() == 1) {
 95                 callu.getUserRecords().addCallingInCityRecords(callrecord);
 96             } else if (callrecord.getCallType() == 2) {
 97                 callu.getUserRecords().addCallingInProvinceRecords(callrecord);
 98             } else {
 99                 callu.getUserRecords().addCallingInLandRecords(callrecord);
100             }
101         }
102 
103         if (answeru != null) {
104             if (callrecord.getCallType() == 1) {
105                 answeru.getUserRecords().addAnswerInCityRecords(callrecord);
106             } else if (callrecord.getCallType() == 2) {
107 
108                 answeru.getUserRecords().addAnswerInProvinceRecords(callrecord);
109             } else {
110                 answeru.getUserRecords().addAnswerInLandRecords(callrecord);
111             }
112         }
113 
114     }
115 }
116 
117 abstract class ChargeMode {
118     protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
119 
120     public abstract double calCost(UserRecords userRecords);
121 
122     public abstract double getMonthlyRent();
123 
124     public ArrayList<ChargeRule> getChargeRules() {
125         return chargeRules;
126     }
127 
128     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
129         this.chargeRules = chargeRules;
130     }
131 }
132 /*
133  *    類:用戶通訊所有資訊記錄
134  * 屬性:市內撥打電話、省內(不含市內)撥打電話、省外撥打電話、
135  * 市內接聽電話、省內(不含市內)接聽電話、省外接聽電話的記錄
136  * 以及發送短信、接收短信的記錄
137  * 功能:按地址分別記錄通話資訊
138  *  */
139 class UserRecords {
140 
141     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
142     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
143     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
144     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
145     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
146     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
147     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
148     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
149 
150     public void addCallingInCityRecords(CallRecord callRecord) {
151         callingInCityRecords.add(callRecord);
152     }
153 
154     public void addCallingInProvinceRecords(CallRecord callRecord) {
155         callingInProvinceRecords.add(callRecord);
156     }
157 
158     public void addCallingInLandRecords(CallRecord callRecord) {
159         callingInLandRecords.add(callRecord);
160     }
161 
162     public void addAnswerInCityRecords(CallRecord callRecord) {
163         answerInCityRecords.add(callRecord);
164     }
165 
166     public void addAnswerInProvinceRecords(CallRecord callRecord) {
167         answerInProvinceRecords.add(callRecord);
168     }
169 
170     public void addAnswerInLandRecords(CallRecord callRecord) {
171         answerInLandRecords.add(callRecord);
172     }
173 
174     public void addSendMessageRecords(MessageRecord callRecord) {
175         sendMessageRecords.add(callRecord);
176     }
177 
178     public void addReceiveMessageRecords(MessageRecord callRecord) {
179         receiveMessageRecords.add(callRecord);
180     }
181 
182     public ArrayList<CallRecord> getCallingInCityRecords() {
183         return callingInCityRecords;
184     }
185 
186     public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
187         this.callingInCityRecords = callingInCityRecords;
188     }
189 
190     public ArrayList<CallRecord> getCallingInProvinceRecords() {
191         return callingInProvinceRecords;
192     }
193 
194     public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
195         this.callingInProvinceRecords = callingInProvinceRecords;
196     }
197 
198     public ArrayList<CallRecord> getCallingInLandRecords() {
199         return callingInLandRecords;
200     }
201 
202     public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
203         this.callingInLandRecords = callingInLandRecords;
204     }
205 
206     public ArrayList<CallRecord> getAnswerInCityRecords() {
207         return answerInCityRecords;
208     }
209 
210     public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
211         this.answerInCityRecords = answerInCityRecords;
212     }
213 
214     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
215         return answerInProvinceRecords;
216     }
217 
218     public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
219         this.answerInProvinceRecords = answerInProvinceRecords;
220     }
221 
222     public ArrayList<CallRecord> getAnswerInLandRecords() {
223         return answerInLandRecords;
224     }
225 
226     public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
227         this.answerInLandRecords = answerInLandRecords;
228     }
229 
230     public ArrayList<MessageRecord> getSendMessageRecords() {
231         return sendMessageRecords;
232     }
233 
234     public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
235         this.sendMessageRecords = sendMessageRecords;
236     }
237 
238     public ArrayList<MessageRecord> getReceiveMessageRecords() {
239         return receiveMessageRecords;
240     }
241 
242     public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
243         this.receiveMessageRecords = receiveMessageRecords;
244     }
245 
246 }
247 /*
248  *  座機計費方式
249  *
250  * */
251 class LandlinePhoneCharging extends ChargeMode {
252 
253     final double monthlyRent = 20;
254 
255     public LandlinePhoneCharging() {
256         super();
257         chargeRules.add(new LandPhoneInCityRule());
258         chargeRules.add(new LandPhoneInProvinceRule());
259         chargeRules.add(new LandPhoneInlandRule());
260     }
261 
262     @Override
263     public double calCost(UserRecords userRecords) {
264         double sumCost = 0;
265         for (ChargeRule rule : chargeRules) {
266             sumCost += rule.calCost(userRecords);
267         }
268         return sumCost;
269     }
270 
271     @Override
272     public double getMonthlyRent() {
273         return monthlyRent;
274     }
275 
276 }
277 /*   類:輸入格式判斷InputDeal
278  * 功能:判斷輸入格式是否正確,時間是否合理
279  *
280  * */
281 class InputDeal {
282 
283     public int check(String input) {
284         String[] inputs = input.split(" ");
285         if (inputs.length == 2) {
286             if (inputs[0].matches("^u-\\d{11,13}$")) {
287                 if (Integer.parseInt(inputs[1]) >= 0 && Integer.parseInt(inputs[1]) <= 2) {
288                     return 1;
289                 }
290             }
291         } else if (inputs.length == 6) {
292             if (check1(inputs[2]) && check1(inputs[4]))
293                 if (check2(inputs[3]) && check2(inputs[5]))
294                     if (inputs[0].matches("[t]-0791\\d{7,8}") && inputs[1].matches(".\\d{9,11}"))
295                         return 2;
296 
297         }
298         return 0;
299     }
300 
301     private boolean check2(String string) {
302         return string.matches("^([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5]\\d)$");
303     }
304 
305     public static boolean check1(String dateString) {
306         // 使用正則運算式 測驗 字符 符合 dddd.dd.dd 的格式(d表示數字)
307         if (!dateString.matches("\\d{4}+.\\d{1,2}+.\\d{1,2}+")) {
308             return false;
309         }
310         // 得到年月日
311         String[] array = dateString.split("\\.");
312         int year = Integer.parseInt(array[0]);
313         int month = Integer.parseInt(array[1]);
314         int day = Integer.parseInt(array[2]);
315 
316         if (month < 1 || month > 12) {
317             return false;
318         }
319         int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
320         if (isLeapYear(year)) {
321             monthLengths[2] = 29;
322         } else {
323             monthLengths[2] = 28;
324         }
325         int monthLength = monthLengths[month];
326         return day >= 1 && day <= monthLength;
327     }
328 
329     /** 是否是閏年 */
330     private static boolean isLeapYear(int year) {
331         return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
332     }
333 
334 }
335 /*
336  *    抽象類:通訊記錄
337  * 屬性:callingNumber撥打號碼、answerNumber接聽號碼
338  *
339  *  */
340 abstract class CommunicationRecord {
341     protected String callingNumber;
342     protected String answerNumber;
343 
344     public String getCallingNumber() {
345         return callingNumber;
346     }
347 
348     public void setCallingNumber(String callingNumber) {
349         this.callingNumber = callingNumber;
350     }
351 
352     public String getAnswerNumber() {
353         return answerNumber;
354     }
355 
356     public void setAnswerNumber(String answerNumber) {
357         this.answerNumber = answerNumber;
358     }
359 
360 }
361 
362 abstract class ChargeRule {
363 
364     abstract public double calCost(UserRecords userRecords);
365 
366 }
367 /*
368  *    類:通話記錄
369  * 屬性:通話起始、結束時間;撥號人地址,接聽人地址
370  * 功能:記錄打電話雙方的地址和通話時間
371  *
372  */
373 class CallRecord extends CommunicationRecord {
374     private Date startTime;
375     private Date endTime;
376     private String callingAddressAreaCode;
377     private String answerAddressAreaCode;
378     //
379     public double getCallTime(){
380         return endTime.getTime() - startTime.getTime();
381     }
382     public int getCallType() {
383         if (callingAddressAreaCode.equals(answerAddressAreaCode)) {
384             return 1;
385         }
386         if (callingAddressAreaCode.matches("^079\\d$") || callingAddressAreaCode.equals("0701")) {
387             if (answerAddressAreaCode.matches("^079\\d$") || answerAddressAreaCode.equals("0701")) {
388                 return 2;
389             }
390         }
391         return 3;
392     }
393 
394     public CallRecord(String[] in) {
395         super();
396         if (in[0].length() == 10) {
397             callingAddressAreaCode = in[0].substring(0, 3);
398         } else {
399             callingAddressAreaCode = in[0].substring(0, 4);
400         }
401         if (in[1].length() == 10) {
402             answerAddressAreaCode = in[1].substring(0, 3);
403         } else {
404             answerAddressAreaCode = in[1].substring(0, 4);
405         }
406         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
407         try {
408             startTime = simpleDateFormat.parse(in[2] + " " + in[3]);
409             endTime = simpleDateFormat.parse(in[4] + " " + in[5]);
410         } catch (ParseException e) {
411             throw new RuntimeException(e);
412         }
413 
414     }
415 
416     public Date getStartTime() {
417         return startTime;
418     }
419 
420     public void setStartTime(Date startTime) {
421         this.startTime = startTime;
422     }
423 
424     public Date getEndTime() {
425         return endTime;
426     }
427 
428     public void setEndTime(Date endTime) {
429         this.endTime = endTime;
430     }
431 
432     public String getCallingAddressAreaCode() {
433         return callingAddressAreaCode;
434     }
435 
436     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
437         this.callingAddressAreaCode = callingAddressAreaCode;
438     }
439 
440     public String getAnswerAddressAreaCode() {
441         return answerAddressAreaCode;
442     }
443 
444     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
445         this.answerAddressAreaCode = answerAddressAreaCode;
446     }
447 }
448 
449 abstract class CallChargeRule extends ChargeRule {}
450 
451 /*
452  * 市內
453  * */
454 class LandPhoneInCityRule extends CallChargeRule {
455 
456     @Override
457     public double calCost(UserRecords userRecords) {
458         double sumCost = 0;
459         for (CallRecord call : userRecords.getCallingInCityRecords()) {
460             long distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
461             if (distanceS < 0) {
462                 continue;
463             }
464             long distanceM = (int) distanceS / 60;
465             if (distanceS % 60 != 0) {
466                 distanceM += 1;
467             }
468             sumCost += distanceM * 0.1;
469         }
470         return sumCost;
471     }
472 
473 }
474 /*
475  * 國內
476  * */
477 class LandPhoneInlandRule extends CallChargeRule {
478 
479     @Override
480     public double calCost(UserRecords userRecords) {
481         double sumCost = 0;
482         for (CallRecord call : userRecords.getCallingInLandRecords()) {
483             long distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
484             if (distanceS < 0) {
485                 continue;
486             }
487             long distanceM = (int) distanceS / 60;
488             if (distanceS % 60 != 0) {
489                 distanceM += 1;
490             }
491             sumCost += distanceM * 0.6;
492         }
493         return sumCost;
494     }
495 
496 }
497 /*
498  * 省內
499  */
500 class LandPhoneInProvinceRule extends CallChargeRule {
501 
502     @Override
503     public double calCost(UserRecords userRecords) {
504         double sumCost = 0;
505         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
506             long distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
507             if (distanceS < 0) {
508                 continue;
509             }
510             long distanceM = (int) distanceS / 60;
511             if (distanceS % 60 != 0) {
512                 distanceM += 1;
513             }
514             sumCost += distanceM * 0.3;
515         }
516         return sumCost;
517     }
518 
519 }
520 /*
521  *    類:短信記錄
522  * 屬性:短信內容
523  *
524  * */
525 class MessageRecord extends CommunicationRecord {
526 
527     private String message;
528 
529     public String getMessage() {
530         return message;
531     }
532 
533     public void setMessage(String message) {
534         this.message = message;
535     }
536 }
537 /*
538  *    類:用戶
539  * 屬性:用戶通訊詳細資訊記錄userRecords,話費余額,電話付費方式,電話號碼
540  *
541  *  */
542 class User {
543     private UserRecords userRecords = new UserRecords();
544     double balance = 100;
545     private ChargeMode chargeMode;
546     private String number;
547 
548     public double calCost() {
549         return chargeMode.calCost(userRecords);
550     }
551 
552     public double calBalance() {
553         return balance - chargeMode.getMonthlyRent() - calCost();
554     }
555 
556     public UserRecords getUserRecords() {
557         return userRecords;
558     }
559 
560     public void setUserRecords(UserRecords userRecords) {
561         this.userRecords = userRecords;
562     }
563 
564     public ChargeMode getChargeMode() {
565         return chargeMode;
566     }
567 
568     public void setChargeMode(ChargeMode chargeMode) {
569         this.chargeMode = chargeMode;
570     }
571 
572     public String getNumber() {
573         return number;
574     }
575 
576     public void setNumber(String number) {
577         this.number = number;
578     }
579 
580 }
View Code

結果:

 

 

 分析:電信1的得分點最后還有一個沒有過,但測驗了很多輸入樣例都沒有測出來,由上圖可知,最后的代碼平均深度,平均復雜度和最大深度差不多,不是很高,最大復雜度比較高,資訊量實在是太多了,不過總體來說圈復雜度還是可以的,注釋我都做了類的注釋,但好像還是有點少了,

2.第7次作業:7-2 電信計費系列1-手機計費

實作南昌市電信分公司的計費程式,假設該公司針對手機和座機用戶分別采取了兩種計費方案,分別如下:
1、針對市內座機用戶采用的計費方式(與電信計費系列1內容相同):
月租20元,接電話免費,市內撥打電話0.1元/分鐘,省內長途0.3元/分鐘,國內長途撥打0.6元/分鐘,不足一分鐘按一分鐘計,
假設本市的區號:0791,江西省內各地市區號包括:0790~0799以及0701,
2、針對手機用戶采用實時計費方式:
月租15元,市內省內接電話均免費,市內撥打市內電話0.1元/分鐘,市內撥打省內電話0.2元/分鐘,市內撥打省外電話0.3元/分鐘,省內漫游打電話0.3元/分鐘,省外漫游接聽0.3元/分鐘,省外漫游撥打0.6元/分鐘;
注:被叫電話屬于市內、省內還是國內由被叫電話的接聽地點區號決定,比如以下案例中,南昌市手機用戶13307912264在區號為020的廣州接聽了電話,主叫號碼應被計算為撥打了一個省外長途,同時,手機用戶13307912264也要被計算省外接聽漫游費:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3 10:05:11

輸入:
輸入資訊包括兩種型別
1、逐行輸入南昌市用戶開戶的資訊,每行一個用戶,含手機和座機用戶
格式:u-號碼 計費型別 (計費型別包括:0-座機 1-手機實時計費 2-手機A套餐)
例如:u-079186300001 0
座機號碼由區號和電話號碼拼接而成,電話號碼包含7-8位數字,區號最高位是0,
手機號碼由11位數字構成,最高位是1,
本題在電信計費系列1基礎上增加型別1-手機實時計費,
手機設定0或者座機設定成1,此種錯誤可不做判斷,
2、逐行輸入本月某些用戶的通訊資訊,通訊資訊格式:
座機呼叫座機:t-主叫號碼 接聽號碼 起始時間 結束時間
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四項內容之間以一個英文空格分隔,
時間必須符合"yyyy.MM.dd HH:mm:ss"格式,提示:使用SimpleDateFormat類,
輸入格式增加手機接打電話以及收發短信的格式,手機接打電話的資訊除了號碼之外需要額外記錄撥打/接聽的地點的區號,比如:
座機打手機
t-主叫號碼 接聽號碼 接聽地點區號 起始時間 結束時間
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手機互打
t-主叫號碼 撥號地點 接聽號碼 接聽地點區號 起始時間 結束時間
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11

注意:以上兩類資訊,先輸入所有開戶資訊,再輸入所有通訊資訊,最后一行以“end”結束,

輸出:
根據輸入的詳細通訊資訊,計算所有已開戶的用戶的當月費用(精確到小數點后2位,單位元),假設每個用戶初始余額是100元,
每條通訊、短信資訊均單獨計費后累加,不是將所有資訊累計后統一計費,
格式:號碼+英文空格符+總的話費+英文空格符+余額
每個用戶一行,用戶之間按號碼字符從小到大排序,

類圖同上題,直接省略,

 

分析:上次題目中只寫了座機的計費,本次需要再加上有關手機計費的類,同座機一樣,分為市內,省內,國內三種計費方式,

代碼如下:

  1 import java.util.*;
  2 import java.util.regex.Matcher;
  3 import java.util.regex.Pattern;
  4 import java.math.BigDecimal;
  5 import java.text.SimpleDateFormat;
  6 import java.text.ParseException;
  7 
  8 public class Main {
  9     public static void main(String[] args) {
 10         Outputtool outputtool = new Outputtool();
 11         Inputdeal inputdeal = new Inputdeal();
 12         ArrayList<User> users = new ArrayList<>();
 13         Scanner in = new Scanner(System.in);
 14         String input = in.nextLine();
 15         while (!input.equals("end")) {
 16             if (1 == inputdeal.check(input)) {
 17                 inputdeal.writeUser(users, input);
 18             } else if (2 == inputdeal.check(input)) {
 19                 inputdeal.writeRecord(users, input);
 20             }
 21             input = in.nextLine();
 22         }
 23         //排序
 24         users.sort(new Comparator<User>() {
 25 
 26             @Override
 27             public int compare(User u1, User u2) {
 28                 if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') {
 29                     return -1;
 30                 } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') {
 31                     return 1;
 32                 }
 33                 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
 34                     return 1;
 35                 } else {
 36                     return -1;
 37                 }
 38             }
 39         });
 40         for (User u : users) {
 41             System.out.print(u.getNumber() + " ");
 42             outputtool.output(u.calCost());
 43             System.out.print(" ");
 44             outputtool.output(u.calBalance());
 45             System.out.println();
 46         }
 47     }
 48 }
 49 
 50 abstract class ChargeMode {
 51     protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
 52 
 53     public abstract double calCost(UserRecords userRecords);
 54 
 55     public abstract double getMonthlyRent();
 56 
 57     public ArrayList<ChargeRule> getChargeRules() {
 58         return chargeRules;
 59     }
 60 
 61     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
 62         this.chargeRules = chargeRules;
 63     }
 64 }
 65 /*
 66  *    類:用戶
 67  * 屬性:用戶通訊詳細資訊記錄userRecords,話費余額,電話付費方式,電話號碼
 68  *
 69  *  */
 70 class User {
 71 
 72     private UserRecords userRecords = new UserRecords();
 73     private double balance = 100;
 74     private ChargeMode chargeMode;
 75     private String number;
 76 
 77     public double calCost() {
 78         return chargeMode.calCost(userRecords);
 79     }
 80 
 81     public double calBalance() {
 82         return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
 83     }
 84 
 85     public UserRecords getUserRecords() {
 86         return userRecords;
 87     }
 88 
 89     public void setUserRecords(UserRecords userRecords) {
 90         this.userRecords = userRecords;
 91     }
 92 
 93     public ChargeMode getChargeMode() {
 94         return chargeMode;
 95     }
 96 
 97     public void setChargeMode(ChargeMode chargeMode) {
 98         this.chargeMode = chargeMode;
 99     }
100 
101     public String getNumber() {
102         return number;
103     }
104 
105     public void setNumber(String number) {
106         this.number = number;
107     }
108 
109 }
110 /*
111  *    類:用戶通訊所有資訊記錄
112  * 屬性:市內撥打電話、省內(不含市內)撥打電話、省外撥打電話、
113  * 市內接聽電話、省內(不含市內)接聽電話、省外接聽電話的記錄
114  * 以及發送短信、接收短信的記錄
115  * 功能:按地址分別記錄通話資訊
116  *  */
117 class UserRecords {
118 
119     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
120     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
121     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
122     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
123     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
124     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
125     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
126     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
127 
128     //記錄資訊,將通訊資訊添加到對應串列
129     public void addCallingInCityRecords(CallRecord callRecord) {
130         callingInCityRecords.add(callRecord);
131     }
132 
133     public void addCallingInProvinceRecords(CallRecord callRecord) {
134         callingInProvinceRecords.add(callRecord);
135     }
136 
137     public void addCallingInLandRecords(CallRecord callRecord) {
138         callingInLandRecords.add(callRecord);
139     }
140 
141     public void addAnswerInCityRecords(CallRecord callRecord) {
142         answerInCityRecords.add(callRecord);
143     }
144 
145     public void addAnswerInProvinceRecords(CallRecord callRecord) {
146         answerInProvinceRecords.add(callRecord);
147     }
148 
149     public void addAnswerInLandRecords(CallRecord callRecord) {
150         answerInLandRecords.add(callRecord);
151     }
152 
153     public void addSendMessageRecords(MessageRecord callRecord) {
154         sendMessageRecords.add(callRecord);
155     }
156 
157     public void addReceiveMessageRecords(MessageRecord callRecord) {
158         receiveMessageRecords.add(callRecord);
159     }
160 
161     public ArrayList<CallRecord> getCallingInCityRecords() {
162         return callingInCityRecords;
163     }
164 
165     public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
166         this.callingInCityRecords = callingInCityRecords;
167     }
168 
169     public ArrayList<CallRecord> getCallingInProvinceRecords() {
170         return callingInProvinceRecords;
171     }
172 
173     public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
174         this.callingInProvinceRecords = callingInProvinceRecords;
175     }
176 
177     public ArrayList<CallRecord> getCallingInLandRecords() {
178         return callingInLandRecords;
179     }
180 
181     public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
182         this.callingInLandRecords = callingInLandRecords;
183     }
184 
185     public ArrayList<CallRecord> getAnswerInCityRecords() {
186         return answerInCityRecords;
187     }
188 
189     public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
190         this.answerInCityRecords = answerInCityRecords;
191     }
192 
193     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
194         return answerInProvinceRecords;
195     }
196 
197     public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
198         this.answerInProvinceRecords = answerInProvinceRecords;
199     }
200 
201     public ArrayList<CallRecord> getAnswerInLandRecords() {
202         return answerInLandRecords;
203     }
204 
205     public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
206         this.answerInLandRecords = answerInLandRecords;
207     }
208 
209     public ArrayList<MessageRecord> getSendMessageRecords() {
210         return sendMessageRecords;
211     }
212 
213     public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
214         this.sendMessageRecords = sendMessageRecords;
215     }
216 
217     public ArrayList<MessageRecord> getReceiveMessageRecords() {
218         return receiveMessageRecords;
219     }
220 
221     public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
222         this.receiveMessageRecords = receiveMessageRecords;
223     }
224 
225 }
226 /*
227  *  座機計費方式
228  *
229  * */
230 class LandlinePhoneCharging extends ChargeMode {
231 
232     private double monthlyRent = 20;
233 
234     public LandlinePhoneCharging() {
235         super();
236         chargeRules.add(new LandPhoneInCityRule());
237         chargeRules.add(new LandPhoneInProvinceRule());
238         chargeRules.add(new LandPhoneInlandRule());
239     }
240 
241     @Override
242     public double calCost(UserRecords userRecords) {
243         double sumCost = 0;
244         for (ChargeRule rule : chargeRules) {
245             sumCost += rule.calCost(userRecords);
246         }
247         return sumCost;
248     }
249 
250     @Override
251     public double getMonthlyRent() {
252         return monthlyRent;
253     }
254 
255 }
256 /*
257  *  手機計費方式
258  *
259  * */
260 class MobilePhoneCharging extends ChargeMode {
261 
262     private double monthlyRent = 15;
263 
264     public MobilePhoneCharging() {
265         super();
266         chargeRules.add(new MobilePhoneInCityRule());
267         chargeRules.add(new MobilePhoneInProvinceRule());
268         chargeRules.add(new MobilePhoneInlandRule());
269     }
270 
271     @Override
272     public double calCost(UserRecords userRecords) {
273         double sumCost = 0;
274         for (ChargeRule rule : chargeRules) {
275             sumCost += rule.calCost(userRecords);
276         }
277         return sumCost;
278     }
279 
280     @Override
281     public double getMonthlyRent() {
282         return monthlyRent;
283     }
284 
285 }
286 /*   類:輸入格式判斷InputDeal
287  * 功能:判斷輸入格式是否正確,時間是否合理
288  *
289  * */
290 class Inputdeal {
291 
292     public int check(String input) {
293         if (input.matches("u-0791\\d{7,8}\\s0") || input.matches("u-1\\d{10}\\s[1]")) {
294             return 1;
295         } else if (input.matches("((t-0791\\d{7,8}\\s" + "0\\d{9,11}\\s)|"
296                 + "(t-0791\\d{7,8}\\s" + "1\\d{10}\\s" + "0\\d{2,3}\\s)|"
297                 + "(t-1\\d{10}\\s" + "0\\d{2,3}\\s" + "0\\d{9,11}\\s)|"
298                 + "(t-1\\d{10}\\s" + "0\\d{2,3}\\s" + "1\\d{10}\\s" + "0\\d{2,3}\\s))"
299 
300                 + "(((\\d{3}[1-9]|\\d{2}[1-9]\\d|\\d[1-9]\\d{2}|[1-9]\\d{3})\\.(((0?[13578]|1[02])\\.(0?"
301                 + "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12]\\d|30))|(2\\.([1-9]|1\\d|2[0-8]))))|((("
302                 + "\\d{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"
303                 + "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5]\\d)\\s"
304                 + "(((\\d{3}[1-9]|\\d{2}[1-9]\\d|\\d[1-9]\\d{2}|[1-9]\\d{3})\\.((([13578]|1[02])\\.("
305                 + "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12]\\d|30))|(2\\.([1-9]|1\\d|2[0-8]))))|((("
306                 + "\\d{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"
307                 + "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5]\\d)")) {
308             return 2;
309         }
310         return 0;
311     }
312 
313     @SuppressWarnings("unused")
314     private boolean validatet(String string) {
315         if (!string.matches("^([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5]\\d)$")) {
316             return false;
317         }
318         return true;
319     }
320 
321     public static boolean validate(String dateString) {
322         // 使用正則運算式 測驗 字符 符合 dddd.dd.dd 的格式(d表示數字)
323         Pattern p = Pattern.compile("\\d{4}+[.]\\d{1,2}+[.]\\d{1,2}+");
324         Matcher m = p.matcher(dateString);
325         if (!m.matches()) {
326             return false;
327         }
328 
329         // 得到年月日
330         String[] array = dateString.split("\\.");
331         int year = Integer.parseInt(array[0]);
332         int month = Integer.parseInt(array[1]);
333         int day = Integer.parseInt(array[2]);
334 
335         if (month < 1 || month > 12) {
336             return false;
337         }
338         int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
339         if (isLeapYear(year)) {
340             monthLengths[2] = 29;
341         } else {
342             monthLengths[2] = 28;
343         }
344         int monthLength = monthLengths[month];
345         return day >= 1 && day <= monthLength;
346     }
347 
348     /** 是否是閏年 */
349     private static boolean isLeapYear(int year) {
350         return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
351     }
352 
353     public void writeUser(ArrayList<User> users, String input) {
354         User usernew = new User();
355         String[] inputs = input.split(" ");
356         String num = inputs[0].substring(2);
357         for (User i : users) {
358             if (i.getNumber().equals(num)) {
359                 return;
360             }
361         }
362         usernew.setNumber(num);
363         int mode = Integer.parseInt(inputs[1]);
364         if (mode == 0) {
365             usernew.setChargeMode(new LandlinePhoneCharging());
366         } else if (mode == 1) {
367             usernew.setChargeMode(new MobilePhoneCharging());
368         }
369         users.add(usernew);
370     }
371 
372     public void writeRecord(ArrayList<User> users, String input) {
373         String[] inputs = input.split(" ");
374 
375         User callu = null, answeru = null;
376         CallRecord callrecord = new CallRecord(inputs);
377 
378         if (input.charAt(0) == 't') {
379             String out = inputs[0];
380             String in = "";
381             if (inputs.length == 6) {
382                 in = inputs[1];
383             } else if (inputs.length == 7) {
384                 in = inputs[1];
385             } else if (inputs.length == 8) {
386                 in = inputs[2];
387             }
388 
389             for (User i : users) {
390                 if (i.getNumber().equals(out)) {
391                     callu = i;
392                 }
393                 if (i.getNumber().equals(in)) {
394                     answeru = i;
395                 }
396                 if (callu != null && answeru != null) {
397                     break;
398                 }
399             }
400 
401             if (callu != null) {
402                 if (callrecord.getCallType().matches("^1[1-3]$")) {
403                     callu.getUserRecords().addCallingInCityRecords(callrecord);
404                 } else if (callrecord.getCallType().matches("^2[1-3]$")) {
405                     callu.getUserRecords().addCallingInProvinceRecords(callrecord);
406                 } else {
407                     callu.getUserRecords().addCallingInLandRecords(callrecord);
408                 }
409             }
410 
411             if (answeru != null) {
412                 if (callrecord.getCallType().matches("^[1-3]1$")) {
413                     answeru.getUserRecords().addAnswerInCityRecords(callrecord);
414                 } else if (callrecord.getCallType().matches("^[1-3]2$")) {
415                     answeru.getUserRecords().addAnswerInProvinceRecords(callrecord);
416                 } else {
417                     answeru.getUserRecords().addAnswerInLandRecords(callrecord);
418                 }
419             }
420         }
421 
422     }
423 
424 }
425 /*
426  *    抽象類:通訊記錄
427  * 屬性:callingNumber撥打號碼、answerNumber接聽號碼
428  *
429  *  */
430 abstract class CommunicationRecord {
431     protected String callingNumber;
432     protected String answerNumber;
433 
434     public String getCallingNumber() {
435         return callingNumber;
436     }
437 
438     public void setCallingNumber(String callingNumber) {
439         this.callingNumber = callingNumber;
440     }
441 
442     public String getAnswerNumber() {
443         return answerNumber;
444     }
445 
446     public void setAnswerNumber(String answerNumber) {
447         this.answerNumber = answerNumber;
448     }
449 
450 }
451 
452 abstract class ChargeRule {
453 
454     abstract public double calCost(UserRecords userRecords);
455 
456 }
457 /*
458  *    類:通話記錄
459  * 屬性:通話起始、結束時間;撥號人地址,接聽人地址
460  * 功能:記錄打電話雙方的地址和通話時間
461  *
462  */
463 class CallRecord extends CommunicationRecord {
464     private Date startTime;
465     private Date endTime;
466     private String callingAddressAreaCode;
467     private String answerAddressAreaCode;
468 
469     public String getCallType() {
470         String type = "";
471         /*
472          * type = 11,市內撥打市內
473          * type = 12,市內撥打省內
474          * type = 13,市內撥打省外
475          * type = 21,省內撥打市內
476          * type = 21,省內撥打省內
477          * type = 21,省內撥打省外
478          * */
479         if (callingAddressAreaCode.equals("0791")) {
480             type = type.concat("1");
481         } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) {
482             type = type.concat("2");
483         } else {
484             type = type.concat("3");
485         }
486 
487         if (answerAddressAreaCode.equals("0791")) {
488             type = type.concat("1");
489         } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) {
490             type = type.concat("2");
491         } else {
492             type = type.concat("3");
493         }
494         return type;
495     }
496 
497     public CallRecord(String[] inputs) {
498         super();
499 
500         char type = inputs[0].charAt(0);
501         inputs[0] = inputs[0].substring(2);
502 
503         String sd = null, st = null, ed = null, et = null;
504 
505         if (type == 't') {
506             if (inputs.length == 6) {
507                 sd = inputs[2];
508                 st = inputs[3];
509                 ed = inputs[4];
510                 et = inputs[5];
511                 callingAddressAreaCode = inputs[0].substring(0, 4);
512                 answerAddressAreaCode = inputs[1].substring(0, 4);
513             } else if (inputs.length == 7) {
514                 sd = inputs[3];
515                 st = inputs[4];
516                 ed = inputs[5];
517                 et = inputs[6];
518                 if (inputs[0].charAt(0) != '0') {   //手機打給座機
519                     if (inputs[2].length() == 10) {
520                         answerAddressAreaCode = inputs[2].substring(0, 3);
521                     } else {
522                         answerAddressAreaCode = inputs[2].substring(0, 4);
523                     }
524                     callingAddressAreaCode = inputs[1];
525                 } else {               //座機打給手機
526                     if (inputs[0].length() == 10) {
527                         callingAddressAreaCode = inputs[0].substring(0, 3);
528                     } else {
529                         callingAddressAreaCode = inputs[0].substring(0, 4);
530                     }
531                     answerAddressAreaCode = inputs[2];
532                 }
533             } else if (inputs.length == 8) {
534                 sd = inputs[4];
535                 st = inputs[5];
536                 ed = inputs[6];
537                 et = inputs[7];
538                 callingAddressAreaCode = inputs[1];
539                 answerAddressAreaCode = inputs[3];
540             }
541         }
542         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
543         try {
544             startTime = simpleDateFormat.parse(sd + " " + st);
545             endTime = simpleDateFormat.parse(ed + " " + et);
546         } catch (ParseException e) {
547         }
548 
549     }
550 
551     public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
552         super();
553         this.startTime = startTime;
554         this.endTime = endTime;
555         this.callingAddressAreaCode = callingAddressAreaCode;
556         this.answerAddressAreaCode = answerAddressAreaCode;
557     }
558 
559     public Date getStartTime() {
560         return startTime;
561     }
562 
563     public void setStartTime(Date startTime) {
564         this.startTime = startTime;
565     }
566 
567     public Date getEndTime() {
568         return endTime;
569     }
570 
571     public void setEndTime(Date endTime) {
572         this.endTime = endTime;
573     }
574 
575     public String getCallingAddressAreaCode() {
576         return callingAddressAreaCode;
577     }
578 
579     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
580         this.callingAddressAreaCode = callingAddressAreaCode;
581     }
582 
583     public String getAnswerAddressAreaCode() {
584         return answerAddressAreaCode;
585     }
586 
587     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
588         this.answerAddressAreaCode = answerAddressAreaCode;
589     }
590 }
591 
592 abstract class CallChargeRule extends ChargeRule {
593 
594 }
595 /*
596  * 市內
597  * */
598 class LandPhoneInCityRule extends CallChargeRule {
599 
600     @Override
601     public double calCost(UserRecords userRecords) {
602         double sumCost = 0;
603         for (CallRecord call : userRecords.getCallingInCityRecords()) {
604             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
605             if (distanceS < 0) {
606                 continue;
607             }
608             double distanceM = (int) distanceS / 60;
609             if (distanceS % 60 != 0) {
610                 distanceM += 1;
611             }
612             if (call.getCallType().equals("11")) {
613                 sumCost += distanceM * 0.1;
614             } else if (call.getCallType().equals("12")) {
615                 sumCost += distanceM * 0.3;
616             } else if (call.getCallType().equals("13")) {
617                 sumCost += distanceM * 0.6;
618             }
619         }
620         return sumCost;
621     }
622 
623 }
624 /*
625  * 國內
626  * */
627 class LandPhoneInlandRule extends CallChargeRule {
628 
629     @Override
630     public double calCost(UserRecords userRecords) {
631         double sumCost = 0;
632         for (CallRecord call : userRecords.getCallingInLandRecords()) {
633             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
634             if (distanceS < 0) {
635                 continue;
636             }
637             double distanceM = (int) distanceS / 60;
638             if (distanceS % 60 != 0) {
639                 distanceM += 1;
640             }
641             sumCost += distanceM * 0.6;
642         }
643         return sumCost;
644     }
645 
646 }
647 /*
648  * 省內
649  */
650 class LandPhoneInProvinceRule extends CallChargeRule {
651 
652     @Override
653     public double calCost(UserRecords userRecords) {
654         double sumCost = 0;
655         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
656             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
657             if (distanceS < 0) {
658                 continue;
659             }
660             double distanceM = (int) distanceS / 60;
661             if (distanceS % 60 != 0) {
662                 distanceM += 1;
663             }
664             sumCost += distanceM * 0.3;
665         }
666         return sumCost;
667     }
668 
669 }
670 /*
671  * 手機市內付費
672  */
673 class MobilePhoneInCityRule extends CallChargeRule {
674 
675     @Override
676     public double calCost(UserRecords userRecords) {
677         double sumCost = 0;
678         for (CallRecord call : userRecords.getCallingInCityRecords()) {
679             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
680             if (distanceS < 0) {
681                 continue;
682             }
683             double distanceM = (int) distanceS / 60;
684             if (distanceS % 60 != 0) {
685                 distanceM += 1;
686             }
687             if (call.getCallType().equals("11")) {
688                 sumCost += distanceM * 0.1;
689             } else if (call.getCallType().equals("12")) {
690                 sumCost += distanceM * 0.2;
691             } else if (call.getCallType().equals("13")) {
692                 sumCost += distanceM * 0.3;
693             }
694 
695         }
696         return sumCost;
697     }
698 
699 }
700 /*
701  * 手機國內
702  */
703 class MobilePhoneInlandRule extends CallChargeRule {
704 
705     @Override
706     public double calCost(UserRecords userRecords) {
707         double sumCost = 0;
708         for (CallRecord call : userRecords.getCallingInLandRecords()) {
709             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
710             if (distanceS < 0) {
711                 continue;
712             }
713             double distanceM = (int) distanceS / 60;
714             if (distanceS % 60 != 0) {
715                 distanceM += 1;
716             }
717             sumCost += distanceM * 0.6;
718         }
719         for (CallRecord call : userRecords.getAnswerInLandRecords()) {
720             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
721             if (distanceS < 0) {
722                 continue;
723             }
724             double distanceM = (int) distanceS / 60;
725             if (distanceS % 60 != 0) {
726                 distanceM += 1;
727             }
728             sumCost += distanceM * 0.3;
729         }
730         return sumCost;
731     }
732 
733 }
734 /*
735  * 手機省內
736  */
737 class MobilePhoneInProvinceRule extends CallChargeRule {
738 
739     @Override
740     public double calCost(UserRecords userRecords) {
741         double sumCost = 0;
742         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
743             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
744             if (distanceS < 0) {
745                 continue;
746             }
747             double distanceM = (int) distanceS / 60;
748             if (distanceS % 60 != 0) {
749                 distanceM += 1;
750             }
751             if (call.getCallType().equals("21")) {
752                 sumCost += distanceM * 0.3;
753             } else if (call.getCallType().equals("22")) {
754                 sumCost += distanceM * 0.3;
755             } else if (call.getCallType().equals("23")) {
756                 sumCost += distanceM * 0.3;
757             }
758         }
759         return sumCost;
760     }
761 
762 }
763 
764 class MessageRecord extends CommunicationRecord {
765 
766     private String message;
767 
768     public String getMessage() {
769         return message;
770     }
771 
772     public void setMessage(String message) {
773         this.message = message;
774     }
775 }
776 /*
777  *    類:用戶
778  * 屬性:用戶通訊詳細資訊記錄userRecords,話費余額,電話付費方式,電話號碼
779  *
780  *  */
781 class User {
782 
783     private UserRecords userRecords = new UserRecords();
784     private double balance = 100;
785     private ChargeMode chargeMode;
786     private String number;
787 
788     public double calCost() {
789         return chargeMode.calCost(userRecords);
790     }
791 
792     public double calBalance() {
793         return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
794     }
795 
796     public UserRecords getUserRecords() {
797         return userRecords;
798     }
799 
800     public void setUserRecords(UserRecords userRecords) {
801         this.userRecords = userRecords;
802     }
803 
804     public ChargeMode getChargeMode() {
805         return chargeMode;
806     }
807 
808     public void setChargeMode(ChargeMode chargeMode) {
809         this.chargeMode = chargeMode;
810     }
811 
812     public String getNumber() {
813         return number;
814     }
815 
816     public void setNumber(String number) {
817         this.number = number;
818     }
819 
820 }
821 
822 class Outputtool {
823 
824     @SuppressWarnings("deprecation")
825     public void output(double out) {
826         BigDecimal numb = new BigDecimal(out);
827         out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
828         System.out.print(out);
829     }
830 }
View Code

結果:

 

 

分析:這次代碼我將輸入格式判斷之類的函式全都放到了一個inputdeal類中,對寫入正確通信資訊的方法進行了改進,最后所有測驗點都過了,有source monitor的圖可以看出,形狀與上次代碼的差不多,不過由于處理函式多了,總體的圈復雜度稍微增大了一些,

 

 3.7-3 閱讀程式,按照題目需求修改程式

題目略,

分析:這次題目里面給出了代碼,只是有些細節問題,需要修改,但就是這些細節讓我改了很久,因為他還考察Iterator,Collection這些陌生的類,后來看了很多網上的解釋再去改,還是過不了,原來問題不在這,是輸入scanner有問題,要把它放到回圈外面,,,

代碼略,

4.第8次作業:7-1 電信計費系列3-短信計費

實作一個簡單的電信計費程式,針對手機的短信采用如下計費方式
1、接收短信免費,發送短信0.1元/條,超過3條0.2元/條,超過5條0.3元/條,
2、如果一次發送短信的字符數量超過10個,按每10個字符一條短信進行計算,

輸入:
輸入資訊包括兩種型別
1、逐行輸入南昌市手機用戶開戶的資訊,每行一個用戶,
格式:u-號碼 計費型別 (計費型別包括:0-座機 1-手機實時計費 2-手機A套餐 3-手機短信計費)
例如:u-13305862264 3
座機號碼由區號和電話號碼拼接而成,電話號碼包含7-8位數字,區號最高位是0,
手機號碼由11位數字構成,最高位是1,
本題只針對型別3-手機短信計費,
2、逐行輸入本月某些用戶的短信資訊,短信的格式:
m-主叫號碼,接收號碼,短信內容 (短信內容只能由數字、字母、空格、英文逗號、英文句號組成)
m-18907910010 13305862264 welcome to jiangxi.
m-13305862264 18907910010 thank you.

注意:以上兩類資訊,先輸入所有開戶資訊,再輸入所有通訊資訊,最后一行以“end”結束,

類圖及其他要求略,

分析:這次難度就降低了,只需要照著之前的框架寫就行,不過最后700多行的代碼它還顯示太長了,我就把之前的座機,手機電話付費的刪掉了,測驗點也都能過,

代碼如下:

  1 import java.util.ArrayList;
  2 import java.util.Comparator;
  3 import java.util.Scanner;
  4 import java.math.BigDecimal;
  5 import java.text.SimpleDateFormat;
  6 import java.util.Date;
  7 import java.util.Locale;
  8 import java.text.ParseException;
  9 
 10 public class Main {
 11 
 12     public static void main(String[] args) {
 13 
 14         Outputtool outputtool = new Outputtool();
 15 
 16         Inputdeal inputdeal = new Inputdeal();
 17 
 18         ArrayList<User> users = new ArrayList<>();
 19 
 20         Scanner in = new Scanner(System.in);
 21 
 22         String input = in.nextLine();
 23 
 24         while (!input.equals("end")) {
 25             if (1 == inputdeal.check(input)) {
 26                 inputdeal.writeUser(users, input);
 27             } else if (2 == inputdeal.check(input)) {
 28                 inputdeal.writeRecord(users, input);
 29             }
 30             input = in.nextLine();
 31         }
 32 
 33         users.sort(new Comparator<User>() {
 34 
 35             @Override
 36             public int compare(User u1, User u2) {
 37                 if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') {
 38                     return -1;
 39                 } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') {
 40                     return 1;
 41                 }
 42                 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
 43                     return 1;
 44                 } else {
 45                     return -1;
 46                 }
 47             }
 48         });
 49 
 50         for (User u : users) {
 51             System.out.print(u.getNumber() + " ");
 52             outputtool.output(u.calCost());
 53             System.out.print(" ");
 54             outputtool.output(u.calBalance());
 55             System.out.println();
 56 
 57         }
 58 
 59     }
 60 
 61 }
 62 
 63 abstract class ChargeMode {
 64     protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
 65 
 66     public abstract double calCost(UserRecords userRecords);
 67 
 68     public abstract double getMonthlyRent();
 69 
 70     public ArrayList<ChargeRule> getChargeRules() {
 71         return chargeRules;
 72     }
 73 
 74     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
 75         this.chargeRules = chargeRules;
 76     }
 77 }
 78 /*
 79  *    類:用戶
 80  * 屬性:用戶通訊詳細資訊記錄userRecords,話費余額,電話付費方式,電話號碼
 81  *
 82  *  */
 83 class User {
 84 
 85     private UserRecords userRecords = new UserRecords();
 86     private double balance = 100;
 87     private ChargeMode chargeMode;
 88     private String number;
 89 
 90     public double calCost() {
 91         return chargeMode.calCost(userRecords);
 92     }
 93 
 94     public double calBalance() {
 95         return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
 96     }
 97 
 98     public UserRecords getUserRecords() {
 99         return userRecords;
100     }
101 
102     public void setUserRecords(UserRecords userRecords) {
103         this.userRecords = userRecords;
104     }
105 
106     public ChargeMode getChargeMode() {
107         return chargeMode;
108     }
109 
110     public void setChargeMode(ChargeMode chargeMode) {
111         this.chargeMode = chargeMode;
112     }
113 
114     public String getNumber() {
115         return number;
116     }
117 
118     public void setNumber(String number) {
119         this.number = number;
120     }
121 
122 }
123 /*
124  *    類:用戶通訊所有資訊記錄
125  * 屬性:市內撥打電話、省內(不含市內)撥打電話、省外撥打電話、
126  * 市內接聽電話、省內(不含市內)接聽電話、省外接聽電話的記錄
127  * 以及發送短信、接收短信的記錄
128  * 功能:按地址分別記錄通話資訊
129  *  */
130 class UserRecords {
131 
132     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
133     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
134     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
135     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
136     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
137     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
138     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
139     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
140 
141     public void addCallingInCityRecords(CallRecord callRecord) {
142         callingInCityRecords.add(callRecord);
143     }
144 
145     public void addCallingInProvinceRecords(CallRecord callRecord) {
146         callingInProvinceRecords.add(callRecord);
147     }
148 
149     public void addCallingInLandRecords(CallRecord callRecord) {
150         callingInLandRecords.add(callRecord);
151     }
152 
153     public void addAnswerInCityRecords(CallRecord callRecord) {
154         answerInCityRecords.add(callRecord);
155     }
156 
157     public void aaddAnswerInProvinceRecords(CallRecord callRecord) {
158         answerInProvinceRecords.add(callRecord);
159     }
160 
161     public void addAnswerInLandRecords(CallRecord callRecord) {
162         answerInLandRecords.add(callRecord);
163     }
164 
165     public void addSendMessageRecords(MessageRecord callRecord) {
166         sendMessageRecords.add(callRecord);
167     }
168 
169     public void addReceiveMessageRecords(MessageRecord callRecord) {
170         receiveMessageRecords.add(callRecord);
171     }
172 
173     public ArrayList<CallRecord> getCallingInCityRecords() {
174         return callingInCityRecords;
175     }
176 
177     public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
178         this.callingInCityRecords = callingInCityRecords;
179     }
180 
181     public ArrayList<CallRecord> getCallingInProvinceRecords() {
182         return callingInProvinceRecords;
183     }
184 
185     public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
186         this.callingInProvinceRecords = callingInProvinceRecords;
187     }
188 
189     public ArrayList<CallRecord> getCallingInLandRecords() {
190         return callingInLandRecords;
191     }
192 
193     public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
194         this.callingInLandRecords = callingInLandRecords;
195     }
196 
197     public ArrayList<CallRecord> getAnswerInCityRecords() {
198         return answerInCityRecords;
199     }
200 
201     public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
202         this.answerInCityRecords = answerInCityRecords;
203     }
204 
205     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
206         return answerInProvinceRecords;
207     }
208 
209     public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
210         this.answerInProvinceRecords = answerInProvinceRecords;
211     }
212 
213     public ArrayList<CallRecord> getAnswerInLandRecords() {
214         return answerInLandRecords;
215     }
216 
217     public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
218         this.answerInLandRecords = answerInLandRecords;
219     }
220 
221     public ArrayList<MessageRecord> getSendMessageRecords() {
222         return sendMessageRecords;
223     }
224 
225     public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
226         this.sendMessageRecords = sendMessageRecords;
227     }
228 
229     public ArrayList<MessageRecord> getReceiveMessageRecords() {
230         return receiveMessageRecords;
231     }
232 
233     public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
234         this.receiveMessageRecords = receiveMessageRecords;
235     }
236 
237 }
238 
239 /*
240  *  座機計費方式
241  *  不包括通話計費
242  * */
243 class LandlinePhoneCharging extends ChargeMode {
244 
245     private double monthlyRent = 20;
246 /*
247     public LandlinePhoneCharging() {
248         super();
249         chargeRules.add(new LandPhoneInCityRule());
250         chargeRules.add(new LandPhoneInProvinceRule());
251         chargeRules.add(new LandPhoneInlandRule());
252     }
253 */
254     @Override
255     public double calCost(UserRecords userRecords) {
256         double sumCost = 0;
257         for (ChargeRule rule : chargeRules) {
258             sumCost += rule.calCost(userRecords);
259         }
260         return sumCost;
261     }
262 
263     @Override
264     public double getMonthlyRent() {
265         return monthlyRent;
266     }
267 
268 }
269 
270 /*
271  *  手機計費方式
272  *  去掉通話計費
273  * */
274 class MobilePhoneCharging extends ChargeMode {
275 
276     private double monthlyRent = 15;
277     
278     /*public MobilePhoneCharging() {
279         super();
280         chargeRules.add(new MobilePhoneInCityRule());
281         chargeRules.add(new MobilePhoneInProvinceRule());
282         chargeRules.add(new MobilePhoneInlandRule());
283     }*/
284 
285     @Override
286     public double calCost(UserRecords userRecords) {
287         double sumCost = 0;
288         for (ChargeRule rule : chargeRules) {
289             sumCost += rule.calCost(userRecords);
290         }
291         return sumCost;
292     }
293 
294     @Override
295     public double getMonthlyRent() {
296         return monthlyRent;
297     }
298 
299 }
300 /*
301  *  手機短信計費方式
302  *
303  * */
304 class MobilePhoneMassageCharging extends ChargeMode {
305 
306     private double monthlyRent = 0;
307 
308     public MobilePhoneMassageCharging() {
309         super();
310         chargeRules.add(new MobilePhoneMessageRule());
311     }
312 
313     @Override
314     public double calCost(UserRecords userRecords) {
315         double sumCost = 0;
316         for (ChargeRule rule : chargeRules) {
317             sumCost += rule.calCost(userRecords);
318         }
319         return sumCost;
320     }
321 
322     @Override
323     public double getMonthlyRent() {
324         return monthlyRent;
325     }
326 
327 }
328 
329 class Inputdeal {
330 
331     public int check(String input) {
332         if (input.matches("u-0791\\d{7,8}\\s[0]") || input.matches("u-1\\d{10}\\s[13]")) {
333             return 1;
334         } else if (input.matches("m-1\\d{10}\\s" + "1\\d{10}\\s" + "[\\da-zA-Z\\s.,]+")) {
335             return 2;
336         }
337         return 0;
338     }
339 
340     public void writeUser(ArrayList<User> users, String input) {
341         User usernew = new User();
342         String[] inputs = input.split(" ");
343         String num = inputs[0].substring(2);
344         for (User i : users) {
345             if (i.getNumber().equals(num)) {
346                 return;
347             }
348         }
349         usernew.setNumber(num);
350         int mode = Integer.parseInt(inputs[1]);
351         if (mode == 0) {
352             usernew.setChargeMode(new LandlinePhoneCharging());
353         } else if (mode == 1) {
354             usernew.setChargeMode(new MobilePhoneCharging());
355         } else if (mode == 3) {
356             usernew.setChargeMode(new MobilePhoneMassageCharging());
357         }
358         users.add(usernew);
359     }
360 
361     public void writeRecord(ArrayList<User> users, String input) {
362         String[] inputs = input.split(" ");
363         inputs[0] = inputs[0].substring(2);
364 
365         User callu = null, answeru = null;
366 
367         String out = inputs[0];
368         String in = "";
369         if (inputs.length == 6) {
370             in = inputs[1];
371         } else if (inputs.length == 7) {
372             in = inputs[1];
373         } else if (inputs.length == 8) {
374             in = inputs[2];
375         } else {
376             in = inputs[1];
377         }
378 
379         for (User i : users) {
380             if (i.getNumber().equals(out)) {
381                 callu = i;
382             }
383             if (i.getNumber().equals(in)) {
384                 answeru = i;
385             }
386             if (callu != null && answeru != null) {
387                 break;
388             }
389         }
390 
391         if (input.charAt(0) == 'm') {
392             MessageRecord messageRecord = new MessageRecord(input);
393             if (callu != null) {
394                 callu.getUserRecords().addSendMessageRecords(messageRecord);
395                 
396             }
397             if (answeru != null) {
398                 callu.getUserRecords().addReceiveMessageRecords(messageRecord);
399             }
400         }
401 
402     }
403 
404 }
405 /*
406  *    抽象類:通訊記錄
407  * 屬性:callingNumber撥打號碼、answerNumber接聽號碼
408  *
409  *  */
410 abstract class CommunicationRecord {
411     protected String callingNumber;
412     protected String answerNumber;
413 
414     public String getCallingNumber() {
415         return callingNumber;
416     }
417 
418     public void setCallingNumber(String callingNumber) {
419         this.callingNumber = callingNumber;
420     }
421 
422     public String getAnswerNumber() {
423         return answerNumber;
424     }
425 
426     public void setAnswerNumber(String answerNumber) {
427         this.answerNumber = answerNumber;
428     }
429 
430 }
431 
432 abstract class ChargeRule {
433 
434     abstract public double calCost(UserRecords userRecords);
435 
436 }
437 /*
438  *    類:電話和短信具體資訊記錄
439  * 屬性:通話起始、結束時間;撥號人地址,接聽人地址
440  * 功能:記錄短信接收雙方的地址和通話時間
441  *
442  */
443 class CallRecord extends CommunicationRecord {
444     private Date startTime;
445     private Date endTime;
446     private String callingAddressAreaCode;
447     private String answerAddressAreaCode;
448 
449     public String getCallType() {
450         String type = "";
451         if (callingAddressAreaCode.equals("0791")) {
452             type = type.concat("1");
453         } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) {
454             type = type.concat("2");
455         } else {
456             type = type.concat("3");
457         }
458 
459         if (answerAddressAreaCode.equals("0791")) {
460             type = type.concat("1");
461         } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) {
462             type = type.concat("2");
463         } else {
464             type = type.concat("3");
465         }
466 
467         return type;
468     }
469 
470     public CallRecord(String[] inputs) {
471         super();
472 
473         char type = inputs[0].charAt(0);
474 
475         String sd = null, st = null, ed = null, et = null;
476 
477         if (type == 't') {
478             if (inputs.length == 6) {
479                 sd = inputs[2];
480                 st = inputs[3];
481                 ed = inputs[4];
482                 et = inputs[5];
483                 callingAddressAreaCode = inputs[0].substring(0, 4);
484                 answerAddressAreaCode = inputs[1].substring(0, 4);
485             } else if (inputs.length == 7) {
486                 sd = inputs[3];
487                 st = inputs[4];
488                 ed = inputs[5];
489                 et = inputs[6];
490                 if (inputs[0].charAt(0) != '0') {
491                     if (inputs[2].length() == 10) {
492                         answerAddressAreaCode = inputs[2].substring(0, 3);
493                     } else {
494                         answerAddressAreaCode = inputs[2].substring(0, 4);
495                     }
496                     callingAddressAreaCode = inputs[1];
497                 } else {
498                     if (inputs[0].length() == 10) {
499                         callingAddressAreaCode = inputs[0].substring(0, 3);
500                     } else {
501                         callingAddressAreaCode = inputs[0].substring(0, 4);
502                     }
503                     answerAddressAreaCode = inputs[2];
504                 }
505             } else if (inputs.length == 8) {
506                 sd = inputs[4];
507                 st = inputs[5];
508                 ed = inputs[6];
509                 et = inputs[7];
510                 callingAddressAreaCode = inputs[1];
511                 answerAddressAreaCode = inputs[3];
512             }
513         } else if (type == 'm') {
514 
515         }
516         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
517         try {
518             startTime = simpleDateFormat.parse(sd + " " + st);
519             endTime = simpleDateFormat.parse(ed + " " + et);
520         } catch (ParseException e) {
521         }
522 
523     }
524 
525     public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
526         super();
527         this.startTime = startTime;
528         this.endTime = endTime;
529         this.callingAddressAreaCode = callingAddressAreaCode;
530         this.answerAddressAreaCode = answerAddressAreaCode;
531     }
532 
533     public Date getStartTime() {
534         return startTime;
535     }
536 
537     public void setStartTime(Date startTime) {
538         this.startTime = startTime;
539     }
540 
541     public Date getEndTime() {
542         return endTime;
543     }
544 
545     public void setEndTime(Date endTime) {
546         this.endTime = endTime;
547     }
548 
549     public String getCallingAddressAreaCode() {
550         return callingAddressAreaCode;
551     }
552 
553     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
554         this.callingAddressAreaCode = callingAddressAreaCode;
555     }
556 
557     public String getAnswerAddressAreaCode() {
558         return answerAddressAreaCode;
559     }
560 
561     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
562         this.answerAddressAreaCode = answerAddressAreaCode;
563     }
564 }
565 
566 abstract class CallChargeRule extends ChargeRule {
567 
568 }
569 /*
570  *    類:手機短信計費
571  * 屬性:通話起始、結束時間;撥號人地址,接聽人地址
572  */
573 class MobilePhoneMessageRule extends CallChargeRule {
574 
575     @Override
576     public double calCost(UserRecords userRecords) {
577         double sumCost = 0;
578         int number = 0;
579         for (MessageRecord m : userRecords.getSendMessageRecords()) {
580             int length = m.getMessage().length();
581             if (length <= 10) {
582                 number++;
583             } else {
584                 number += length / 10;
585                 if (length % 10 != 0) {
586                     number++;
587                 }
588             }
589         }
590         if (number <= 3) {
591             sumCost = number * 0.1;
592         } else if (number <= 5) {
593             sumCost = 0.3 + 0.2 * (number - 3);
594         } else {
595             sumCost = 0.7 + 0.3 * (number - 5);
596         }
597         return sumCost;
598     }
599 
600 }
601 
602 class MessageRecord extends CommunicationRecord {
603 
604     private String message;
605 
606     public MessageRecord(String input) {
607         super();
608         this.message = input.substring(26);
609     }
610 
611     public String getMessage() {
612         return message;
613     }
614 
615     public void setMessage(String message) {
616         this.message = message;
617     }
618 }
619 
620 class Outputtool {
621 
622     @SuppressWarnings("deprecation")
623     public void output(double out) {
624         BigDecimal numb = new BigDecimal(out);
625         out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
626         System.out.print(out);
627     }
628 }
View Code

結果:

 

 

 

 

 

 分析:在之前兩次電信題中已經打好了框架,只需加上短信詳細的計費方法的類即可,總體的圈復雜度與之前的大同小異,

三、踩坑心得

1.電信系列1

(1)首先就是輸入格式的判斷,需要判斷號碼的格式是否正確,以及時間是否合理,因為時間有年,月,日,小時,分鐘,秒,年要判斷是否為閏年,月份也不一樣等,所以判斷格式是否正確就寫了很長的代碼,

(2)ArrayList類的使用,不只電信系列中用到了,這三次作業中幾乎都用到了,資料太多了,必須用ArrayList建立一個物件來存盤,還需要重寫sort方法,

(3)類特別多,需要非常好的邏輯性,靈活運用抽象類或介面,寫代碼的很容易暈,可能是我還沒有完全掌握抽象類的用法,

(4)需要用到一些之前沒用過的類,例如:Comparator,SimpleDateFormat,Date,

四、改進建議

        這三次作業的題目都比較詳細,要么給出了UML圖,要么直接給出了部分代碼,或詳細描述了類里面的成員方法,按照題目要求來,最后寫出的代碼都比較優良,但是寫電信3的代碼時,我的代碼長度達到了800行左右,提交不了,說篇幅過長了,我只是縮減了一些本題可能用不到的代碼(但其實是有用代碼),說明前面寫的代碼還是復雜了些,沒有用到更簡便的方法,例如以下代碼:

 1 }
 2 /*
 3  * 市內
 4  * */
 5 class LandPhoneInCityRule extends CallChargeRule {
 6 
 7     @Override
 8     public double calCost(UserRecords userRecords) {
 9         double sumCost = 0;
10         for (CallRecord call : userRecords.getCallingInCityRecords()) {
11             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
12             if (distanceS < 0) {
13                 continue;
14             }
15             double distanceM = (int) distanceS / 60;
16             if (distanceS % 60 != 0) {
17                 distanceM += 1;
18             }
19             if (call.getCallType().equals("11")) {
20                 sumCost += distanceM * 0.1;
21             } else if (call.getCallType().equals("12")) {
22                 sumCost += distanceM * 0.3;
23             } else if (call.getCallType().equals("13")) {
24                 sumCost += distanceM * 0.6;
25             }
26         }
27         return sumCost;
28     }
29 
30 }
31 /*
32  * 國內
33  * */
34 class LandPhoneInlandRule extends CallChargeRule {
35 
36     @Override
37     public double calCost(UserRecords userRecords) {
38         double sumCost = 0;
39         for (CallRecord call : userRecords.getCallingInLandRecords()) {
40             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
41             if (distanceS < 0) {
42                 continue;
43             }
44             double distanceM = (int) distanceS / 60;
45             if (distanceS % 60 != 0) {
46                 distanceM += 1;
47             }
48             sumCost += distanceM * 0.6;
49         }
50         return sumCost;
51     }
52 
53 }
54 /*
55  * 省內
56  */
57 class LandPhoneInProvinceRule extends CallChargeRule {
58 
59     @Override
60     public double calCost(UserRecords userRecords) {
61         double sumCost = 0;
62         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
63             double distanceS = (call.getEndTime().getTime() - call.getStartTime().getTime()) / 1000;
64             if (distanceS < 0) {
65                 continue;
66             }
67             double distanceM = (int) distanceS / 60;
68             if (distanceS % 60 != 0) {
69                 distanceM += 1;
70             }
71             sumCost += distanceM * 0.3;
72         }
73         return sumCost;
74     }
75 
76 }

這些計算費用方法中有部分代碼重復了,手機三個,座機三個,還有一個短信的,相同代碼重復太多次了,不太符合java代碼復用的原則,增加代碼長度,可以單獨提煉出一個static方法或類,

        還有就是輸入格式判斷中我用到了一個很長的正則運算式,感覺這個方法不太好,應該還能有其他更簡便的方法吧,

五、總結

       這三次作業主要讓我們練習了抽象類,介面,內部類,以及一些如ArrayList,Date等常用類,演算法上相較之前幾次的作業來講更簡單了,但是更集中的運用了java寫代碼的套路,可以感覺到作業更java啦!從這幾次作業也可看出多型能減少代碼長度,且更能體現代碼復用或者說java的便利,不過繼承與多型好像常常是同時出現的,都能實作代碼復用,除了繼承,多型,聚合等類的關系外,還要多去學習一些java中常用的類,java庫中已經建好了很多實作方法,可以直接拿來用,會方便很多,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/539706.html

標籤:其他

上一篇:用戶重復注冊分析-多執行緒事務中加鎖引發的bug

下一篇:新款 c++ web framework 支持orm http/2

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more