BLOG-3

Java博客作业(三)

一、前言

<1>第六次大作业

题型总结:电信计费系列1-座机计费、多态测试。

涉及知识点:正则表达式的理解和应用、Java基本的语法和面向对象的一系列操作,对给出类图的阅读能力,父类和子类的关系以及对多态的理解。

题量:适中。

难度:适中。

 

<2>第七次大作业

题型总结: 电信计费系列2-手机+座机计费,sdut-Collection-sort--C~K的班级(II),阅读程序,按照题目需求修改程序。

涉及知识点:正则表达式的理解和应用、Java基本的语法和面向对象的一系列操作,阅读类图的能力,对动态数组的理解和其自带方法的使用。

题量:适中。

难度:适中。

 

<3>第八次大作业

题型总结:电信计费系列3-短信计费、编写一个类Shop(商店)、内部类InnerCoupons(内部购物券)、动物发声模拟器(多态)。

涉及知识点:Java基本的语法和面向对象的一系列操作,继承和多态、抽象方法、类的重构、ArrayList的使用、容器的使用。

题量:适中。

难度:适中。

 

二、设计与分析

1.算法设计以及思路

<1>第六次大作业第一题

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)。

 

 大概思路:

首先通过给出的类图去理解每个类的内容和类与类之间的关系,理解计算余额,计算消费的方法,比如座机收费模式,短信收费模式,手机收费模式,而在这些收费模式中可以包括一些计费方式比如市内计费方式,省内计费方式,省外计费方式,在用户记录类当中包括市内拨号记录,市内接听记录,短信发送记录,短信接收记录等等,最后根据类图在idea里逐步实现。

 

 

 代码:

