首页 > 其他分享 >BLOG-3

BLOG-3

时间:2022-12-06 00:56:39浏览次数:62  
标签:inputs return String double ArrayList BLOG public

前言:

  在上一个月的课程学习中,我吸收掌握了很多具有拓展性、延申性的知识,其中包含类与对象的构造、组成,以及在封装、继承、多态三原则优化后的代码结构基础上,进行抽象类、抽象方法的联系与应用。同时,也在课堂上和平时的大作业里着重锻炼了自己对程序类图结构的拆分和理解,并从中编写出成功案例的能力。在第六次至第八次PTA大作业中,我们接触并实现了以类与对象为基础的电信计费系列的编程,三次的题目分别从座机计费、手机座机计费、短信计费出发,对我们关于构造类知识的掌握、类图的分析与理解做出了考察。除开三次大作业里难度适中的普通题目,电信计费系列的题目难度偏大,但主要原因在于代码量大、涉及的类与继承关系复杂。不过只要我们能够读懂类图,分析清楚题目的要求,加之对不同信息格式的严格判断,写出符合要求的代码是完全可行的。本文将重点分析三次大作业中电信计费系列的题目,并用IDEA生成类图、SourceMonitor生成圈图进行辅助解析。

设计与分析:

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中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。

ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。

UserRecords是用户记录类,保存用户各种通话、短信的记录,
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。

 

 

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

CallRecord(通话记录类)包含属性:
通话的起始、结束时间以及
拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。
区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。

 

 

图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList<CallRecord> callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。

LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是
座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。
(提示:可以从UserRecords类中获取各种类型的callRecords)。

后续扩展说明:
后续题目集将增加手机用户,手机用户的计费方式中除了与座机计费类似的主叫通话费之外,还包含市外接听电话的漫游费以及发短信的费用。在本题的设计时可统一考虑。
通话记录中,手机需要额外记录拨打/接听的地点的区号,比如:
座机打手机:t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
短信的格式:m-主叫号码,接收号码,短信内容
m-18907910010 13305862264 welcome to jiangxi
m-13305862264 18907910010 thank you

输入样例:

在这里给出一组输入。例如:

u-079186300001 0
t-079186300001 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:25
end

输出样例:

在这里给出相应的输出。例如:

079186300001 3.0 77.0

其余参考样例详见附件,未尽事宜以附件样例为准:

电信计费简化版-座机计费说明.pdf

我的答案:

首先先给出关键部分的实现细节:

用户记录类UserRecords:

  1 class UserRecords {
  2 
  3     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
  4     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
  5     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
  6     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
  7     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
  8     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
  9     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
 10     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
 11 
 12     public void addCallingInCityRecords(CallRecord callRecord) {
 13         callingInCityRecords.add(callRecord);
 14     }
 15 
 16     public void addCallingInProvinceRecords(CallRecord callRecord) {
 17         callingInProvinceRecords.add(callRecord);
 18     }
 19 
 20     public void addCallingInLandRecords(CallRecord callRecord) {
 21         callingInLandRecords.add(callRecord);
 22     }
 23 
 24     public void addAnswerInCityRecords(CallRecord callRecord) {
 25         answerInCityRecords.add(callRecord);
 26     }
 27 
 28     public void aaddAnswerInProvinceRecords(CallRecord callRecord) {
 29         answerInProvinceRecords.add(callRecord);
 30     }
 31 
 32     public void addAnswerInLandRecords(CallRecord callRecord) {
 33         answerInLandRecords.add(callRecord);
 34     }
 35 
 36     public void addSendMessageRecords(MessageRecord callRecord) {
 37         sendMessageRecords.add(callRecord);
 38     }
 39 
 40     public void addReceiveMessageRecords(MessageRecord callRecord) {
 41         receiveMessageRecords.add(callRecord);
 42     }
 43 
 44     public ArrayList<CallRecord> getCallingInCityRecords() {
 45         return callingInCityRecords;
 46     }
 47 
 48     public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
 49         this.callingInCityRecords = callingInCityRecords;
 50     }
 51 
 52     public ArrayList<CallRecord> getCallingInProvinceRecords() {
 53         return callingInProvinceRecords;
 54     }
 55 
 56     public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
 57         this.callingInProvinceRecords = callingInProvinceRecords;
 58     }
 59 
 60     public ArrayList<CallRecord> getCallingInLandRecords() {
 61         return callingInLandRecords;
 62     }
 63 
 64     public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
 65         this.callingInLandRecords = callingInLandRecords;
 66     }
 67 
 68     public ArrayList<CallRecord> getAnswerInCityRecords() {
 69         return answerInCityRecords;
 70     }
 71 
 72     public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
 73         this.answerInCityRecords = answerInCityRecords;
 74     }
 75 
 76     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
 77         return answerInProvinceRecords;
 78     }
 79 
 80     public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
 81         this.answerInProvinceRecords = answerInProvinceRecords;
 82     }
 83 
 84     public ArrayList<CallRecord> getAnswerInLandRecords() {
 85         return answerInLandRecords;
 86     }
 87 
 88     public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
 89         this.answerInLandRecords = answerInLandRecords;
 90     }
 91 
 92     public ArrayList<MessageRecord> getSendMessageRecords() {
 93         return sendMessageRecords;
 94     }
 95 
 96     public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
 97         this.sendMessageRecords = sendMessageRecords;
 98     }
 99 
