百木园-与人分享,
就是让自己快乐。

PTA作业6-8电信系列总结

一、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

 

分析:本题要求比较多,但给出了类图,需要先根据类图建立好这些类,在考虑如何实现,最后测试,根据结果作出适当调整。不过需要注意,最后输出的通信记录需要按电话这串字符从小到大排序的,还要写一个类用来判断格式,需要判断闰年。

代码如下:(代码很长已全部折叠)

PTA作业6-8电信系列总结PTA作业6-8电信系列总结

  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

结果:

PTA作业6-8电信系列总结

 

 

 分析:电信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元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。

类图同上题,直接省略。

 

分析:上次题目中只写了座机的计费,本次需要再加上有关手机计费的类,同座机一样,分为市内,省内,国内三种计费方式。

代码如下:

PTA作业6-8电信系列总结PTA作业6-8电信系列总结

  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

结果:

PTA作业6-8电信系列总结

 

 

分析:这次代码我将输入格式判断之类的函数全都放到了一个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多行的代码它还显示太长了,我就把之前的座机,手机电话付费的删掉了,测试点也都能过。

代码如下:

PTA作业6-8电信系列总结PTA作业6-8电信系列总结

  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

结果:

PTA作业6-8电信系列总结

 

 

 

 

 

 分析:在之前两次电信题中已经打好了框架,只需加上短信详细的计费方法的类即可,总体的圈复杂度与之前的大同小异。

三、踩坑心得

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.cnblogs.com/java-036/p/16961766.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » PTA作业6-8电信系列总结

相关推荐

  • 暂无文章