复制代码
  1 package 电信计费1;
  2 
  3 
  4 import java.math.RoundingMode;
  5 import java.util.ArrayList;
  6 import java.util.Comparator;
  7 import java.util.Scanner;
  8 import java.util.regex.Matcher;
  9 import java.util.regex.Pattern;
 10 import java.math.BigDecimal;
 11 import java.text.SimpleDateFormat;
 12 import java.util.Date;
 13 import java.util.Locale;
 14 import java.text.ParseException;
 15 
 16 public class Main {
 17     public static Double output(Double data)
 18     {
 19         double a = data;
 20         BigDecimal bigDecimal = new BigDecimal(a);
 21         double res = bigDecimal.setScale(2, RoundingMode.HALF_UP).doubleValue();
 22         return res;
 23     }
 24     public static void main(String[] args) {
 25         Inputdeal inputdeal = new Inputdeal();
 26         ArrayList<User> users = new ArrayList<>();
 27         Scanner in = new Scanner(System.in);
 28         String input = in.nextLine();
 29         while (!input.equals("end")) {
 30             if (inputdeal.check(input) == 1) {
 31                 inputdeal.writeUser(users, input);
 32             } else if (inputdeal.check(input) == 2) {
 33                 inputdeal.writeRecord(users, input);
 34             }
 35             input = in.nextLine();
 36         }
 37         users.sort(new Comparator<User>() {
 38             @Override
 39             public int compare(User u1, User u2) {
 40                 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
 41                     return 1;
 42                 } else {
 43                     return -1;
 44                 }
 45             }
 46         });
 47         for (User u : users) {
 48             System.out.println(u.getNumber() + " "+output(u.calCost())+" "+u.calBalance());
 49         }
 50     }
 51 }
 52 
 53 abstract class ChargeMode {
 54     protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
 55     public abstract double calCost(UserRecords userRecords);
 56     public abstract double getMonthlyRent();
 57     public ArrayList<ChargeRule> getChargeRules() {
 58         return chargeRules;
 59     }
 60 }
 61 
 62 class UserRecords {
 63 
 64     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<>();
 65     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<>();
 66     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<>();
 67     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<>();
 68     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<>();
 69     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<>();
 70     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<>();
 71     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>();
 72 
 73     public void addCallingInCityRecords(CallRecord callRecord) {
 74         callingInCityRecords.add(callRecord);
 75     }
 76 
 77     public void addCallingInProvinceRecords(CallRecord callRecord) {
 78         callingInProvinceRecords.add(callRecord);
 79     }
 80     public void addCallingInLandRecords(CallRecord callRecord) {
 81         callingInLandRecords.add(callRecord);
 82     }
 83     public void addAnswerInCityRecords(CallRecord callRecord) {
 84         answerInCityRecords.add(callRecord);
 85     }
 86     public void addAnswerInProvinceRecords(CallRecord callRecord) {
 87         answerInProvinceRecords.add(callRecord);
 88     }
 89     public void addAnswerInLandRecords(CallRecord callRecord) {
 90         answerInLandRecords.add(callRecord);
 91     }
 92     public ArrayList<CallRecord> getCallingInCityRecords() {
 93         return callingInCityRecords;
 94     }
 95 
 96     public ArrayList<CallRecord> getCallingInProvinceRecords() {
 97         return callingInProvinceRecords;
 98     }
 99     public ArrayList<CallRecord> getCallingInLandRecords() {
100         return callingInLandRecords;
101     }
102 }
103 
104 class LandlinePhoneCharging extends ChargeMode {
105     private double monthlyRent = 20;
106     public LandlinePhoneCharging() {
107         super();
108         chargeRules.add(new LandPhoneInCityRule());
109         chargeRules.add(new LandPhoneInProvinceRule());
110         chargeRules.add(new LandPhoneInlandRule());
111     }
112 
113     @Override
114     public double calCost(UserRecords userRecords) {
115         double sumCost = 0;
116         for (ChargeRule rule : chargeRules) {
117             sumCost += rule.calCost(userRecords);
118         }
119         return sumCost;
120     }
121 
122     @Override
123     public double getMonthlyRent() {
124         return monthlyRent;
125     }
126 
127 }
128 
129 class Inputdeal {
130 
131     public int check(String input) {
132         String[] inputs = input.split(" ");
133         if (inputs.length == 2) {
134             if (inputs[0].matches("^u-[0-9]{11,13}$")) {
135                 if (Integer.parseInt(inputs[1]) >= 0) {
136                     if (Integer.parseInt(inputs[1]) <= 2) {
137                         return 1;
138                     }
139                 }
140             }
141         } else if (inputs.length == 6) {
142             if (validate(inputs[2]))
143                 if (validate(inputs[4]))
144                     if (validatet(inputs[3]))
145                         if (validatet(inputs[5]))
146 //                    if (inputs[0].matches("^t\\-[0-9]{10,12}$")) {
147                             if (inputs[0].matches("[t]-0791[0-9]{7,8}")) {
148                                 if (inputs[1].matches(".[0-9]{9,11}"))
149                                     return 2;
150                             }
151         }
152         return 0;
153     }
154     private boolean validatet(String string) {
155         String[] split = string.split(":");
156         if (!string.matches("^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$")) {
157             return false;
158         }
159         return true;
160     }
161     public static boolean validate(String dateString) {
162         // 使用正则表达式 测试 字符 符合 dddd.dd.dd 的格式(d表示数字)
163         Pattern p = Pattern.compile("\\d{4}+[\\.]\\d{1,2}+[\\.]\\d{1,2}+");
164         Matcher m = p.matcher(dateString);
165         if (!m.matches()) {
166             return false;
167         }
168 
169         // 得到年月日
170         String[] array = dateString.split("\\.");
171         int year = Integer.parseInt(array[0]);
172         int month = Integer.parseInt(array[1]);
173         int day = Integer.parseInt(array[2]);
174         if (month < 1 || month > 12) {
175             return false;
176         }
177         int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
178         if (isLeapYear(year)) {
179             monthLengths[2] = 29;
180         } else {
181             monthLengths[2] = 28;
182         }
183         int monthLength = monthLengths[month];
184         if (day < 1 || day > monthLength) {
185             return false;
186         }
187         return true;
188     }
189 
190     /** 是否是闰年 */
191     private static boolean isLeapYear(int year) {
192         return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
193     }
194 
195     public boolean judge(String input) {
196 
197         return false;
198     }
199 
200     /** 是否是闰年 */
201 
202     public void writeUser(ArrayList<User> users, String input) {
203         User newuser = new User();
204         String[] inputs = input.split(" ");
205         String num = inputs[0].substring(2);
206         for (User i : users) {
207             if (i.getNumber().equals(num)) {
208                 return;
209             }
210         }
211         newuser.setNumber(num);
212         int mode = Integer.parseInt(inputs[1]);
213         if (mode == 0) {
214             newuser.setChargeMode(new LandlinePhoneCharging());
215         }
216         users.add(newuser);
217     }
218 
219     public void writeRecord(ArrayList<User> users, String input) {
220         String[] inputs = input.split(" ");
221         inputs[0] = inputs[0].replace("t-", "");
222 
223         User callu = null, answeru = null;
224         CallRecord callrecord = new CallRecord(inputs);
225 
226         for (User i : users) {
227             if (i.getNumber().equals(inputs[0])) {
228                 callu = i;
229             }
230             if (i.getNumber().equals(inputs[1])) {
231                 answeru = i;
232             }
233             if (callu != null && answeru != null) {
234                 break;
235             }
236         }
237 
238         if (callu != null) {
239             if (callrecord.getCallType() == 1) {
240                 callu.getUserRecords().addCallingInCityRecords(callrecord);
241             } else if (callrecord.getCallType() == 2) {
242                 callu.getUserRecords().addCallingInProvinceRecords(callrecord);
243             } else {
244                 callu.getUserRecords().addCallingInLandRecords(callrecord);
245             }
246         }
247 
248         if (answeru != null) {
249             if (callrecord.getCallType() == 1) {
250                 answeru.getUserRecords().addAnswerInCityRecords(callrecord);
251             } else if (callrecord.getCallType() == 2) {
252                 answeru.getUserRecords().addAnswerInProvinceRecords(callrecord);
253             } else {
254                 answeru.getUserRecords().addAnswerInLandRecords(callrecord);
255             }
256         }
257 
258     }
259 
260 }
261 
262 abstract class CommunicationRecord {
263     protected String callingNumber;
264     protected String answerNumber;
265     public String getCallingNumber() {
266         return callingNumber;
267     }
268     public void setCallingNumber(String callingNumber) {
269         this.callingNumber = callingNumber;
270     }
271     public String getAnswerNumber() {
272         return answerNumber;
273     }
274     public void setAnswerNumber(String answerNumber) {
275         this.answerNumber = answerNumber;
276     }
277 }
278 
279 abstract class ChargeRule {
280     abstract public double calCost(UserRecords userRecords);
281 }
282 
283 class CallRecord extends CommunicationRecord {
284     private Date startTime;
285     private Date endTime;
286     private String callingAddressAreaCode;
287     private String answerAddressAreaCode;
288 
289     public int getCallType() {
290         if (callingAddressAreaCode.equals(answerAddressAreaCode)) {
291             return 1;
292         }
293         if (callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701")) {
294             if (answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701")) {
295                 return 2;
296             }
297         }
298         return 3;
299     }
300 
301     public CallRecord(String[] inputs) {
302         super();
303         if (inputs[0].length() == 10) {
304             callingAddressAreaCode = inputs[0].substring(0, 3);
305         } else {
306             callingAddressAreaCode = inputs[0].substring(0, 4);
307         }
308         if (inputs[1].length() == 10) {
309             answerAddressAreaCode = inputs[1].substring(0, 3);
310         } else {
311             answerAddressAreaCode = inputs[1].substring(0, 4);
312         }
313         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
314         try {
315             startTime = simpleDateFormat.parse(inputs[2] + " " + inputs[3]);
316             endTime = simpleDateFormat.parse(inputs[4] + " " + inputs[5]);
317         } catch (ParseException e) {
318         }
319     }
320     public Date getStartTime() {
321         return startTime;
322     }
323     public void setStartTime(Date startTime) {
324         this.startTime = startTime;
325     }
326     public Date getEndTime() {
327         return endTime;
328     }
329     public void setEndTime(Date endTime) {
330         this.endTime = endTime;
331     }
332 
333     public String getCallingAddressAreaCode() {
334         return callingAddressAreaCode;
335     }
336     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
337         this.callingAddressAreaCode = callingAddressAreaCode;
338     }
339     public String getAnswerAddressAreaCode() {
340         return answerAddressAreaCode;
341     }
342     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
343         this.answerAddressAreaCode = answerAddressAreaCode;
344     }
345 }
346 abstract class CallChargeRule extends ChargeRule {
347 
348 }
349 
350 class LandPhoneInCityRule extends CallChargeRule {
351 
352     @Override
353     public double calCost(UserRecords userRecords) {
354         double sumCost = 0;
355         for (CallRecord call : userRecords.getCallingInCityRecords()) {
356             double distanceS = (call.getEndTime().getTime()-call.getStartTime().getTime()) / 1000;
357             if (distanceS < 0) {
358                 continue;
359             }
360             double distanceM = (int) distanceS / 60;
361             if (distanceS % 60 != 0) {
362                 distanceM += 1;
363             }
364             sumCost += distanceM * 0.1;
365         }
366         return sumCost;
367     }
368 
369 }
370 
371 class LandPhoneInlandRule extends CallChargeRule {
372 
373     @Override
374     public double calCost(UserRecords userRecords) {
375         double sumCost = 0;
376         for (CallRecord call : userRecords.getCallingInLandRecords()) {
377             double distanceS = (call.getEndTime().getTime()-call.getStartTime().getTime()) / 1000;
378             if (distanceS < 0) {
379                 continue;
380             }
381             double distanceM = (int) distanceS / 60;
382             if (distanceS % 60 != 0) {
383                 distanceM += 1;
384             }
385             sumCost += distanceM * 0.6;
386         }
387         return sumCost;
388     }
389 
390 }
391 
392 class LandPhoneInProvinceRule extends CallChargeRule {
393 
394     @Override
395     public double calCost(UserRecords userRecords) {
396         double sumCost = 0;
397         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
398             double distanceS = (call.getEndTime().getTime()-call.getStartTime().getTime()) / 1000;
399             if (distanceS < 0) {
400                 continue;
401             }
402             double distanceM = (int) distanceS / 60;
403             if (distanceS % 60 != 0) {
404                 distanceM += 1;
405             }
406             sumCost += distanceM * 0.3;
407         }
408         return sumCost;
409     }
410 
411 }
412 
413 class MessageRecord extends CommunicationRecord {
414 
415     private String message;
416 
417     public String getMessage() {
418         return message;
419     }
420 
421     public void setMessage(String message) {
422         this.message = message;
423     }
424 }
425 
426 class User {
427 
428     private UserRecords userRecords = new UserRecords();
429     private double balance = 100;
430     private ChargeMode chargeMode;
431     private String number;
432 
433     public double calCost() {
434         return chargeMode.calCost(userRecords);
435     }
436     public double calBalance() {
437         return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
438     }
439 
440     public UserRecords getUserRecords() {
441         return userRecords;
442     }
443 
444     public void setUserRecords(UserRecords userRecords) {
445         this.userRecords = userRecords;
446     }
447 
448     public ChargeMode getChargeMode() {
449         return chargeMode;
450     }
451 
452     public void setChargeMode(ChargeMode chargeMode) {
453         this.chargeMode = chargeMode;
454     }
455 
456     public String getNumber() {
457         return number;
458     }
459     public void setNumber(String number) {
460         this.number = number;
461     }
462 }
View Code
复制代码

 