100     public ArrayList<MessageRecord> getReceiveMessageRecords() {
101         return receiveMessageRecords;
102     }
103 
104     public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
105         this.receiveMessageRecords = receiveMessageRecords;
106     }
107 
108 }
View Code

 通话记录类CallRecord:

 1 class CallRecord extends CommunicationRecord {
 2     private Date startTime;
 3     private Date endTime;
 4     private String callingAddressAreaCode;
 5     private String answerAddressAreaCode;
 6 
 7     public int getCallType() {
 8         if (callingAddressAreaCode.equals(answerAddressAreaCode)) {
 9             return 1;
10         }
11         if (callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701")) {
12             if (answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701")) {
13                 return 2;
14             }
15         }
16         return 3;
17     }
18 
19     public CallRecord(String[] inputs) {
20         super();
21         if (inputs[0].length() == 10) {
22             callingAddressAreaCode = inputs[0].substring(0, 3);
23         } else {
24             callingAddressAreaCode = inputs[0].substring(0, 4);
25         }
26         if (inputs[1].length() == 10) {
27             answerAddressAreaCode = inputs[1].substring(0, 3);
28         } else {
29             answerAddressAreaCode = inputs[1].substring(0, 4);
30         }
31         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
32         try {
33             startTime = simpleDateFormat.parse(inputs[2] + " " + inputs[3]);
34             endTime = simpleDateFormat.parse(inputs[4] + " " + inputs[5]);
35         } catch (ParseException e) {
36         }
37 
38     }
39 
40     public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
41         super();
42         this.startTime = startTime;
43         this.endTime = endTime;
44         this.callingAddressAreaCode = callingAddressAreaCode;
45         this.answerAddressAreaCode = answerAddressAreaCode;
46     }
47 
48     public Date getStartTime() {
49         return startTime;
50     }
51 
52     public void setStartTime(Date startTime) {
53         this.startTime = startTime;
54     }
55 
56     public Date getEndTime() {
57         return endTime;
58     }
59 
60     public void setEndTime(Date endTime) {
61         this.endTime = endTime;
62     }
63 
64     public String getCallingAddressAreaCode() {
65         return callingAddressAreaCode;
66     }
67 
68     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
69         this.callingAddressAreaCode = callingAddressAreaCode;
70     }
71 
72     public String getAnswerAddressAreaCode() {
73         return answerAddressAreaCode;
74     }
75 
76     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
77         this.answerAddressAreaCode = answerAddressAreaCode;
78     }
79 }
View Code

全码展示:

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

 SourceMonitor分析图:

 IDEA生成程序类图:

 总结:

  本题作为电信计费系列的第一道题,需要我们将题干中给出的类图进行详细的分析,从中提取关键信息组成完成的可运行代码。对于本题我的思路和解题步骤可总结如下:首先构造出电信计费系列的基本框架,即弄清楚都有些什么具体的类,类与类之间的继承关系是怎样的。比如通过第一张类图,我们可以认为它是用来讲用户的,其讲清楚了三个类:用户类User,用户记录类UserRecords,以及计费方式ChargeMode。其中ChargeMode是抽象类,我们可以同时确定继承ChargeMode的是哪些类,以及三种类之间的联系。按照同样的方式分析类图2与类图3,我们可以认为它们分别是通讯记录类和计费规则相关类,之再后向类中填入方法,同时注意抽象类的抽象方法,以及继承时对方法的引用做出相应的改变。另外,本题除了对类与对象以及抽象类、抽象方法,类图分析的考察,由于题目所处的现实环境,对ArryList集合的考察也非常突出。本题构建的结构(此处仅添加了座机计费的功能)对后续功能的继续添加(本系列的第二题需要添加手机计费)十分重要,值得花费较长时间去好好琢磨。

 

7-2 电信计费系列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:

 

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

 

 

