最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

【焦点热闻】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,可根据理解自行调整:

图1图1中User是用户类,包括属性:userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。ChargeMode是计费方式的抽象类:chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。getMonthlyRent()方法用于返回月租(monthlyRent)。UserRecords是用户记录类,保存用户各种通话、短信的记录,    各种计费规则将使用其中的部分或者全部记录。其属性从上到下依次是:市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、市内接听电话、省内(不含市内)接听电话、省外接听电话的记录以及发送短信、接收短信的记录。
图2图2中CommunicationRecord是抽象的通讯记录类:包含callingNumber拨打号码、answerNumber接听号码两个属性。CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。CallRecord(通话记录类)包含属性:通话的起始、结束时间以及拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。
图3图3是计费规则的相关类,这些类的核心方法是:calCost(ArrayList 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 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() { 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 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 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 chargeRules = new ArrayList<>();119 120     public abstract double calCost(UserRecords userRecords);121 122     public abstract double getMonthlyRent();123 124     public ArrayList getChargeRules() {125         return chargeRules;126     }127 128     public void setChargeRules(ArrayList chargeRules) {129         this.chargeRules = chargeRules;130     }131 }132 /*133  *    类:用户通讯所有信息记录134  * 属性:市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、135  * 市内接听电话、省内(不含市内)接听电话、省外接听电话的记录136  * 以及发送短信、接收短信的记录137  * 功能:按地址分别记录通话信息138  *  */139 class UserRecords {140 141     private ArrayList callingInCityRecords = new ArrayList();142     private ArrayList callingInProvinceRecords = new ArrayList();143     private ArrayList callingInLandRecords = new ArrayList();144     private ArrayList answerInCityRecords = new ArrayList();145     private ArrayList answerInProvinceRecords = new ArrayList();146     private ArrayList answerInLandRecords = new ArrayList();147     private ArrayList sendMessageRecords = new ArrayList();148     private ArrayList receiveMessageRecords = new ArrayList();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 getCallingInCityRecords() {183         return callingInCityRecords;184     }185 186     public void setCallingInCityRecords(ArrayList callingInCityRecords) {187         this.callingInCityRecords = callingInCityRecords;188     }189 190     public ArrayList getCallingInProvinceRecords() {191         return callingInProvinceRecords;192     }193 194     public void setCallingInProvinceRecords(ArrayList callingInProvinceRecords) {195         this.callingInProvinceRecords = callingInProvinceRecords;196     }197 198     public ArrayList getCallingInLandRecords() {199         return callingInLandRecords;200     }201 202     public void setCallingInLandRecords(ArrayList callingInLandRecords) {203         this.callingInLandRecords = callingInLandRecords;204     }205 206     public ArrayList getAnswerInCityRecords() {207         return answerInCityRecords;208     }209 210     public void setAnswerInCityRecords(ArrayList answerInCityRecords) {211         this.answerInCityRecords = answerInCityRecords;212     }213 214     public ArrayList getAnswerInProvinceRecords() {215         return answerInProvinceRecords;216     }217 218     public void setAnswerInProvinceRecords(ArrayList answerInProvinceRecords) {219         this.answerInProvinceRecords = answerInProvinceRecords;220     }221 222     public ArrayList getAnswerInLandRecords() {223         return answerInLandRecords;224     }225 226     public void setAnswerInLandRecords(ArrayList answerInLandRecords) {227         this.answerInLandRecords = answerInLandRecords;228     }229 230     public ArrayList getSendMessageRecords() {231         return sendMessageRecords;232     }233 234     public void setSendMessageRecords(ArrayList sendMessageRecords) {235         this.sendMessageRecords = sendMessageRecords;236     }237 238     public ArrayList getReceiveMessageRecords() {239         return receiveMessageRecords;240     }241 242     public void setReceiveMessageRecords(ArrayList 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     @Override263     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     @Override272     public double getMonthlyRent() {273         return monthlyRent;274     }275 276 }277 /*   类:输入格式判断InputDeal278  * 功能:判断输入格式是否正确,时间是否合理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     @Override457     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     @Override480     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     @Override503     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 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() { 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 chargeRules = new ArrayList<>(); 52  53     public abstract double calCost(UserRecords userRecords); 54  55     public abstract double getMonthlyRent(); 56  57     public ArrayList getChargeRules() { 58         return chargeRules; 59     } 60  61     public void setChargeRules(ArrayList 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 callingInCityRecords = new ArrayList();120     private ArrayList callingInProvinceRecords = new ArrayList();121     private ArrayList callingInLandRecords = new ArrayList();122     private ArrayList answerInCityRecords = new ArrayList();123     private ArrayList answerInProvinceRecords = new ArrayList();124     private ArrayList answerInLandRecords = new ArrayList();125     private ArrayList sendMessageRecords = new ArrayList();126     private ArrayList receiveMessageRecords = new ArrayList();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 getCallingInCityRecords() {162         return callingInCityRecords;163     }164 165     public void setCallingInCityRecords(ArrayList callingInCityRecords) {166         this.callingInCityRecords = callingInCityRecords;167     }168 169     public ArrayList getCallingInProvinceRecords() {170         return callingInProvinceRecords;171     }172 173     public void setCallingInProvinceRecords(ArrayList callingInProvinceRecords) {174         this.callingInProvinceRecords = callingInProvinceRecords;175     }176 177     public ArrayList getCallingInLandRecords() {178         return callingInLandRecords;179     }180 181     public void setCallingInLandRecords(ArrayList callingInLandRecords) {182         this.callingInLandRecords = callingInLandRecords;183     }184 185     public ArrayList getAnswerInCityRecords() {186         return answerInCityRecords;187     }188 189     public void setAnswerInCityRecords(ArrayList answerInCityRecords) {190         this.answerInCityRecords = answerInCityRecords;191     }192 193     public ArrayList getAnswerInProvinceRecords() {194         return answerInProvinceRecords;195     }196 197     public void setAnswerInProvinceRecords(ArrayList answerInProvinceRecords) {198         this.answerInProvinceRecords = answerInProvinceRecords;199     }200 201     public ArrayList getAnswerInLandRecords() {202         return answerInLandRecords;203     }204 205     public void setAnswerInLandRecords(ArrayList answerInLandRecords) {206         this.answerInLandRecords = answerInLandRecords;207     }208 209     public ArrayList getSendMessageRecords() {210         return sendMessageRecords;211     }212 213     public void setSendMessageRecords(ArrayList sendMessageRecords) {214         this.sendMessageRecords = sendMessageRecords;215     }216 217     public ArrayList getReceiveMessageRecords() {218         return receiveMessageRecords;219     }220 221     public void setReceiveMessageRecords(ArrayList 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     @Override242     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     @Override251     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     @Override272     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     @Override281     public double getMonthlyRent() {282         return monthlyRent;283     }284 285 }286 /*   类:输入格式判断InputDeal287  * 功能:判断输入格式是否正确,时间是否合理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 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 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     @Override601     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     @Override630     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     @Override653     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     @Override676     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     @Override706     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     @Override740     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 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() { 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 chargeRules = new ArrayList<>(); 65  66     public abstract double calCost(UserRecords userRecords); 67  68     public abstract double getMonthlyRent(); 69  70     public ArrayList getChargeRules() { 71         return chargeRules; 72     } 73  74     public void setChargeRules(ArrayList 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 callingInCityRecords = new ArrayList();133     private ArrayList callingInProvinceRecords = new ArrayList();134     private ArrayList callingInLandRecords = new ArrayList();135     private ArrayList answerInCityRecords = new ArrayList();136     private ArrayList answerInProvinceRecords = new ArrayList();137     private ArrayList answerInLandRecords = new ArrayList();138     private ArrayList sendMessageRecords = new ArrayList();139     private ArrayList receiveMessageRecords = new ArrayList();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 getCallingInCityRecords() {174         return callingInCityRecords;175     }176 177     public void setCallingInCityRecords(ArrayList callingInCityRecords) {178         this.callingInCityRecords = callingInCityRecords;179     }180 181     public ArrayList getCallingInProvinceRecords() {182         return callingInProvinceRecords;183     }184 185     public void setCallingInProvinceRecords(ArrayList callingInProvinceRecords) {186         this.callingInProvinceRecords = callingInProvinceRecords;187     }188 189     public ArrayList getCallingInLandRecords() {190         return callingInLandRecords;191     }192 193     public void setCallingInLandRecords(ArrayList callingInLandRecords) {194         this.callingInLandRecords = callingInLandRecords;195     }196 197     public ArrayList getAnswerInCityRecords() {198         return answerInCityRecords;199     }200 201     public void setAnswerInCityRecords(ArrayList answerInCityRecords) {202         this.answerInCityRecords = answerInCityRecords;203     }204 205     public ArrayList getAnswerInProvinceRecords() {206         return answerInProvinceRecords;207     }208 209     public void setAnswerInProvinceRecords(ArrayList answerInProvinceRecords) {210         this.answerInProvinceRecords = answerInProvinceRecords;211     }212 213     public ArrayList getAnswerInLandRecords() {214         return answerInLandRecords;215     }216 217     public void setAnswerInLandRecords(ArrayList answerInLandRecords) {218         this.answerInLandRecords = answerInLandRecords;219     }220 221     public ArrayList getSendMessageRecords() {222         return sendMessageRecords;223     }224 225     public void setSendMessageRecords(ArrayList sendMessageRecords) {226         this.sendMessageRecords = sendMessageRecords;227     }228 229     public ArrayList getReceiveMessageRecords() {230         return receiveMessageRecords;231     }232 233     public void setReceiveMessageRecords(ArrayList 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     @Override255     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     @Override264     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     @Override286     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     @Override295     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     @Override314     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     @Override323     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 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 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     @Override576     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     @Override37     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     @Override60     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库中已经建好了很多实现方法,可以直接拿来用,会方便很多。

关键词: 计费方式 结束时间 输入格式