<2>第七次大作业第一题

7-1 电信计费系列2-手机+座机计费

实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
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元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。

本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。
 

建议类图:
参见图1、2、3:

image.png
图1

1User是用户类,包括属性:
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的约束条件:必须是某一个用户的符合计费规则要求的所有记录。
SendMessageRule是发送短信的计费规则类,用于计算发送短信的费用。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。

大概思路:

 本次在第一次座机计费的基础上添加了手机用户的计费方式,在手机用户的计费方式中添加了漫游的计费方式,漫游指的是在南昌市的用户,在外地拨打电话或者接听电话等,在处理这种的通讯机录主要是区号,根据区号来判断位置,其他的与座机的收费模式类似,对第一次座机计费的代码进行相应的添加和修改。

 

 

复制代码
  1 package 电信计费2;
  2 
  3 import java.util.Scanner;
  4 import java.util.ArrayList;
  5 import java.util.Comparator;
  6 import java.util.Date;
  7 import java.util.Locale;
  8 import java.text.ParseException;
  9 import java.util.regex.Matcher;
 10 import java.util.regex.Pattern;
 11 import java.math.BigDecimal;
 12 import java.text.SimpleDateFormat;
 13 
 14 
 15 public class Main {
 16 
 17     public static void main(String[] args) {
 18 
 19         Output output = new Output();
 20 
 21         Inputdeal inputdeal = new Inputdeal();
 22 
 23         ArrayList<User> users = new ArrayList<>();
 24 
 25         Scanner in = new Scanner(System.in);
 26 
 27         String input = in.nextLine();
 28 
 29         while (!input.equals("end")) {
 30             if (1 == inputdeal.check(input)) {
 31                 inputdeal.writeUser(users, input);
 32             } else if (2 == inputdeal.check(input)) {
 33                 inputdeal.writeRecord(users, input);
 34             }
 35             input = in.nextLine();
 36         }
 37 
 38         users.sort(new Comparator<User>() {
 39 
 40             @Override
 41             public int compare(User u1, User u2) {
 42                 if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') {
 43                     return -1;
 44                 } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') {
 45                     return 1;
 46                 }
 47                 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
 48                     return 1;
 49                 } else {
 50                     return -1;
 51                 }
 52             }
 53         });
 54 
 55         for (User u : users) {
 56             System.out.print(u.getNumber() + " ");
 57             output.output(u.calCost());
 58             System.out.print(" ");
 59             output.output(u.calBalance());
 60             System.out.println();
 61 
 62         }
 63 
 64     }
 65 
 66 }
 67 class Output {
 68 
 69     @SuppressWarnings("deprecation")
 70     public void output(double out) {
 71         BigDecimal numb = new BigDecimal(out);
 72         out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
 73         System.out.print(out);
 74     }
 75 }
 76 
 77 abstract class ChargeMode {
 78     protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
 79 
 80     public abstract double calCost(UserRecords userRecords);
 81 
 82     public abstract double getMonthlyRent();
 83 
 84 }
 85 
 86 class UserRecords {
 87 
 88     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<>();
 89     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<>();
 90     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<>();
 91     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<>();
 92     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<>();
 93     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<>();
 94     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<>();
 95     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>();
 96 
 97     public void addCallingInCityRecords(CallRecord callRecord) {
 98         callingInCityRecords.add(callRecord);
 99     }
100 
101     public void addCallingInProvinceRecords(CallRecord callRecord) {
102         callingInProvinceRecords.add(callRecord);
103     }
104 
105     public void addCallingInLandRecords(CallRecord callRecord) {
106         callingInLandRecords.add(callRecord);
107     }
108 
109     public void addAnswerInCityRecords(CallRecord callRecord) {
110         answerInCityRecords.add(callRecord);
111     }
112 
113     public void aaddAnswerInProvinceRecords(CallRecord callRecord) {
114         answerInProvinceRecords.add(callRecord);
115     }
116 
117     public void addAnswerInLandRecords(CallRecord callRecord) {
118         answerInLandRecords.add(callRecord);
119     }
120 
121 
122     public ArrayList<CallRecord> getCallingInCityRecords() {
123         return callingInCityRecords;
124     }
125 
126 
127     public ArrayList<CallRecord> getCallingInProvinceRecords() {
128         return callingInProvinceRecords;
129     }
130 
131 
132     public ArrayList<CallRecord> getCallingInLandRecords() {
133         return callingInLandRecords;
134     }
135 
136 
137     public ArrayList<CallRecord> getAnswerInLandRecords() {
138         return answerInLandRecords;
139     }
140 
141 
142 }
143 
144 class LandlinePhoneCharging extends ChargeMode {
145 
146     private final double monthlyRent = 20;
147 
148     public LandlinePhoneCharging() {
149         super();
150         chargeRules.add(new LandPhoneInCityRule());
151         chargeRules.add(new LandPhoneInProvinceRule());
152         chargeRules.add(new LandPhoneInlandRule());
153     }
154 
155     @Override
156     public double calCost(UserRecords userRecords) {
157         double sumCost = 0;
158         for (ChargeRule rule : chargeRules) {
159             sumCost += rule.calCost(userRecords);
160         }
161         return sumCost;
162     }
163 
164     @Override
165     public double getMonthlyRent() {
166         return monthlyRent;
167     }
168 
169 }
170 
171 class MobilePhoneCharging extends ChargeMode {
172 
173     private final double monthlyRent = 15;
174 
175     public MobilePhoneCharging() {
176         super();
177         chargeRules.add(new MobilePhoneInCityRule());
178         chargeRules.add(new MobilePhoneInProvinceRule());
179         chargeRules.add(new MobilePhoneInlandRule());
180     }
181 
182     @Override
183     public double calCost(UserRecords userRecords) {
184         double sumCost = 0;
185         for (ChargeRule rule : chargeRules) {
186             sumCost += rule.calCost(userRecords);
187         }
188         return sumCost;
189     }
190 
191     @Override
192     public double getMonthlyRent() {
193         return monthlyRent;
194     }
195 
196 }
197 
198 class Inputdeal {
199 
200     public int check(String input) {
201         if (input.matches("[u]-0791[0-9]{7,8}\\s[0]") || input.matches("[u]-1[0-9]{10}\\s[1]")) {
202             return 1;
203         } else if (input.matches("(([t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s)|"
204                 + "([t]-0791[0-9]{7,8}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s)|"
205                 + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "0[0-9]{9,11}\\s)|"
206                 + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s))"
207 
208                 + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?"
209                 + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((("
210                 + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"
211                 + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s"
212                 + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.("
213                 + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((("
214                 + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"
215                 + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])")) {
216             return 2;
217         }
218         return 0;
219     }
220 
221     @SuppressWarnings("unused")
222     private boolean validatet(String string) {
223         if (!string.matches("^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$")) {
224             return false;
225         }
226         return true;
227     }
228 
229     public static boolean validate(String dateString) {
230         // 使用正则表达式 测试 字符 符合 dddd.dd.dd 的格式(d表示数字)
231         Pattern p = Pattern.compile("\\d{4}+[\\.]\\d{1,2}+[\\.]\\d{1,2}+");
232         Matcher m = p.matcher(dateString);
233         if (!m.matches()) {
234             return false;
235         }
236 
237         // 得到年月日
238         String[] array = dateString.split("\\.");
239         int year = Integer.valueOf(array[0]);
240         int month = Integer.valueOf(array[1]);
241         int day = Integer.valueOf(array[2]);
242 
243         if (month < 1 || month > 12) {
244             return false;
245         }
246         int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
247         if (isLeapYear(year)) {
248             monthLengths[2] = 29;
249         } else {
250             monthLengths[2] = 28;
251         }
252         int monthLength = monthLengths[month];
253         if (day < 1 || day > monthLength) {
254             return false;
255         }
256         return true;
257     }
258 
259     /** 是否是闰年 */
260     private static boolean isLeapYear(int year) {
261         return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
262     }
263 
264     public boolean judge(String input) {
265 
266         return false;
267     }
268 
269     public void writeUser(ArrayList<User> users, String input) {
270         User usernew = new User();
271         String[] inputs = input.split(" ");
272         String num = inputs[0].substring(2);
273         for (User i : users) {
274             if (i.getNumber().equals(num)) {
275                 return;
276             }
277         }
278         usernew.setNumber(num);
279         int mode = Integer.parseInt(inputs[1]);
280         if (mode == 0) {
281             usernew.setChargeMode(new LandlinePhoneCharging());
282         } else if (mode == 1) {
283             usernew.setChargeMode(new MobilePhoneCharging());
284         }
285         users.add(usernew);
286     }
287 
288     public void writeRecord(ArrayList<User> users, String input) {
289         String[] inputs = input.split(" ");
290 
291         User callu = null, answeru = null;
292         CallRecord callrecord = new CallRecord(inputs);
293 
294         if (input.charAt(0) == 't') {
295             String out = inputs[0];
296             String in = "";
297             if (inputs.length == 6) {
298                 in = inputs[1];
299             } else if (inputs.length == 7) {
300                 in = inputs[1];
301             } else if (inputs.length == 8) {
302                 in = inputs[2];
303             }
304 
305             for (User i : users) {
306                 if (i.getNumber().equals(out)) {
307                     callu = i;
308                 }
309                 if (i.getNumber().equals(in)) {
310                     answeru = i;
311                 }
312                 if (callu != null && answeru != null) {
313                     break;
314                 }
315             }
316 
317             if (callu != null) {
318                 if (callrecord.getCallType().matches("^1[1-3]$")) {
319                     callu.getUserRecords().addCallingInCityRecords(callrecord);
320                 } else if (callrecord.getCallType().matches("^2[1-3]$")) {
321                     callu.getUserRecords().addCallingInProvinceRecords(callrecord);
322                 } else {
323                     callu.getUserRecords().addCallingInLandRecords(callrecord);
324                 }
325             }
326 
327             if (answeru != null) {
328                 if (callrecord.getCallType().matches("^[1-3]1$")) {
329                     answeru.getUserRecords().addAnswerInCityRecords(callrecord);
330                 } else if (callrecord.getCallType().matches("^[1-3]2$")) {
331                     answeru.getUserRecords().aaddAnswerInProvinceRecords(callrecord);
332                 } else {
333                     answeru.getUserRecords().addAnswerInLandRecords(callrecord);
334                 }
335             }
336         } else if (input.charAt(0) == 'm') {
337 
338         }
339 
340     }
341 
342 }
343 
344 abstract class CommunicationRecord {
345     protected String callingNumber;
346     protected String answerNumbe;
347 
348 }
349 
350 abstract class ChargeRule {
351 
352     abstract public double calCost(UserRecords userRecords);
353 
354 }
355 
356 class CallRecord extends CommunicationRecord {
357     private Date startTime;
358     private Date endTime;
359     private String callingAddressAreaCode;
360     private String answerAddressAreaCode;
361 
362     public String getCallType() {
363         String type = "";
364         if (callingAddressAreaCode.equals("0791")) {
365             type = type.concat("1");
366         } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) {
367             type = type.concat("2");
368         } else {
369             type = type.concat("3");
370         }
371 
372         if (answerAddressAreaCode.equals("0791")) {
373             type = type.concat("1");
374         } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) {
375             type = type.concat("2");
376         } else {
377             type = type.concat("3");
378         }
379 
380         return type;
381     }
382 
383     public CallRecord(String[] inputs) {
384         super();
385 
386         char type = inputs[0].charAt(0);
387         inputs[0] = inputs[0].substring(2);
388 
389         String sd = null, st = null, ed = null, et = null;
390 
391         if (type == 't') {
392             if (inputs.length == 6) {
393                 sd = inputs[2];
394                 st = inputs[3];
395                 ed = inputs[4];
396                 et = inputs[5];
397                 callingAddressAreaCode = inputs[0].substring(0, 4);
398                 answerAddressAreaCode = inputs[1].substring(0, 4);
399             } else if (inputs.length == 7) {
400                 sd = inputs[3];
401                 st = inputs[4];
402                 ed = inputs[5];
403                 et = inputs[6];
404                 if (inputs[0].charAt(0) != '0') {
405                     if (inputs[2].length() == 10) {
406                         answerAddressAreaCode = inputs[2].substring(0, 3);
407                     } else {
408                         answerAddressAreaCode = inputs[2].substring(0, 4);
409                     }
410                     callingAddressAreaCode = inputs[1];
411                 } else {
412                     if (inputs[0].length() == 10) {
413                         callingAddressAreaCode = inputs[0].substring(0, 3);
414                     } else {
415                         callingAddressAreaCode = inputs[0].substring(0, 4);
416                     }
417                     answerAddressAreaCode = inputs[2];
418                 }
419             } else if (inputs.length == 8) {
420                 sd = inputs[4];
421                 st = inputs[5];
422                 ed = inputs[6];
423                 et = inputs[7];
424                 callingAddressAreaCode = inputs[1];
425                 answerAddressAreaCode = inputs[3];
426             }
427         } else if (type == 'm') {
428 
429         }
430         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
431         try {
432             startTime = simpleDateFormat.parse(sd + " " + st);
433             endTime = simpleDateFormat.parse(ed + " " + et);
434         } catch (ParseException e) {
435         }
436 
437     }
438 
439     public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
440         super();
441         this.startTime = startTime;
442         this.endTime = endTime;
443         this.callingAddressAreaCode = callingAddressAreaCode;
444         this.answerAddressAreaCode = answerAddressAreaCode;
445     }
446 
447     public Date getStartTime() {
448         return startTime;
449     }
450 
451 
452 
453     public Date getEndTime() {
454         return endTime;
455     }
456 
457 }
458 
459 abstract class CallChargeRule extends ChargeRule {
460 
461 }
462 
463 class LandPhoneInCityRule extends CallChargeRule {
464 
465     @Override
466     public double calCost(UserRecords userRecords) {
467         double sumCost = 0;
468         for (CallRecord call : userRecords.getCallingInCityRecords()) {
469             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
470             if (distanceS < 0) {
471                 continue;
472             }
473             double distanceM = (int) distanceS / 60;
474             if (distanceS % 60 != 0) {
475                 distanceM += 1;
476             }
477             if (call.getCallType().equals("11")) {
478                 sumCost += distanceM * 0.1;
479             } else if (call.getCallType().equals("12")) {
480                 sumCost += distanceM * 0.3;
481             } else if (call.getCallType().equals("13")) {
482                 sumCost += distanceM * 0.6;
483             }
484         }
485         return sumCost;
486     }
487 
488 }
489 
490 class LandPhoneInlandRule extends CallChargeRule {
491 
492     @Override
493     public double calCost(UserRecords userRecords) {
494         double sumCost = 0;
495         for (CallRecord call : userRecords.getCallingInLandRecords()) {
496             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
497             if (distanceS < 0) {
498                 continue;
499             }
500             double distanceM = (int) distanceS / 60;
501             if (distanceS % 60 != 0) {
502                 distanceM += 1;
503             }
504             sumCost += distanceM * 0.6;
505         }
506         return sumCost;
507     }
508 
509 }
510 
511 class LandPhoneInProvinceRule extends CallChargeRule {
512 
513     @Override
514     public double calCost(UserRecords userRecords) {
515         double sumCost = 0;
516         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
517             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
518             if (distanceS < 0) {
519                 continue;
520             }
521             double distanceM = (int) distanceS / 60;
522             if (distanceS % 60 != 0) {
523                 distanceM += 1;
524             }
525             sumCost += distanceM * 0.3;
526         }
527         return sumCost;
528     }
529 
530 }
531 
532 class MobilePhoneInCityRule extends CallChargeRule {
533 
534     @Override
535     public double calCost(UserRecords userRecords) {
536         double sumCost = 0;
537         for (CallRecord call : userRecords.getCallingInCityRecords()) {
538             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
539             if (distanceS < 0) {
540                 continue;
541             }
542             double distanceM = (int) distanceS / 60;
543             if (distanceS % 60 != 0) {
544                 distanceM += 1;
545             }
546             if (call.getCallType().equals("11")) {
547                 sumCost += distanceM * 0.1;
548             } else if (call.getCallType().equals("12")) {
549                 sumCost += distanceM * 0.2;
550             } else if (call.getCallType().equals("13")) {
551                 sumCost += distanceM * 0.3;
552             }
553 
554         }
555         return sumCost;
556     }
557 
558 }
559 
560 class MobilePhoneInlandRule extends CallChargeRule {
561 
562     @Override
563     public double calCost(UserRecords userRecords) {
564         double sumCost = 0;
565         for (CallRecord call : userRecords.getCallingInLandRecords()) {
566             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
567             if (distanceS < 0) {
568                 continue;
569             }
570             double distanceM = (int) distanceS / 60;
571             if (distanceS % 60 != 0) {
572                 distanceM += 1;
573             }
574             sumCost += distanceM * 0.6;
575         }
576         for (CallRecord call : userRecords.getAnswerInLandRecords()) {
577             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
578             if (distanceS < 0) {
579                 continue;
580             }
581             double distanceM = (int) distanceS / 60;
582             if (distanceS % 60 != 0) {
583                 distanceM += 1;
584             }
585             sumCost += distanceM * 0.3;
586         }
587         return sumCost;
588     }
589 
590 }
591 
592 class MobilePhoneInProvinceRule extends CallChargeRule {
593 
594     @Override
595     public double calCost(UserRecords userRecords) {
596         double sumCost = 0;
597         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
598             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
599             if (distanceS < 0) {
600                 continue;
601             }
602             double distanceM = (int) distanceS / 60;
603             if (distanceS % 60 != 0) {
604                 distanceM += 1;
605             }
606             if (call.getCallType().equals("21")) {
607                 sumCost += distanceM * 0.3;
608             } else if (call.getCallType().equals("22")) {
609                 sumCost += distanceM * 0.3;
610             } else if (call.getCallType().equals("23")) {
611                 sumCost += distanceM * 0.3;
612             }
613         }
614         return sumCost;
615     }
616 
617 }
618 
619 class MessageRecord extends CommunicationRecord {
620 
621     private String message;
622 
623 }
624 
625 class User {
626 
627     private UserRecords userRecords = new UserRecords();
628     private double balance = 100;
629     private ChargeMode chargeMode;
630     private String number;
631 
632     public double calCost() {
633         return chargeMode.calCost(userRecords);
634     }
635 
636     public double calBalance() {
637         return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
638     }
639 
640     public UserRecords getUserRecords() {
641         return userRecords;
642     }
643 
644 
645     public void setChargeMode(ChargeMode chargeMode) {
646         this.chargeMode = chargeMode;
647     }
648 
649     public String getNumber() {
650         return number;
651     }
652 
653     public void setNumber(String number) {
654         this.number = number;
655     }
656 
657 }
View Code
复制代码

 