图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。CallRecord(通话记录类)包含属性:
通话的起始、结束时间以及
拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。
区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。

 

 

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

(提示:可以从UserRecords类中获取各种类型的callRecords)。
注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。

输入样例:

在这里给出一组输入。例如:

u-13811111111 1
t-13811111111 0791 13811111110 020 2022.1.3 08:00:00 2022.1.3 08:09:20
end

输出样例:

在这里给出相应的输出。例如:

13811111111 3.0 82.0

更多内容详见附件:

电信计费简化版-座机计费说明.pdf

我的答案:

上一题我们已经确定好了仅含有座机计费的体系结构,现在我们把手机计费体系添加的部分类展示如下:

 1 class LandlinePhoneCharging extends ChargeMode {
 2 
 3     private double monthlyRent = 20;
 4 
 5     public LandlinePhoneCharging() {
 6         super();
 7         chargeRules.add(new LandPhoneInCityRule());
 8         chargeRules.add(new LandPhoneInProvinceRule());
 9         chargeRules.add(new LandPhoneInlandRule());
10     }
11 
12     @Override
13     public double calCost(UserRecords userRecords) {
14         double sumCost = 0;
15         for (ChargeRule rule : chargeRules) {
16             sumCost += rule.calCost(userRecords);
17         }
18         return sumCost;
19     }
20 
21     @Override
22     public double getMonthlyRent() {
23         return monthlyRent;
24     }
25 
26 }
27 
28 class MobilePhoneCharging extends ChargeMode {
29 
30     private double monthlyRent = 15;
31 
32     public MobilePhoneCharging() {
33         super();
34         chargeRules.add(new MobilePhoneInCityRule());
35         chargeRules.add(new MobilePhoneInProvinceRule());
36         chargeRules.add(new MobilePhoneInlandRule());
37     }
38 
39     @Override
40     public double calCost(UserRecords userRecords) {
41         double sumCost = 0;
42         for (ChargeRule rule : chargeRules) {
43             sumCost += rule.calCost(userRecords);
44         }
45         return sumCost;
46     }
47 
48     @Override
49     public double getMonthlyRent() {
50         return monthlyRent;
51     }
52 
53 }
View Code

全码如下:

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

 SourceMonitor分析图:

 IDEA生成程序类图:

总结:

  本题是电信计费系列的第二题,在上一题座机计费的基础上添加了手机计费的功能和计费准则,本题关键点在于添加新继承在原抽象类下的子类。举个例子,CallChargeRule是电信计费的抽象规则类,我们在原来的座机计费中定义了如下三个子类去继承:LandPhoneInlandRule、LandPhoneInlandRule和LandPhoneInCityRule,但是在手机座机并列计费的情况下,对于抽象规则类我们要添加继承在它之下的子类,例如:MobilePhoneInCityRule、MobilePhoneInlandRule、MobilePhoneInProvinceRule。本题中还加入了更多非常复杂的格式判定,对正则表达式的理解和掌握程度有非常大的考察力度。不过我第一步首先还是抄类图,题干中的类图会因为手机类的加入发生变化,我们在第一题的基础上按照同样的方式加入手机通信的付费规则等需要增添的类即可(用户类那些都可以不变的)。

 

7-3 电信计费系列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:

 

 

 

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

 

 

 

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

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

(提示:可以从UserRecords类中获取各种类型的callRecords)。

注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。

输入样例:

在这里给出一组输入。例如:

u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaaaaaaaaaaaaa
end

输出样例:

在这里给出相应的输出。例如:

18907910010 0.3 99.7

在这里给出一组输入。例如:

u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaa
m-18907910010 13305862264 aaaaaaa.
m-18907910010 13305862264 bb,bbbb
end

输出样例1:

在这里给出相应的输出。例如:

18907910010 0.5 99.5

我的答案:

这道题的测试点居然只有短信计费哈哈哈哈哈,直接上全码:

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

SourceMonitor分析图:

 IDEA生成程序类图:

 

 

 总结:

  这题其实可以偷大懒。本题的测试点仅有短信计费,和手机计费不同,我们可以像考虑座机计费的构成那样去思考,而无需进一步完善先前的体系。根据类图,我们依次建立对应的类及其继承方法,再增添短信计费需要新增的类:如MobilePhoneMassageCharging、MobilePhoneMessageRule等等。本题使用的方法和结构与前两题类似,按照同样的思路去做就行,对此我们不做过多讨论。

 

踩坑心得