<3>第八次大作业第一题

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”结束。
输出:
根据输入的详细短信信息,计算所有已开户的用户的当月短信费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码、自己给自己打电话等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。

本题只考虑短信计费,不考虑通信费用以及月租费。

建议类图:
参见图1、2、3:

image.png

图1

1User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。
ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。    
UserRecords是用户记录类,保存用户各种通话、短信的记录,    
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。
 

image.png

图2

    图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。
 

image.png

图3
图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。
SendMessageRule是发送短信的计费规则类,用于计算发送短信的费用。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。

大概思路:

本系列中添加短信计费模式较简单,在上次的基础上容易实现。

 

 

 

复制代码
  1 package 电信计费3;
  2 
  3 import java.math.RoundingMode;
  4 import java.util.Scanner;
  5 import java.util.ArrayList;
  6 import java.util.Comparator;
  7 import java.util.Date;
  8 import java.math.BigDecimal;
  9 import java.text.SimpleDateFormat;
 10 import java.text.ParseException;
 11 import java.util.Locale;
 12 
 13 public class Main {
 14 
 15     public static void main(String[] args) {
 16 
 17         Output output = new Output();
 18 
 19         Inputdeal inputdeal = new Inputdeal();
 20 
 21         ArrayList<User> users = new ArrayList<>();
 22 
 23         Scanner in = new Scanner(System.in);
 24 
 25         String input = in.nextLine();
 26 
 27         while (!input.equals("end")) {
 28             if (1 == inputdeal.check(input)) {
 29                 inputdeal.writeUser(users, input);
 30             } else if (2 == inputdeal.check(input)) {
 31                 inputdeal.writeRecord(users, input);
 32             }
 33             input = in.nextLine();
 34         }
 35 
 36         users.sort((u1, 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         for (User u : users) {
 50             System.out.print(u.getNumber() + " ");
 51             output.output(u.calCost());
 52             System.out.print(" ");
 53             output.output(u.calBalance());
 54             System.out.println();
 55 
 56         }
 57 
 58     }
 59 
 60 }
 61 class Output {
 62     public void output(double out) {
 63         BigDecimal numb = new BigDecimal(out);
 64         out = numb.setScale(2, RoundingMode.HALF_UP).doubleValue();
 65         System.out.print(out);
 66     }
 67 }
 68 abstract class ChargeMode {
 69     protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
 70 
 71     public abstract double calCost(UserRecords userRecords);
 72 
 73     public abstract double getMonthlyRent();
 74 
 75 
 76 }
 77 
 78 class UserRecords {
 79 
 80     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
 81     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
 82     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
 83     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
 84     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
 85     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
 86     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
 87     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
 88 
 89     public void addCallingInCityRecords(CallRecord callRecord) {
 90         callingInCityRecords.add(callRecord);
 91     }
 92 
 93     public void addCallingInProvinceRecords(CallRecord callRecord) {
 94         callingInProvinceRecords.add(callRecord);
 95     }
 96 
 97     public void addCallingInLandRecords(CallRecord callRecord) {
 98         callingInLandRecords.add(callRecord);
 99     }
100 
101     public void addAnswerInCityRecords(CallRecord callRecord) {
102         answerInCityRecords.add(callRecord);
103     }
104 
105 
106 
107     public void addSendMessageRecords(MessageRecord callRecord) {
108         sendMessageRecords.add(callRecord);
109     }
110 
111     public void addReceiveMessageRecords(MessageRecord callRecord) {
112         receiveMessageRecords.add(callRecord);
113     }
114 
115     public ArrayList<CallRecord> getCallingInCityRecords() {
116         return callingInCityRecords;
117     }
118 
119     public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
120         this.callingInCityRecords = callingInCityRecords;
121     }
122 
123     public ArrayList<CallRecord> getCallingInProvinceRecords() {
124         return callingInProvinceRecords;
125     }
126 
127 
128 
129     public ArrayList<CallRecord> getCallingInLandRecords() {
130         return callingInLandRecords;
131     }
132 
133 
134 
135 
136 
137     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
138         return answerInProvinceRecords;
139     }
140 
141     public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
142         this.answerInProvinceRecords = answerInProvinceRecords;
143     }
144 
145     public ArrayList<CallRecord> getAnswerInLandRecords() {
146         return answerInLandRecords;
147     }
148 
149     public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
150         this.answerInLandRecords = answerInLandRecords;
151     }
152 
153     public ArrayList<MessageRecord> getSendMessageRecords() {
154         return sendMessageRecords;
155     }
156 
157     public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
158         this.sendMessageRecords = sendMessageRecords;
159     }
160 
161     public ArrayList<MessageRecord> getReceiveMessageRecords() {
162         return receiveMessageRecords;
163     }
164 
165     public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
166         this.receiveMessageRecords = receiveMessageRecords;
167     }
168 
169 }
170 
171 class LandlinePhoneCharging extends ChargeMode {
172 
173     private final double monthlyRent = 20;
174 
175     public LandlinePhoneCharging() {
176         super();
177         chargeRules.add(new LandPhoneInCityRule());
178         chargeRules.add(new LandPhoneInProvinceRule());
179         chargeRules.add(new LandPhoneInlandRule());
180     }
181 
182     @Override
183     public double calCost(UserRecords userRecords) {
184         double sumCost = 0;
185         for (ChargeRule rule : chargeRules) {
186             sumCost += rule.calCost(userRecords);
187         }
188         return sumCost;
189     }
190 
191     @Override
192     public double getMonthlyRent() {
193         return monthlyRent;
194     }
195 
196 }
197 
198 class MobilePhoneCharging extends ChargeMode {
199 
200     private final double monthlyRent = 15;
201 
202     public MobilePhoneCharging() {
203         super();
204         chargeRules.add(new MobilePhoneInCityRule());
205         chargeRules.add(new MobilePhoneInProvinceRule());
206         chargeRules.add(new MobilePhoneInlandRule());
207     }
208 
209     @Override
210     public double calCost(UserRecords userRecords) {
211         double sumCost = 0;
212         for (ChargeRule rule : chargeRules) {
213             sumCost += rule.calCost(userRecords);
214         }
215         return sumCost;
216     }
217 
218     @Override
219     public double getMonthlyRent() {
220         return monthlyRent;
221     }
222 
223 }
224 
225 class MobilePhoneMassageCharging extends ChargeMode {
226 
227     private final double monthlyRent = 0;
228 
229     public MobilePhoneMassageCharging() {
230         super();
231         chargeRules.add(new MobilePhoneMessageRule());
232     }
233 
234     @Override
235     public double calCost(UserRecords userRecords) {
236         double sumCost = 0;
237         for (ChargeRule rule : chargeRules) {
238             sumCost += rule.calCost(userRecords);
239         }
240         return sumCost;
241     }
242 
243     @Override
244     public double getMonthlyRent() {
245         return monthlyRent;
246     }
247 
248 }
249 
250 class Inputdeal {
251 
252     public int check(String input) {
253         if (input.matches("[u]-0791[0-9]{7,8}\\s[0]") || input.matches("[u]-1[0-9]{10}\\s[13]")) {
254             return 1;
255         } else if (input.matches("[m]-1[0-9]{10}\\s" + "1[0-9]{10}\\s" + "[0-9a-zA-Z\\s\\.,]+")) {
256             return 2;
257         }
258         return 0;
259     }
260 
261     public void writeUser(ArrayList<User> users, String input) {
262         User usernew = new User();
263         String[] inputs = input.split(" ");
264         String num = inputs[0].substring(2);
265         for (User i : users) {
266             if (i.getNumber().equals(num)) {
267                 return;
268             }
269         }
270         usernew.setNumber(num);
271         int mode = Integer.parseInt(inputs[1]);
272         if (mode == 0) {
273             usernew.setChargeMode(new LandlinePhoneCharging());
274         } else if (mode == 1) {
275             usernew.setChargeMode(new MobilePhoneCharging());
276         } else if (mode == 3) {
277             usernew.setChargeMode(new MobilePhoneMassageCharging());
278         }
279         users.add(usernew);
280     }
281 
282     public void writeRecord(ArrayList<User> users, String input) {
283         String[] inputs = input.split(" ");
284         inputs[0] = inputs[0].substring(2);
285 
286         User callu = null, answeru = null;
287 
288         String out = inputs[0];
289         String in = "";
290         if (inputs.length == 6) {
291             in = inputs[1];
292         } else if (inputs.length == 7) {
293             in = inputs[1];
294         } else if (inputs.length == 8) {
295             in = inputs[2];
296         } else {
297             in = inputs[1];
298         }
299 
300         for (User i : users) {
301             if (i.getNumber().equals(out)) {
302                 callu = i;
303             }
304             if (i.getNumber().equals(in)) {
305                 answeru = i;
306             }
307             if (callu != null && answeru != null) {
308                 break;
309             }
310         }
311 
312         if (input.charAt(0) == 'm') {
313             MessageRecord messageRecord = new MessageRecord(input);
314             if (callu != null) {
315                 callu.getUserRecords().addSendMessageRecords(messageRecord);
316                 ;
317             }
318             if (answeru != null) {
319                 callu.getUserRecords().addReceiveMessageRecords(messageRecord);
320             }
321         }
322 
323     }
324 
325 }
326 
327 abstract class CommunicationRecord {
328     protected String callingNumber;
329     protected String answerNumbe;
330 
331     public String getCallingNumber() {
332         return callingNumber;
333     }
334 
335     public void setCallingNumber(String callingNumber) {
336         this.callingNumber = callingNumber;
337     }
338 
339     public String getAnswerNumbe() {
340         return answerNumbe;
341     }
342 
343     public void setAnswerNumbe(String answerNumbe) {
344         this.answerNumbe = answerNumbe;
345     }
346 
347 }
348 
349 abstract class ChargeRule {
350 
351     abstract public double calCost(UserRecords userRecords);
352 
353 }
354 
355 class CallRecord extends CommunicationRecord {
356     private Date startTime;
357     private Date endTime;
358     private String callingAddressAreaCode;
359     private String answerAddressAreaCode;
360 
361     public String getCallType() {
362         String type = "";
363         if (callingAddressAreaCode.equals("0791")) {
364             type = type.concat("1");
365         } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) {
366             type = type.concat("2");
367         } else {
368             type = type.concat("3");
369         }
370 
371         if (answerAddressAreaCode.equals("0791")) {
372             type = type.concat("1");
373         } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) {
374             type = type.concat("2");
375         } else {
376             type = type.concat("3");
377         }
378 
379         return type;
380     }
381 
382     public CallRecord(String[] inputs) {
383         super();
384 
385         char type = inputs[0].charAt(0);
386 
387         String sd = null, st = null, ed = null, et = null;
388 
389         if (type == 't') {
390             if (inputs.length == 6) {
391                 sd = inputs[2];
392                 st = inputs[3];
393                 ed = inputs[4];
394                 et = inputs[5];
395                 callingAddressAreaCode = inputs[0].substring(0, 4);
396                 answerAddressAreaCode = inputs[1].substring(0, 4);
397             } else if (inputs.length == 7) {
398                 sd = inputs[3];
399                 st = inputs[4];
400                 ed = inputs[5];
401                 et = inputs[6];
402                 if (inputs[0].charAt(0) != '0') {
403                     if (inputs[2].length() == 10) {
404                         answerAddressAreaCode = inputs[2].substring(0, 3);
405                     } else {
406                         answerAddressAreaCode = inputs[2].substring(0, 4);
407                     }
408                     callingAddressAreaCode = inputs[1];
409                 } else {
410                     if (inputs[0].length() == 10) {
411                         callingAddressAreaCode = inputs[0].substring(0, 3);
412                     } else {
413                         callingAddressAreaCode = inputs[0].substring(0, 4);
414                     }
415                     answerAddressAreaCode = inputs[2];
416                 }
417             } else if (inputs.length == 8) {
418                 sd = inputs[4];
419                 st = inputs[5];
420                 ed = inputs[6];
421                 et = inputs[7];
422                 callingAddressAreaCode = inputs[1];
423                 answerAddressAreaCode = inputs[3];
424             }
425         } else if (type == 'm') {
426 
427         }
428         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
429         try {
430             startTime = simpleDateFormat.parse(sd + " " + st);
431             endTime = simpleDateFormat.parse(ed + " " + et);
432         } catch (ParseException e) {
433         }
434 
435     }
436 
437     public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
438         super();
439         this.startTime = startTime;
440         this.endTime = endTime;
441         this.callingAddressAreaCode = callingAddressAreaCode;
442         this.answerAddressAreaCode = answerAddressAreaCode;
443     }
444 
445     public Date getStartTime() {
446         return startTime;
447     }
448 
449     public void setStartTime(Date startTime) {
450         this.startTime = startTime;
451     }
452 
453     public Date getEndTime() {
454         return endTime;
455     }
456 
457 
458 }
459 
460 abstract class CallChargeRule extends ChargeRule {
461 
462 }
463 
464 class LandPhoneInCityRule extends CallChargeRule {
465 
466     @Override
467     public double calCost(UserRecords userRecords) {
468         double sumCost = 0;
469         for (CallRecord call : userRecords.getCallingInCityRecords()) {
470             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
471             if (distanceS < 0) {
472                 continue;
473             }
474             double distanceM = (int) distanceS / 60;
475             if (distanceS % 60 != 0) {
476                 distanceM += 1;
477             }
478             if (call.getCallType().equals("11")) {
479                 sumCost += distanceM * 0.1;
480             } else if (call.getCallType().equals("12")) {
481                 sumCost += distanceM * 0.3;
482             } else if (call.getCallType().equals("13")) {
483                 sumCost += distanceM * 0.6;
484             }
485         }
486         return sumCost;
487     }
488 
489 }
490 
491 class LandPhoneInlandRule extends CallChargeRule {
492 
493     @Override
494     public double calCost(UserRecords userRecords) {
495         double sumCost = 0;
496         for (CallRecord call : userRecords.getCallingInLandRecords()) {
497             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
498             if (distanceS < 0) {
499                 continue;
500             }
501             double distanceM = (int) distanceS / 60;
502             if (distanceS % 60 != 0) {
503                 distanceM += 1;
504             }
505             sumCost += distanceM * 0.6;
506         }
507         return sumCost;
508     }
509 
510 }
511 
512 class LandPhoneInProvinceRule extends CallChargeRule {
513 
514     @Override
515     public double calCost(UserRecords userRecords) {
516         double sumCost = 0;
517         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
518             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
519             if (distanceS < 0) {
520                 continue;
521             }
522             double distanceM = (int) distanceS / 60;
523             if (distanceS % 60 != 0) {
524                 distanceM += 1;
525             }
526             sumCost += distanceM * 0.3;
527         }
528         return sumCost;
529     }
530 
531 }
532 
533 class MobilePhoneInCityRule extends CallChargeRule {
534 
535     @Override
536     public double calCost(UserRecords userRecords) {
537         double sumCost = 0;
538         for (CallRecord call : userRecords.getCallingInCityRecords()) {
539             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
540             if (distanceS < 0) {
541                 continue;
542             }
543             double distanceM = (int) distanceS / 60;
544             if (distanceS % 60 != 0) {
545                 distanceM += 1;
546             }
547             if (call.getCallType().equals("11")) {
548                 sumCost += distanceM * 0.1;
549             } else if (call.getCallType().equals("12")) {
550                 sumCost += distanceM * 0.2;
551             } else if (call.getCallType().equals("13")) {
552                 sumCost += distanceM * 0.3;
553             }
554 
555         }
556         return sumCost;
557     }
558 
559 }
560 
561 class MobilePhoneInlandRule extends CallChargeRule {
562 
563     @Override
564     public double calCost(UserRecords userRecords) {
565         double sumCost = 0;
566         for (CallRecord call : userRecords.getCallingInLandRecords()) {
567             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
568             if (distanceS < 0) {
569                 continue;
570             }
571             double distanceM = (int) distanceS / 60;
572             if (distanceS % 60 != 0) {
573                 distanceM += 1;
574             }
575             sumCost += distanceM * 0.6;
576         }
577         for (CallRecord call : userRecords.getAnswerInLandRecords()) {
578             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
579             if (distanceS < 0) {
580                 continue;
581             }
582             double distanceM = (int) distanceS / 60;
583             if (distanceS % 60 != 0) {
584                 distanceM += 1;
585             }
586             sumCost += distanceM * 0.3;
587         }
588         return sumCost;
589     }
590 
591 }
592 
593 class MobilePhoneInProvinceRule extends CallChargeRule {
594 
595     @Override
596     public double calCost(UserRecords userRecords) {
597         double sumCost = 0;
598         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
599             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
600             if (distanceS < 0) {
601                 continue;
602             }
603             double distanceM = (int) distanceS / 60;
604             if (distanceS % 60 != 0) {
605                 distanceM += 1;
606             }
607             if (call.getCallType().equals("21")) {
608                 sumCost += distanceM * 0.3;
609             } else if (call.getCallType().equals("22")) {
610                 sumCost += distanceM * 0.3;
611             } else if (call.getCallType().equals("23")) {
612                 sumCost += distanceM * 0.3;
613             }
614         }
615         return sumCost;
616     }
617 
618 }
619 
620 class MobilePhoneMessageRule extends CallChargeRule {
621 
622     @Override
623     public double calCost(UserRecords userRecords) {
624         double sumCost = 0;
625         int number = 0;
626         for (MessageRecord m : userRecords.getSendMessageRecords()) {
627             int length = m.getMessage().length();
628             if (length <= 10) {
629                 number++;
630             } else {
631                 number += length / 10;
632                 if (length % 10 != 0) {
633                     number++;
634                 }
635             }
636         }
637         if (number <= 3) {
638             sumCost = number * 0.1;
639         } else if (number <= 5) {
640             sumCost = 0.3 + 0.2 * (number - 3);
641         } else {
642             sumCost = 0.7 + 0.3 * (number - 5);
643         }
644         return sumCost;
645     }
646 
647 }
648 
649 class MessageRecord extends CommunicationRecord {
650 
651     private String message;
652 
653     public MessageRecord(String input) {
654         super();
655         this.message = input.substring(26);
656     }
657 
658     public String getMessage() {
659         return message;
660     }
661 
662 
663 }
664 
665 class User {
666 
667     private UserRecords userRecords = new UserRecords();
668     private final double balance = 100;
669     private ChargeMode chargeMode;
670     private String number;
671 
672     public double calCost() {
673         return chargeMode.calCost(userRecords);
674     }
675 
676     public double calBalance() {
677         return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
678     }
679 
680     public UserRecords getUserRecords() {
681         return userRecords;
682     }
683 
684     public void setUserRecords(UserRecords userRecords) {
685         this.userRecords = userRecords;
686     }
687 
688     public ChargeMode getChargeMode() {
689         return chargeMode;
690     }
691 
692     public void setChargeMode(ChargeMode chargeMode) {
693         this.chargeMode = chargeMode;
694     }
695 
696     public String getNumber() {
697         return number;
698     }
699 
700     public void setNumber(String number) {
701         this.number = number;
702     }
703 
704 }
View Code
复制代码

 

三、踩坑心得

1. 最开始看到这类图时并不能马上理解类图想表达的意思,后面经过慢慢的思考明白了这种设计具备的可扩展性,也是后续学习过程中自己需要学习的地方,在用户类User中包含私有属性 用户记录类 useRecords浮点型用户余额 balance计费模式类chargeMode字符串类型电话号码 number以及计算余额,计算消费的方法。收费模式类是一个抽象类,包含计费方式的集合,以及计费的抽象方法。在后续的扩展中我们可以添加计费模式,就是继承抽象的计费模式类然后实现这些方法,比如座机收费模式,短信收费模式,手机收费模式,而在这些收费模式中可以包括一些计费方式比如市内计费方式,省内计费方式,省外计费方式,在用户记录类当中包括市内拨号记录,市内接听记录,短信发送记录,短信接收记录等等。本题还是要依赖正则表达式处理字符串,利用正则表达式来过滤不符合格式的输入。

2.开始未考虑到未开户的用户产生的通讯记录,导致后面计算的时候出现错误,解决方案就是添加判断条件(若用户集合中不含拨号号码则跳过)。

3.未考虑到一些特殊地区的区号为三位数导致正则表达式出现误判。

4.抽象类可以有构造方法,接口中不能有构造方法。抽象类中可以有普通成员变量,接口中没有普通成员变量。抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。抽象类中可以包含静态方法,接口中不能包含静态方法。

5.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。一个类可以实现多个接口,但只能继承一个抽象类。

四、改进建议

1.添加判断条件(若用户集合中不含拨号号码则跳过)。

2.减少代码的嵌套,将具体功能和判断写成详细的方法,包装起来,不要一个函数写一长串。

3.尽量将子类里相同的方法集合起来写在父类里面。

五、总结

   对于本阶段的学习,收获还是挺大的,较之前的题目也更加贴近生活。了解了许多设计模式,也明白了设计模式的重要性, 设计模式是一套经过反复使用的代码设计经验,目的是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 设计模式于己于人于系统都是多赢的,它使得代码编写真正工程化,它是软件代码的基石,如同大厦的一块块砖石一样。 

  这阶段的学习也对JavaFX有了更深入的理解。场景scene、布局layout、UI控件是javaFX的基本组成部分。控件可以放到布局中,布局可以放到布局中,也可以放到场景中,这里要注意,每个场景里只能放一个布局,多个布局的话只会默认识别最后一个布局。如果添加多个布局,虽然页面可以显示完整,但是所添加的事件驱动可能不会做出反应。

 

posted @   我等你许久了  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示