在过去一个月的学习中,我再次总结了如下几个自己容易犯的错误:

  1、设计类的时候忘记添加构造函数。一般题目中其实很少用到构造函数,但作为学习的过程,添加构造函数也是创建一个完整类的一部分。

  2、类中和方法漏写和判断情况缺失,就算是有类图进行参考,这种情况还是出现了。电信计费需要判断的东西非常多,容易漏掉导致测试点报错.

  3、对正则表达式的理解匮乏。正则表达式是经常应用在function(我一般用它来判断输入格式的正误)的一种判断方法,正则表达式的外围一定要添加“ ”。

  4、对新知识的掌握尚未完全。在这个阶段的学习中,我们在类与对象、方法基本构建、继承、多态的使用的基础上,新学习并着重强化了对抽象类、抽象方法的构造,接口的加入(这个在实验里比较多),还有javaFX的使用。新知较多,使用起来不够熟练。

  5、相关经验较少,对电信计费的实际生活体系不够了解,导致做题思维较慢。

改进意见

   在看到题目时,首先要分析题目中蕴含的结构。比如电信计费都给了类图,相当于已经告知了基本结构,那我们就要分析都有哪些类,创建什么对象,继承关系是怎样的,子类的方法哪些可以直接继承抽象父类使用,哪些是自己独有的方法。其次,要扎实自己的基本功。思路清晰的同时,要学会根据不同的题干环境进行变通。比如第一题,建立了用户方面,还需要建立通讯记录,既然是电信计费,那就要建立对应的计费准则。第一题仅考虑电信计费中的座机,第二题就要学会在其基础上加入对手机的操作,第三题由于出题的原因可以简略很多。

总结

  通过SourceMontior检测发现,自己写的部分代码各项数值的测量值和规定的范围相差甚远,证明自己还可以有很多的提升空间。Java是一门以面向对象为主的编程语言,所以对类和对象及其方法的要求十分看重。在今后课程的学习中,我们要学会三步走分析法:着重分析题目需求、弄懂类中包含的内容以及方法的编写,最后搞清各个功能代码块之间的联系。通过第三阶段java课程的学习,我对java这一门编程语言有了本质上的了解,明白了类与对象作为java语言内核的原因。在不断吸收新知的同时,也发现了自己的代码有很多的漏洞,未来一定会进行改正,变得越来越好。老师上课质量很高,希望老师能将上课讲解得部分代码传到群内方便我们课后复习就更好啦!

 

标签:inputs,return,String,double,ArrayList,BLOG,public
From: https://www.cnblogs.com/aolibugei/p/16952869.html

相关文章

  • BLOG-3
                                                         ......
  • blog_03
    第三次博客作业目录第三次博客作业1.前言2.设计与分析(1)题目集67-1电信计费系列1-座机计费(2)题目集77-1电信计费系列2-手机+座机计费(3)题目集87-1电信计费系列3-......
  • OO第三次java学习blog
    第三次java学习blog第三次java学习blog前言涉及知识点:题量与难度设计与分析电信计费1电信计费2电信计费3踩坑心得改进建议总结前言涉及知识点:1.......
  • Blog3-电信计费系列题目集
    前言电信计费系列题目虽然难度相对于多边形系列有所下降,但涉及知识点很广,主要如下:1、容器的使用2、抛出异常3、抽象类4、继承与多态5、正则表达式6、类和对象设计......
  • BLOG-3
    一、前言难度分析:近三次大作业难度相较与前面多边形难度有所下降,手机计费比座机计费大,而最后的短信计费难度则又降低。题量:题量适中知识点:继承多态容器,正则表达式等......
  • 基于yolo进行目标检测的实验和研究【BLOG】
          根据我接触到的项目经验来看,需要我们进行检测的不是自然场景下的任意物体,而是特定场景下一类物体。典型的就是钢管识别,这些照片一般都是在厂区里面拍的、......
  • 介绍一个JAVA的开源blog--APACHE ROLLER
    开源的BLOG系统,最推荐的依然是PHP的,非常多选择,JAVA的可选择的不多,但今天居然发现一个APACHE的顶级项目roller,项目地址是​​​http://rolller.......
  • weblogic12版本节点启动报错问题处理
    问题:<Sep12,202211:00:13AMCST><Warning><DeploymentService><BEA-290074><Deploymentserviceservletreceivedfiledownloadrequestforfile"security/Se......
  • 使用cnblog上传markdown文件到博客园
    下载并且安装python3地址:https://www.python.org/安装完以后:下载pycnblog地址:https://github.com/dongfanger/pycnblo将下载的pycnblog工具解压,打开config.yaml......
  • weblogic优化
    一、登录web界面卡顿[root@localhostsecurity]#find/-namejava.security/apppackage/jdk1.8.0_311/jre/lib/security/java.security[root@localhostsecurity]#cat......