第三次博客作业

前言:这是本学期最后一次blog作业,最后一次的pta作业也降低了许多难度。

这三次作业主要是写电信计费功能,考察的知识点有很多。例如:lamda表达式的

运用,SimpleDate类的运用。相比之前难度降低,所以对我来说相对简单。

7-1 电信计费系列1-座机计费
作者 蔡轲
单位 南昌航空大学

实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。

输入格式:

输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码除区号外由是7-8位数字组成。
本题只考虑计费类型0-座机计费,电信系列2、3题会逐步增加计费类型。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
注意:
本题非法输入只做格式非法的判断,不做内容是否合理的判断(时间除外,否则无法计算),比如:
1、输入的所有通讯信息均认为是同一个月的通讯信息,不做日期是否在同一个月还是多个月的判定,直接将通讯费用累加,因此月租只计算一次。
2、记录中如果同一电话号码的多条通话记录时间出现重合,这种情况也不做判断,直接 计算每条记录的费用并累加。
3、用户区号不为南昌市的区号也作为正常用户处理。

输出格式:

根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,
单位元)。假设每个用户初始余额是100元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。

错误处理:
输入数据中出现的不符合格式要求的行一律忽略。

建议类图:
参见图1、2、3,可根据理解自行调整:

image.png

                                    图1
图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。

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

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

image.png

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

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

image.png

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

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

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

 

 

以下是源码:

复制代码
  1 import java.util.Scanner;
  2 import java.util.ArrayList;
  3 import java.text.ParseException;
  4 import java.text.SimpleDateFormat;
  5 import java.util.Date;
  6 import java.util.Collections;
  7 
  8 public class Main {
  9     public static void main(String[] args)throws Exception{
 10         Scanner input = new Scanner(System.in);
 11         ArrayList<User> user = new ArrayList<>();
 12         ParseInput parseInput = new ParseInput();
 13         String s = input.nextLine();
 14         String regex = "[u][-]0791[0-9]{7,8}[ ][0]";
 15         String regex_ = "";
 16         int i = 0;
 17         boolean flag = false;
 18         while (!s.equals("end")){
 19             if(s.matches(regex)) {
 20                 for (int l = 0; l<user.size(); l++) {
 21                     if (parseInput.ParseInputNumber(s).equals(user.get(l).getNumber())) {
 22                         flag = true;
 23                     }
 24                 }
 25                 if (!flag) {
 26                     user.add(new User(parseInput.ParseInputNumber(s)));
 27                     user.get(i).setUsersRecords(new UsersRecords());
 28                     i++;
 29                     regex_ = "[t][-]0791[0-9]{7,8}[ ][0-9]{10,12}[ ]([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9])[\\.]([1-9]|[1-9][0-9])[\\.]([1-9]|[1-9][0-9])[ ]([0-1][0-9]|2[0-3])[:][0-5][0-9][:][0-5][0-9][ ]([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9])[\\.]([1-9]|[1-9][0-9])[\\.]([1-9]|[1-9][0-9])[ ]([0-1][0-9]|2[0-3])[:][0-5][0-9][:][0-5][0-9]";
 30                 }
 31             }
 32             else if(s.matches(regex_)) {
 33                 if (parseInput.ParseTimeFormat(s)) {
 34                     int j = 0;
 35                     for (; j<user.size(); j++) {
 36                         if (user.get(j).getNumber().equals(parseInput.ParseInputCalNumber(s))) {
 37                             CallRecord callRecord = new CallRecord();
 38                             callRecord.setStartTime(parseInput.ParseInputStartDate(s));
 39                             callRecord.setEndTime(parseInput.ParseInputEndData(s));
 40                             callRecord.setCallingNumber(parseInput.ParseInputCalNumber(s));
 41                             callRecord.setAnswerNumber(parseInput.ParseInputAnswerNumber(s));
 42                             if (parseInput.ParseNumberArea(callRecord.getAnswerNumber()) == 1) {
 43                                 user.get(j).getUsersRecords().addCallingInCityRecords(callRecord);
 44                             } else if (parseInput.ParseNumberArea(callRecord.getAnswerNumber()) == 2) {
 45                                 user.get(j).getUsersRecords().addCallingInProvinceRecords(callRecord);
 46                             } else if(parseInput.ParseNumberArea(callRecord.getAnswerNumber())==0){
 47                                 user.get(j).getUsersRecords().addCallingInLandRecords(callRecord);
 48                             }
 49                         }
 50                     }
 51                 }
 52             }
 53             s = input.nextLine();
 54         }
 55 
 56         Collections.sort(user);
 57 
 58         for (i = 0;i< user.size();i++){
 59             System.out.println(user.get(i).getNumber()+" "+String.format("%.1f",user.get(i).CalCost())+" "+String.format("%.1f",user.get(i).CalBalance()));
 60         }
 61     }
 62 }
 63 abstract class CallChargeRule extends ChargeRule{
 64     public abstract double calCost(ArrayList<CallRecord> callRecords) throws Exception;
 65 
 66 }
 67 class CallRecord extends CommunicationRecord {
 68     private Date startTime;
 69     private Date endTime;
 70 
 71     private String callingAddressAreaCode;
 72     private String answerAddressAreaCode;
 73 
 74     public Date getStartTime() {
 75         return startTime;
 76     }
 77 
 78     public void setStartTime(Date startTime) {
 79         this.startTime = startTime;
 80     }
 81 
 82     public Date getEndTime() {
 83         return endTime;
 84     }
 85 
 86     public void setEndTime(Date endTime) {
 87         this.endTime = endTime;
 88     }
 89 
 90     public String getCallingAddressAreaCode() {
 91         return callingAddressAreaCode;
 92     }
 93 
 94     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
 95         this.callingAddressAreaCode = callingAddressAreaCode;
 96     }
 97 
 98     public String getAnswerAddressAreaCode() {
 99         return answerAddressAreaCode;
100     }
101 
102     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
103         this.answerAddressAreaCode = answerAddressAreaCode;
104     }
105 
106     public int getTimeOf() throws Exception {
107         SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
108         String start = simpleFormat.format(startTime);
109         String end = simpleFormat.format(endTime);
110         Date fromM = simpleFormat.parse(start.substring(0, 16));
111         Date toM = simpleFormat.parse(end.substring(0, 16));
112 
113         simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
114         start = simpleFormat.format(startTime);
115         end = simpleFormat.format(endTime);
116         int secondStart = Integer.parseInt(start.substring(17, 19));
117         int secondEnd = Integer.parseInt(end.substring(17, 19));
118 
119         long from = fromM.getTime();
120         long to = toM.getTime();
121         int gap = (int) ((to - from) / (1000 * 60));
122 
123         if (secondEnd > secondStart) {
124             gap++;
125         }
126 
127         if (gap > 0) {
128             return gap;
129         } else return 0;
130     }
131 }
132 abstract class ChargeMode {
133     public ArrayList<ChargeRule> getChargeRules() {
134         return chargeRules;
135     }
136 
137     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
138         this.chargeRules = chargeRules;
139     }
140 
141     private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();
142 
143     public abstract double CalCost(UsersRecords usersRecords) throws Exception;
144 
145     public abstract double getMonthlyRent();
146 }
147 abstract class ChargeRule {
148 }
149 abstract class CommunicationRecord {
150     protected String callingNumber;
151     protected String answerNumber;
152 
153     public String getCallingNumber() {
154         return callingNumber;
155     }
156 
157     public void setCallingNumber(String callingNumber) {
158         this.callingNumber = callingNumber;
159     }
160 
161     public String getAnswerNumber() {
162         return answerNumber;
163     }
164 
165     public void setAnswerNumber(String answerNumber) {
166         this.answerNumber = answerNumber;
167     }
168 }
169 class DateUtil {
170 
171     private int year;
172     private int month;
173     private int day;
174 
175     public DateUtil(){
176 
177     }
178 
179     public int getYear() {
180         return year;
181     }
182 
183     public void setYear(int year) {
184         this.year = year;
185     }
186 
187     public int getMonth() {
188         return month;
189     }
190 
191     public void setMonth(int month) {
192         this.month = month;
193     }
194 
195     public int getDay() {
196         return day;
197     }
198 
199     public void setDay(int day) {
200         this.day = day;
201     }
202 
203     public DateUtil(int year, int month, int day){
204         this.year = year;
205         this.month = month;
206         this.day = day;
207     }
208 
209     public boolean checkInputValidity(){
210         if (month > 0 && month < 13 && day > 0 && day < 32) {
211             if (isLeapYear(year)) {
212                 if ((day>29&&month==2)||(day>30&&month==4)||(day>30&&month==6)||(day>30&&month==9)||(day>30&&month==11)){
213                     return false;
214                 } else {
215                     return true;
216                 }
217             }
218             else {
219                 if ((day>28&&month==2)||(day>30&&month==4)||(day>30&&month==6)||(day>30&&month==9)||(day>30&&month==11)) {
220                     return false;
221                 } else {
222                     return true;
223                 }
224             }
225         }
226         else {
227             return false;
228         }
229     }//检测输入的年、月、日是否合法
230     public boolean isLeapYear(int year){
231         if(year%400==0){
232             return true;
233         }
234         else if(year%4==0&&year%100!=0){
235             return true;
236         }
237         else {
238             return false;
239         }
240     }//判断year是否为闰年
241 }
242 class LandingPhoneCharging extends ChargeMode{
243 
244     CallChargeRule city = new LandPhoneInCityRule();
245     CallChargeRule province = new LandPhoneInProvinceRule();
246     CallChargeRule land = new LandPhoneInLandRule();
247 
248     @Override
249     public double CalCost(UsersRecords usersRecords) throws Exception{
250         double sum = 0;
251         sum += city.calCost(usersRecords.getCallingInCityRecords());
252         sum += province.calCost(usersRecords.getCallingInProvinceRecords());
253         sum += land.calCost(usersRecords.getCallingInLandRecords());
254         return sum;
255     }
256 
257     @Override
258     public double getMonthlyRent() {
259         return monthlyRent;
260     }
261 
262     private double monthlyRent = 20;
263 }
264 class LandPhoneInCityRule extends CallChargeRule{
265     @Override
266     public double calCost(ArrayList<CallRecord> callRecords)throws Exception{
267         int i = 0;
268         double sum = 0;
269         for(;i<callRecords.size();i++){
270             sum += callRecords.get(i).getTimeOf()*0.1;
271         }
272         return sum;
273     }
274 }
275 class LandPhoneInLandRule extends CallChargeRule{
276     @Override
277     public double calCost(ArrayList<CallRecord> callRecords)throws Exception {
278         int i = 0;
279         double sum = 0;
280         for(;i<callRecords.size();i++){
281             sum += callRecords.get(i).getTimeOf()*0.6;
282         }
283         return sum;
284     }
285 }
286 class LandPhoneInProvinceRule extends CallChargeRule{
287     @Override
288     public double calCost(ArrayList<CallRecord> callRecords)throws Exception {
289         int i = 0;
290         double sum = 0;
291         for(;i<callRecords.size();i++){
292             sum += callRecords.get(i).getTimeOf()*0.3;
293         }
294         return sum;
295     }
296 }
297 class MessageRecord extends CommunicationRecord{
298     private String message;
299 
300     public String getMessage() {
301         return message;
302     }
303 
304     public void setMessage(String message) {
305         this.message = message;
306     }
307 }
308 class ParseInput {
309 
310     public String ParseInputNumber(String s){
311         String ss[]=s.split("-");
312         String sss[] =ss[1].split(" ");
313         return sss[0];
314     }
315 
316     public Date ParseInputStartDate(String s){
317         String ss[]=s.split("-");
318         String sss[] =ss[1].split(" ");
319         String ssss[] = sss[2].split("\\.");
320         String time[] = sss[3].split(":");
321         int year = Integer.parseInt(ssss[0]);
322         int month = Integer.parseInt(ssss[1]);
323         int day = Integer.parseInt(ssss[2]);
324         int hour = Integer.parseInt(time[0]);
325         int minute = Integer.parseInt(time[1]);
326         int second = Integer.parseInt(time[2]);
327         Date date = new Date(year,month,day,hour,minute,second);
328         return date;
329     }
330 
331     public Date ParseInputEndData(String s){
332         String ss[]=s.split("-");
333         String sss[] =ss[1].split(" ");
334         String ssss[] = sss[4].split("\\.");
335         String time[] = sss[5].split(":");
336         int year = Integer.parseInt(ssss[0]);
337         int month = Integer.parseInt(ssss[1]);
338         int day = Integer.parseInt(ssss[2]);
339         int hour = Integer.parseInt(time[0]);
340         int minute = Integer.parseInt(time[1]);
341         int second = Integer.parseInt(time[2]);
342         Date date = new Date(year,month,day,hour,minute,second);
343         return date;
344     }
345 
346     public String ParseInputCalNumber(String s){
347         String ss[]=s.split("-");
348         String sss[] = ss[1].split(" ");
349         return sss[0];
350     }
351 
352     public String ParseInputAnswerNumber(String s){
353         String ss[]=s.split("-");
354         String sss[] = ss[1].split(" ");
355         return sss[1];
356     }
357 
358     public int ParseNumberArea(String s){
359         String regex1 = "0791[0-9]{7,8}";
360         String regex2 = "079[023456789][0-9]{7,8}";
361         String regex3 = "0701[0-9]{7,8}";
362         if(s.matches(regex1)) {
363             return 1;
364         }
365         else if(s.matches(regex2)||s.matches(regex3)) {
366             return 2;
367         }
368         return 0;
369     }
370 
371     public boolean ParseTimeFormat(String s){
372         String ss[]=s.split("-");
373         String sss[] =ss[1].split(" ");
374         String startDate[] = sss[2].split("\\.");
375         String endDate[] = sss[4].split("\\.");
376 
377 
378         DateUtil dateUtilStart = new DateUtil(Integer.parseInt(startDate[0]), Integer.parseInt(startDate[1]), Integer.parseInt(startDate[2]));
379         DateUtil dateUtilEnd = new DateUtil(Integer.parseInt(endDate[0]),Integer.parseInt(endDate[1]),Integer.parseInt(endDate[2]));
380 
381 
382         return dateUtilEnd.checkInputValidity()&&dateUtilStart.checkInputValidity();
383     }
384 }
385 class User implements Comparable<User>{
386 
387     private UsersRecords usersRecords = new UsersRecords();
388     private double balance = 100;
389     private ChargeMode chargeMode;
390     private String number;
391 
392     public User(String number){
393         this.number = number;
394     }
395 
396     public User() {
397 
398     }
399 
400     public double CalCost()throws Exception{
401         chargeMode = new LandingPhoneCharging();
402         return chargeMode.CalCost(getUsersRecords());
403     }
404 
405     public double CalBalance()throws Exception{
406         this.balance = balance - CalCost() - chargeMode.getMonthlyRent();
407         return balance;
408     }
409 
410     public double getBalance() {
411         return balance;
412     }
413 
414     public UsersRecords getUsersRecords() {
415         return usersRecords;
416     }
417 
418     public void setUsersRecords(UsersRecords usersRecords) {
419         this.usersRecords = usersRecords;
420     }
421 
422     public ChargeMode getChargeMode() {
423         return chargeMode;
424     }
425 
426     public void setChargeMode(ChargeMode chargeMode) {
427         this.chargeMode = chargeMode;
428     }
429 
430     public String getNumber() {
431         return number;
432     }
433 
434     public void setNumber(String number) {
435         this.number = number;
436     }
437 
438     @Override
439     public int compareTo(User o) {
440         return this.getNumber().compareTo(o.getNumber());
441     }
442 }
443 class UsersRecords {
444 
445     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();//市内拨打电话
446     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();//省内拨打电话
447     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();//国内拨打电话
448     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();//市内接听电话
449     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();//省内接听电话
450     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();//国内接听电话
451     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();//发出短信
452     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();//接收短信
453 
454     public ArrayList<CallRecord> getCallingInCityRecords() {
455         return callingInCityRecords;
456     }
457 
458     public ArrayList<CallRecord> getCallingInProvinceRecords() {
459         return callingInProvinceRecords;
460     }
461 
462     public ArrayList<CallRecord> getCallingInLandRecords() {
463         return callingInLandRecords;
464     }
465 
466     public ArrayList<CallRecord> getAnswerInCityRecords() {
467         return answerInCityRecords;
468     }
469 
470     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
471         return answerInProvinceRecords;
472     }
473 
474     public ArrayList<CallRecord> getAnswerInLandRecords() {
475         return answerInLandRecords;
476     }
477 
478     public ArrayList<MessageRecord> getSendMessageRecords() {
479         return sendMessageRecords;
480     }
481 
482     public ArrayList<MessageRecord> getReceiveMessageRecords() {
483         return receiveMessageRecords;
484     }
485 
486     public void addCallingInCityRecords(CallRecord callRecord){
487         callingInCityRecords.add(callRecord);
488     }
489 
490     public void addCallingInProvinceRecords(CallRecord callRecord){
491         callingInProvinceRecords.add(callRecord);
492     }
493 
494     public void addCallingInLandRecords(CallRecord callRecord){
495         callingInLandRecords.add(callRecord);
496     }
497 
498     public void addAnswerInCityRecords(CallRecord callRecord){
499         answerInCityRecords.add(callRecord);
500     }
501 
502     public void addAnswerInProvinceRecords(CallRecord callRecord){
503         answerInProvinceRecords.add(callRecord);
504     }
505 
506     public void addAnswerInLandRecords(CallRecord callRecord){
507         answerInLandRecords.add(callRecord);
508     }
509 
510     public void addSendMessageRecords(MessageRecord messageRecord){
511         sendMessageRecords.add(messageRecord);
512     }
513 
514     public void addReceiveMessageRecords(MessageRecord messageRecord){
515         receiveMessageRecords.add(messageRecord);
516     }
517 }

复制代码

 

这是类图

分析:

这道题要先判断电话号码的区域从而再将通话记录给分成不同的类型

最后在进行对话费的计算。

要注意的点:对于输入的通话记录进行格式判断。

对于输入的通话记录中的时间也要进行判断

实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
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三个类分别是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。    
 

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

代码如下:

复制代码
  1 import java.util.ArrayList;
  2 import java.util.Collections;
  3 import java.util.Scanner;
  4 import java.text.SimpleDateFormat;
  5 import java.util.Date;
  6 public class Main {
  7     public static void main(String[] args)throws Exception {
  8         Scanner input = new Scanner(System.in);
  9         ArrayList<User> user = new ArrayList<>();
 10         ParseInput parseInput = new ParseInput();
 11         String s = input.nextLine();
 12         String regex = "[u][-]0791[0-9]{7,8}[ ][0]";
 13         String regex2 = "[u][-][1][0-9]{10}[ ][1]";
 14         String regex_ = "";
 15         String regex2_ = " ";
 16         int i = 0;
 17         boolean flag = false;
 18         while (!s.equals("end")) {
 19             if (s.matches(regex)) {
 20                 for (int l = 0; l < user.size(); l++) {
 21                     if (parseInput.ParseInputNumber(s).equals(user.get(l).getNumber())) {
 22                         flag = true;
 23                     }
 24                 }
 25                 if (!flag) {
 26                     user.add(new User(parseInput.ParseInputNumber(s)));
 27                     user.get(i).setUsersRecords(new UsersRecords());
 28                     i++;
 29                     regex_ = "[t][-]0791[0-9]{7,8}[ ][0-9]{10,12}[ ]([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9])[\\\\.]([1-9]|[1-9][0-9])[\\\\.]([1-9]|[1-9][0-9])[ ]([0-1][0-9]|2[0-3])[:][0-5][0-9][:][0-5][0-9][ ]([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9])[\\\\.]([1-9]|[1-9][0-9])[\\\\.]([1-9]|[1-9][0-9])[ ]([0-1][0-9]|2[0-3])[:][0-5][0-9][:][0-5][0-9]";
 30                     regex2_ = "[t][-]([0-9]{10,12}|1[0-9]{10}[ ][0-9]{3,4})[ ](1[0-9]{10}[ ][0-9]{3,4}|[0-9]{10,12})[ ]([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9])[\\\\.]([1-9]|[1-9][0-9])[\\\\.]([1-9]|[1-9][0-9])[ ]([0-1][0-9]|2[0-3])[:][0-5][0-9][:][0-5][0-9][ ]([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9])[\\\\.]([1-9]|[1-9][0-9])[\\\\.]([1-9]|[1-9][0-9])[ ]([0-1][0-9]|2[0-3])[:][0-5][0-9][:][0-5][0-9]";
 31                 }
 32                 flag = false;
 33             } else if (s.matches(regex2)) {
 34                 for (int l = 0; l < user.size(); l++) {
 35                     if (parseInput.ParseInputNumber(s).equals(user.get(l).getNumber())) {
 36                         flag = true;
 37                     }
 38                 }
 39                 if (!flag) {
 40                     user.add(new User(parseInput.ParseInputNumber(s)));
 41                     user.get(i).setUsersRecords(new UsersRecords());
 42                     i++;
 43                 }
 44                 flag =false;
 45             } else if (s.matches("t-0791\\d{7,8} 0\\d{9,11} \\d{4}.\\d{1,2}.\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\d{4}.\\d{1,2}.\\d{1,2} \\d{2}:\\d{2}:\\d{2}")) {
 46                 if (parseInput.ParseTimeFormat(s)) {
 47                     int j = 0;
 48                     for (; j < user.size(); j++) {
 49                         if (user.get(j).getNumber().equals(parseInput.ParseInputCalNumber(s))) {
 50                             CallRecord callRecord = new CallRecord();
 51                             callRecord.setStartTime(parseInput.ParseInputStartDate(s));
 52                             callRecord.setEndTime(parseInput.ParseInputEndData(s));
 53                             callRecord.setCallingNumber(parseInput.ParseInputCalNumber(s));
 54                             callRecord.setAnswerNumber(parseInput.ParseInputAnswerNumber(s));
 55                             callRecord.setAnswerAddressAreaCode(parseInput.EndParseArea(s));
 56                             callRecord.setCallingAddressAreaCode(parseInput.StartParseArea(s));
 57                             if (parseInput.ParseNumberArea(callRecord.getAnswerNumber()) == 1) {
 58                                 user.get(j).getUsersRecords().addCallingInCityRecords(callRecord);
 59                             } else if (parseInput.ParseNumberArea(callRecord.getAnswerNumber()) == 2) {
 60                                 user.get(j).getUsersRecords().addCallingInProvinceRecords(callRecord);
 61                             } else if (parseInput.ParseNumberArea(callRecord.getAnswerNumber()) == 0) {
 62                                 user.get(j).getUsersRecords().addCallingInLandRecords(callRecord);
 63                             }
 64                         }
 65                     }
 66                 }
 67 
 68             }
 69             else if(s.matches("t-0791\\d{7,8} 1\\d{10} 0\\d{2,3} \\d{4}.\\d{1,2}.\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\d{4}.\\d{1,2}.\\d{1,2} \\d{2}:\\d{2}:\\d{2}")) {
 70                 if (parseInput.ParseTimeFormat(s)) {
 71                     int j = 0;
 72                     for (; j < user.size(); j++) {
 73                         if (user.get(j).getNumber().equals(parseInput.ParseInputCalNumber(s))) {
 74                             CallRecord callRecord = new CallRecord();
 75                             callRecord.setStartTime(parseInput.ParseInputStartDate(s));
 76                             callRecord.setEndTime(parseInput.ParseInputEndData(s));
 77                             callRecord.setCallingNumber(parseInput.ParseInputCalNumber(s));
 78                             callRecord.setAnswerNumber(parseInput.ParseInputAnswerNumber(s));
 79                             callRecord.setAnswerAddressAreaCode(parseInput.EndParseArea(s));
 80                             callRecord.setCallingAddressAreaCode(parseInput.StartParseArea(s));
 81                             if (callRecord.getAnswerAddressAreaCode().matches("0791")) {
 82                                 user.get(j).getUsersRecords().addCallingInCityRecords(callRecord);
 83                             } else if (callRecord.getAnswerAddressAreaCode().matches("[0][7][9][234567890]|[0][7][0][1]")) {
 84                                 user.get(j).getUsersRecords().addCallingInProvinceRecords(callRecord);
 85                             } else user.get(j).getUsersRecords().addCallingInLandRecords(callRecord);
 86                         }
 87                     }
 88                     int k = 0;
 89                     for (; k < user.size(); k++) {
 90                         if (user.get(k).getNumber().equals(parseInput.ParseInputAnswerNumber(s))) {
 91                             CallRecord callRecord = new CallRecord();
 92                             callRecord.setStartTime(parseInput.ParseInputStartDate(s));
 93                             callRecord.setEndTime(parseInput.ParseInputEndData(s));
 94                             callRecord.setCallingNumber(parseInput.ParseInputCalNumber(s));
 95                             callRecord.setAnswerNumber(parseInput.ParseInputAnswerNumber(s));
 96                             callRecord.setAnswerAddressAreaCode(parseInput.EndParseArea(s));
 97                             callRecord.setCallingAddressAreaCode(parseInput.StartParseArea(s));
 98                             if (callRecord.getAnswerAddressAreaCode().matches("0791")) {
 99                                 user.get(k).getUsersRecords().addAnswerInCityRecords(callRecord);
100                             } else if (callRecord.getAnswerAddressAreaCode().matches("[0][7][9][234567890]|[0][7][0][1]")) {
101                                 user.get(k).getUsersRecords().addAnswerInProvinceRecords(callRecord);
102                             } else user.get(k).getUsersRecords().addAnswerInLandRecords(callRecord);
103                         }
104                     }
105                 }
106 
107             }
108             else if(s.matches("t-1\\d{10} 0\\d{2,3} 0\\d{9,11} \\d{4}.\\d{1,2}.\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\d{4}.\\d{1,2}.\\d{1,2} \\d{2}:\\d{2}:\\d{2}")){
109                 int j = 0;
110                 for (; j < user.size(); j++) {
111                     if (user.get(j).getNumber().equals(parseInput.ParseInputCalNumber(s))) {
112                         CallRecord callRecord = new CallRecord();
113                         callRecord.setStartTime(parseInput.ParseInputStartDate(s));
114                         callRecord.setEndTime(parseInput.ParseInputEndData(s));
115                         callRecord.setCallingNumber(parseInput.ParseInputCalNumber(s));
116                         callRecord.setAnswerNumber(parseInput.ParseInputAnswerNumber(s));
117                         callRecord.setAnswerAddressAreaCode(parseInput.EndParseArea(s));
118                         callRecord.setCallingAddressAreaCode(parseInput.StartParseArea(s));
119                         if (callRecord.getCallingAddressAreaCode().matches("0791")){
120                             if(callRecord.getAnswerAddressAreaCode().matches("0791")){
121                                 user.get(j).getUsersRecords().addCallingInCityRecords(callRecord);
122                             }
123                             else if(callRecord.getAnswerAddressAreaCode().matches("[0][7][9][234567890]|[0][7][0][1]")){
124                                 user.get(j).getUsersRecords().addCallingInProvinceRecords(callRecord);
125                             }
126                             else user.get(j).getUsersRecords().addCallingInLandRecords(callRecord);
127                         }
128                         else if(callRecord.getCallingAddressAreaCode().matches("[0][7][9][234567890]|[0][7][0][1]")){
129                             user.get(j).getUsersRecords().addCallingProvinceRecords(callRecord);
130                         }
131                         else user.get(j).getUsersRecords().addCallingLandRecords(callRecord);
132                     }
133                 }
134             }
135             else if(s.matches("t-1\\d{10} 0\\d{2,3} 1\\d{10} 0\\d{2,3} \\d{4}.\\d{1,2}.\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\d{4}.\\d{1,2}.\\d{1,2} \\d{2}:\\d{2}:\\d{2}")){
136                 int j = 0;
137                 for (; j < user.size(); j++) {
138                     if (user.get(j).getNumber().equals(parseInput.ParseInputCalNumber(s))) {
139                         CallRecord callRecord = new CallRecord();
140                         callRecord.setStartTime(parseInput.ParseInputStartDate(s));
141                         callRecord.setEndTime(parseInput.ParseInputEndData(s));
142                         callRecord.setCallingNumber(parseInput.ParseInputCalNumber(s));
143                         callRecord.setAnswerNumber(parseInput.ParseInputAnswerNumber(s));
144                         callRecord.setAnswerAddressAreaCode(parseInput.EndParseArea(s));
145                         callRecord.setCallingAddressAreaCode(parseInput.StartParseArea(s));
146                         if (callRecord.getCallingAddressAreaCode().matches("0791")){
147                             if(callRecord.getAnswerAddressAreaCode().matches("0791")){
148                                 user.get(j).getUsersRecords().addCallingInCityRecords(callRecord);
149                             }
150                             else if(callRecord.getAnswerAddressAreaCode().matches("[0][7][9][234567890]|[0][7][0][1]")){
151                                 user.get(j).getUsersRecords().addCallingInProvinceRecords(callRecord);
152                             }
153                             else user.get(j).getUsersRecords().addCallingInLandRecords(callRecord);
154                         }
155                         else if(callRecord.getCallingAddressAreaCode().matches("[0][7][9][234567890]|[0][7][0][1]")){
156                             user.get(j).getUsersRecords().addCallingProvinceRecords(callRecord);
157                         }
158                         else user.get(j).getUsersRecords().addCallingLandRecords(callRecord);
159                     }
160                 }
161                 int k = 0;
162                 for (; k < user.size(); k++) {
163                     if (user.get(k).getNumber().equals(parseInput.ParseInputAnswerNumber(s))) {
164                         CallRecord callRecord = new CallRecord();
165                         callRecord.setStartTime(parseInput.ParseInputStartDate(s));
166                         callRecord.setEndTime(parseInput.ParseInputEndData(s));
167                         callRecord.setCallingNumber(parseInput.ParseInputCalNumber(s));
168                         callRecord.setAnswerNumber(parseInput.ParseInputAnswerNumber(s));
169                         callRecord.setAnswerAddressAreaCode(parseInput.EndParseArea(s));
170                         callRecord.setCallingAddressAreaCode(parseInput.StartParseArea(s));
171                         if (callRecord.getAnswerAddressAreaCode().matches("0791")) {
172                             user.get(k).getUsersRecords().addAnswerInCityRecords(callRecord);
173                         } else if (callRecord.getAnswerAddressAreaCode().matches("[0][7][9][234567890]|[0][7][0][1]")) {
174                             user.get(k).getUsersRecords().addAnswerInProvinceRecords(callRecord);
175                         } else user.get(k).getUsersRecords().addAnswerInLandRecords(callRecord);
176                     }
177                 }
178 
179             }
180                 s = input.nextLine();
181         }
182 
183         Collections.sort(user);
184 
185         for (i = 0;i< user.size();i++){
186             System.out.println(user.get(i).getNumber()+" "+String.format("%.1f",user.get(i).CalCost())+" "+String.format("%.1f",user.get(i).CalBalance()));
187         }
188     }
189 }
190 
191 abstract class CallChargeRule extends ChargeRule{
192     public abstract double calCost(ArrayList<CallRecord> callRecords) throws Exception;
193 
194 }
195 class CallRecord extends CommunicationRecord {
196     private Date startTime;
197     private Date endTime;
198 
199     private String callingAddressAreaCode;
200     private String answerAddressAreaCode;
201 
202     public Date getStartTime() {
203         return startTime;
204     }
205 
206     public void setStartTime(Date startTime) {
207         this.startTime = startTime;
208     }
209 
210     public Date getEndTime() {
211         return endTime;
212     }
213 
214     public void setEndTime(Date endTime) {
215         this.endTime = endTime;
216     }
217 
218     public String getCallingAddressAreaCode() {
219         return callingAddressAreaCode;
220     }
221 
222     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
223         this.callingAddressAreaCode = callingAddressAreaCode;
224     }
225 
226     public String getAnswerAddressAreaCode() {
227         return answerAddressAreaCode;
228     }
229 
230     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
231         this.answerAddressAreaCode = answerAddressAreaCode;
232     }
233 
234     public int getTimeOf() throws Exception {
235         SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
236         String start = simpleFormat.format(startTime);
237         String end = simpleFormat.format(endTime);
238         Date fromM = simpleFormat.parse(start.substring(0, 16));
239         Date toM = simpleFormat.parse(end.substring(0, 16));
240 
241         simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
242         start = simpleFormat.format(startTime);
243         end = simpleFormat.format(endTime);
244         int secondStart = Integer.parseInt(start.substring(17, 19));
245         int secondEnd = Integer.parseInt(end.substring(17, 19));
246 
247         long from = fromM.getTime();
248         long to = toM.getTime();
249         int gap = (int) ((to - from) / (1000 * 60));
250 
251         if (secondEnd > secondStart) {
252             gap++;
253         }
254 
255         if (gap > 0) {
256             return gap;
257         } else return 0;
258     }
259 }
260 abstract class ChargeMode {
261     public ArrayList<ChargeRule> getChargeRules() {
262         return chargeRules;
263     }
264 
265     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
266         this.chargeRules = chargeRules;
267     }
268 
269     private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();
270 
271     public abstract double CalCost(UsersRecords usersRecords) throws Exception;
272 
273     public abstract double getMonthlyRent();
274 }
275 abstract class ChargeRule {
276 }
277 abstract class CommunicationRecord {
278     protected String callingNumber;
279     protected String answerNumber;
280 
281     public String getCallingNumber() {
282         return callingNumber;
283     }
284 
285     public void setCallingNumber(String callingNumber) {
286         this.callingNumber = callingNumber;
287     }
288 
289     public String getAnswerNumber() {
290         return answerNumber;
291     }
292 
293     public void setAnswerNumber(String answerNumber) {
294         this.answerNumber = answerNumber;
295     }
296 }
297 class DateUtil {
298 
299     private int year;
300     private int month;
301     private int day;
302 
303     public DateUtil(){
304 
305     }
306 
307     public int getYear() {
308         return year;
309     }
310 
311     public void setYear(int year) {
312         this.year = year;
313     }
314 
315     public int getMonth() {
316         return month;
317     }
318 
319     public void setMonth(int month) {
320         this.month = month;
321     }
322 
323     public int getDay() {
324         return day;
325     }
326 
327     public void setDay(int day) {
328         this.day = day;
329     }
330 
331     public DateUtil(int year, int month, int day){
332         this.year = year;
333         this.month = month;
334         this.day = day;
335     }
336 
337     public boolean checkInputValidity(){
338         if (month > 0 && month < 13 && day > 0 && day < 32) {
339             if (isLeapYear(year)) {
340                 if ((day>29&&month==2)||(day>30&&month==4)||(day>30&&month==6)||(day>30&&month==9)||(day>30&&month==11)){
341                     return false;
342                 } else {
343                     return true;
344                 }
345             }
346             else {
347                 if ((day>28&&month==2)||(day>30&&month==4)||(day>30&&month==6)||(day>30&&month==9)||(day>30&&month==11)) {
348                     return false;
349                 } else {
350                     return true;
351                 }
352             }
353         }
354         else {
355             return false;
356         }
357     }//检测输入的年、月、日是否合法
358     public boolean isLeapYear(int year){
359         if(year%400==0){
360             return true;
361         }
362         else if(year%4==0&&year%100!=0){
363             return true;
364         }
365         else {
366             return false;
367         }
368     }//判断year是否为闰年
369 }
370 class LandingPhoneCharging extends ChargeMode{
371 
372     CallChargeRule city = new LandPhoneInCityRule();
373     CallChargeRule province = new LandPhoneInProvinceRule();
374     CallChargeRule land = new LandPhoneInLandRule();
375 
376     @Override
377     public double CalCost(UsersRecords usersRecords) throws Exception{
378         double sum = 0;
379         sum += city.calCost(usersRecords.getCallingInCityRecords());
380         sum += province.calCost(usersRecords.getCallingInProvinceRecords());
381         sum += land.calCost(usersRecords.getCallingInLandRecords());
382 
383         return sum;
384     }
385 
386     @Override
387     public double getMonthlyRent() {
388         return monthlyRent;
389     }
390 
391     private double monthlyRent = 20;
392 }
393 class LandPhoneInCityRule extends CallChargeRule{
394     @Override
395     public double calCost(ArrayList<CallRecord> callRecords)throws Exception{
396         int i = 0;
397         double sum = 0;
398         for(;i<callRecords.size();i++){
399             sum += callRecords.get(i).getTimeOf()*0.1;
400         }
401         return sum;
402     }
403 }
404 class LandPhoneInLandRule extends CallChargeRule{
405     @Override
406     public double calCost(ArrayList<CallRecord> callRecords)throws Exception {
407         int i = 0;
408         double sum = 0;
409         for(;i<callRecords.size();i++){
410             sum += callRecords.get(i).getTimeOf()*0.6;
411         }
412         return sum;
413     }
414 }
415 class LandPhoneInProvinceRule extends CallChargeRule{
416     @Override
417     public double calCost(ArrayList<CallRecord> callRecords)throws Exception {
418         int i = 0;
419         double sum = 0;
420         for(;i<callRecords.size();i++){
421             sum += callRecords.get(i).getTimeOf()*0.3;
422         }
423         return sum;
424     }
425 }
426 class MessageRecord extends CommunicationRecord{
427     private String message;
428 
429     public String getMessage() {
430         return message;
431     }
432 
433     public void setMessage(String message) {
434         this.message = message;
435     }
436 }
437 class MobilePhoneAnswerProvince extends CallChargeRule{
438     @Override
439     public double calCost(ArrayList<CallRecord> callRecords) throws Exception {
440         int i = 0;
441         double sum = 0;
442         for(;i<callRecords.size();i++){
443             sum += callRecords.get(i).getTimeOf()*0.3;
444         }
445         return sum;
446     }
447 }
448 class MobilePhoneCharging extends ChargeMode{
449     private double monthlyRent = 15;
450 
451     CallChargeRule city = new MobilePhoneCityRule();
452     CallChargeRule province = new MobilePhoneProvinceRule();
453     CallChargeRule land = new MobilePhoneLandRule();
454     CallChargeRule answer = new MobilePhoneAnswerProvince();
455     CallChargeRule province_ = new MobilePhoneProvince();
456     CallChargeRule land_ = new MobilePhoneLand();
457 
458     @Override
459     public double CalCost(UsersRecords usersRecords) throws Exception {
460         double sum = 0;
461         sum+=city.calCost(usersRecords.getCallingInCityRecords());
462         sum+=province.calCost(usersRecords.getCallingInProvinceRecords());
463         sum+=land.calCost(usersRecords.getCallingInLandRecords());
464         sum+=province_.calCost(usersRecords.getCallingProvinceRecords());
465         sum+=land_.calCost(usersRecords.getCallingLandRecords());
466         sum+=answer.calCost(usersRecords.getAnswerInLandRecords());
467         return sum;
468     }
469 
470     @Override
471     public double getMonthlyRent() {
472         return monthlyRent;
473     }
474 }
475 class MobilePhoneCityRule extends CallChargeRule{
476     @Override
477     public double calCost(ArrayList<CallRecord> callRecords) throws Exception {
478         int i = 0;
479         double sum = 0;
480         for(;i<callRecords.size();i++){
481             sum += callRecords.get(i).getTimeOf()*0.1;
482         }
483         return sum;
484     }
485 }
486 class MobilePhoneLand extends CallChargeRule{
487     @Override
488     public double calCost(ArrayList<CallRecord> callRecords) throws Exception {
489         int i = 0;
490         double sum = 0;
491         for(;i<callRecords.size();i++){
492             sum += callRecords.get(i).getTimeOf()*0.6;
493         }
494         return sum;
495     }
496 }
497 class MobilePhoneLandRule extends CallChargeRule{
498     @Override
499     public double calCost(ArrayList<CallRecord> callRecords) throws Exception {
500         int i = 0;
501         double sum = 0;
502         for(;i<callRecords.size();i++){
503             sum += callRecords.get(i).getTimeOf()*0.3;
504         }
505         return sum;
506     }
507 }
508 class MobilePhoneProvince extends CallChargeRule{
509     @Override
510     public double calCost(ArrayList<CallRecord> callRecords) throws Exception {
511         int i = 0;
512         double sum = 0;
513         for(;i<callRecords.size();i++){
514             sum += callRecords.get(i).getTimeOf()*0.3;
515         }
516         return sum;
517     }
518 }
519 class MobilePhoneProvinceRule extends CallChargeRule{
520     @Override
521     public double calCost(ArrayList<CallRecord> callRecords) throws Exception {
522         int i = 0;
523         double sum = 0;
524         for(;i<callRecords.size();i++){
525             sum += callRecords.get(i).getTimeOf()*0.2;
526         }
527         return sum;
528     }
529 }
530 class ParseInput {
531 
532     public String ParseInputNumber(String s){
533         String ss[]=s.split("-");
534         String sss[] =ss[1].split(" ");
535         return sss[0];
536     }
537 
538     public Date ParseInputStartDate(String s){
539         String ss[]=s.split("-");
540         String sss[] =ss[1].split(" ");
541         String ssss[] = sss[sss.length-4].split("\\.");
542         String time[] = sss[sss.length-3].split(":");
543         int year = Integer.parseInt(ssss[0]);
544         int month = Integer.parseInt(ssss[1]);
545         int day = Integer.parseInt(ssss[2]);
546         int hour = Integer.parseInt(time[0]);
547         int minute = Integer.parseInt(time[1]);
548         int second = Integer.parseInt(time[2]);
549         Date date = new Date(year-1900,month-1,day,hour,minute,second);
550         return date;
551     }
552 
553     public Date ParseInputEndData(String s){
554         String ss[]=s.split("-");
555         String sss[] =ss[1].split(" ");
556         String ssss[] = sss[sss.length-2].split("\\.");
557         String time[] = sss[sss.length-1].split(":");
558         int year = Integer.parseInt(ssss[0]);
559         int month = Integer.parseInt(ssss[1]);
560         int day = Integer.parseInt(ssss[2]);
561         int hour = Integer.parseInt(time[0]);
562         int minute = Integer.parseInt(time[1]);
563         int second = Integer.parseInt(time[2]);
564         Date date = new Date(year-1900,month-1,day,hour,minute,second);
565         return date;
566     }
567 
568     public String ParseInputCalNumber(String s){
569         String ss[]=s.split("-");
570         String sss[] = ss[1].split(" ");
571         return sss[0];
572     }
573 
574     public String ParseInputAnswerNumber(String s){
575         String ss[] = s.split(" ");
576         if(ss[1].length()==4||ss[1].length()==3){
577             return ss[2];
578         }
579         return ss[1];
580     }
581 
582     public int ParseNumberArea(String s){
583         String regex1 = "0791[0-9]{7,8}";
584         String regex2 = "079[023456789][0-9]{7,8}";
585         String regex3 = "0701[0-9]{7,8}";
586         if(s.matches(regex1)) {
587             return 1;
588         }
589         else if(s.matches(regex2)||s.matches(regex3)) {
590             return 2;
591         }
592         return 0;
593     }
594 
595     public String StartParseArea(String s){
596         String ss[]=s.split(" ");
597         if(ss[1].length()==4||ss[1].length()==3){
598             return ss[1];
599         }
600         else {
601             String sss[] = ss[0].split("-");
602             return sss[1].substring(0,4);
603         }
604     }
605 
606     public String EndParseArea(String s){
607         String ss[] = s.split(" ");
608         if(ss[1].length()==4||ss[1].length()==3){
609             if(ss[3].length()==4||ss[3].length()==3){
610                 return ss[3];
611             }
612             else {
613                 return ss[2].substring(0,4);
614             }
615         }
616         else {
617             if(ss[2].length()==4||ss[2].length()==3){
618                 return ss[2];
619             }
620             else {
621                 return ss[1].substring(0,4);
622             }
623         }
624     }
625 
626     public boolean ParseTimeFormat(String s){
627         String ss[]=s.split("-");
628         String sss[] =ss[1].split(" ");
629         String startDate[] = sss[sss.length-4].split("\\.");
630         String endDate[] = sss[sss.length-2].split("\\.");
631 
632 
633         DateUtil dateUtilStart = new DateUtil(Integer.parseInt(startDate[0]), Integer.parseInt(startDate[1]), Integer.parseInt(startDate[2]));
634         DateUtil dateUtilEnd = new DateUtil(Integer.parseInt(endDate[0]),Integer.parseInt(endDate[1]),Integer.parseInt(endDate[2]));
635 
636 
637         return dateUtilEnd.checkInputValidity()&&dateUtilStart.checkInputValidity();
638     }
639 }
640 class User implements Comparable<User>{
641 
642     private UsersRecords usersRecords = new UsersRecords();
643     private double balance = 100;
644     private ChargeMode chargeMode;
645     private String number;
646 
647     public User(String number){
648         this.number = number;
649         if (!number.matches("[1][0-9]{10}"))
650             chargeMode = new LandingPhoneCharging();
651         else chargeMode = new MobilePhoneCharging();
652     }
653 
654     public User() {
655 
656     }
657 
658     public double CalCost()throws Exception{
659         return chargeMode.CalCost(getUsersRecords());
660     }
661 
662     public double CalBalance()throws Exception{
663         this.balance = balance - CalCost() - chargeMode.getMonthlyRent();
664         return balance;
665     }
666 
667     public double getBalance() {
668         return balance;
669     }
670 
671     public UsersRecords getUsersRecords() {
672         return usersRecords;
673     }
674 
675     public void setUsersRecords(UsersRecords usersRecords) {
676         this.usersRecords = usersRecords;
677     }
678 
679     public ChargeMode getChargeMode() {
680         return chargeMode;
681     }
682 
683     public void setChargeMode(ChargeMode chargeMode) {
684         this.chargeMode = chargeMode;
685     }
686 
687     public String getNumber() {
688         return number;
689     }
690 
691     public void setNumber(String number) {
692         this.number = number;
693     }
694 
695     @Override
696     public int compareTo(User o) {
697         return this.getNumber().compareTo(o.getNumber());
698     }
699 }
700 
701 class UsersRecords {
702 
703     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();//市内拨打电话
704     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();//省内拨打电话
705     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();//国内拨打电话
706     private ArrayList<CallRecord> callingProvinceRecords = new ArrayList<CallRecord>();//在省内拨打电话
707     private ArrayList<CallRecord> callingLandRecords = new ArrayList<CallRecord>();//在省外拨打电话
708     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();//市内接听电话
709     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();//省内接听电话
710     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();//国内接听电话
711     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();//发出短信
712     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();//接收短信
713 
714     public ArrayList<CallRecord> getCallingInCityRecords() {
715         return callingInCityRecords;
716     }
717 
718     public ArrayList<CallRecord> getCallingInProvinceRecords() {
719         return callingInProvinceRecords;
720     }
721 
722     public ArrayList<CallRecord> getCallingInLandRecords() {
723         return callingInLandRecords;
724     }
725 
726     public ArrayList<CallRecord> getAnswerInCityRecords() {
727         return answerInCityRecords;
728     }
729 
730     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
731         return answerInProvinceRecords;
732     }
733 
734     public ArrayList<CallRecord> getAnswerInLandRecords() {
735         return answerInLandRecords;
736     }
737 
738     public ArrayList<MessageRecord> getSendMessageRecords() {
739         return sendMessageRecords;
740     }
741 
742     public ArrayList<MessageRecord> getReceiveMessageRecords() {
743         return receiveMessageRecords;
744     }
745 
746     public void addCallingInCityRecords(CallRecord callRecord){
747         callingInCityRecords.add(callRecord);
748     }
749 
750     public void addCallingInProvinceRecords(CallRecord callRecord){
751         callingInProvinceRecords.add(callRecord);
752     }
753 
754     public void addCallingInLandRecords(CallRecord callRecord){
755         callingInLandRecords.add(callRecord);
756     }
757 
758     public void addAnswerInCityRecords(CallRecord callRecord){
759         answerInCityRecords.add(callRecord);
760     }
761 
762     public void addAnswerInProvinceRecords(CallRecord callRecord){
763         answerInProvinceRecords.add(callRecord);
764     }
765 
766     public void addAnswerInLandRecords(CallRecord callRecord){
767         answerInLandRecords.add(callRecord);
768     }
769 
770     public void addSendMessageRecords(MessageRecord messageRecord){
771         sendMessageRecords.add(messageRecord);
772     }
773 
774     public void addReceiveMessageRecords(MessageRecord messageRecord){
775         receiveMessageRecords.add(messageRecord);
776     }
777 
778     public ArrayList<CallRecord> getCallingProvinceRecords() {
779         return callingProvinceRecords;
780     }
781 
782     public void addCallingProvinceRecords(CallRecord callRecord) {
783         callingProvinceRecords.add(callRecord);
784     }
785 
786     public ArrayList<CallRecord> getCallingLandRecords() {
787         return callingLandRecords;
788     }
789 
790     public void addCallingLandRecords(CallRecord callRecord) {
791         callingLandRecords.add(callRecord);
792     }
793 }
复制代码

类图如下:和上图差不多

分析:

这次作业和上次相比增加了手机号码的用户,这对正则表达式的要求会变得更加高的

并且手机用户接听电话也会收费,所以在第一题的基础之上还要加上这个。

对于第一题已经完成的也用不了多久。

实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
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三个类分别是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。

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

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

复制代码
  1 import java.util.ArrayList;
  2 import java.util.Collections;
  3 import java.util.Scanner;
  4 import java.text.SimpleDateFormat;
  5 import java.util.Date;
  6 public class Main {
  7     public static void main(String[] args)throws Exception {
  8         Scanner input = new Scanner(System.in);
  9         ArrayList<User> user = new ArrayList<>();
 10         ParseInput parseInput = new ParseInput();
 11         String s = input.nextLine();
 12         String regex = "[u][-]0791[0-9]{7,8}[ ][0]";
 13         String regex2 = "[u][-][1][0-9]{10}[ ][1]";
 14         String regex3 = "[u][-][1][0-9]{10}[ ][3]";
 15         String regex_ = "";
 16         String regex2_ = " ";
 17         int i = 0;
 18         boolean flag = false;
 19         while (!s.equals("end")) {
 20            
 21             if(s.matches(regex3)){
 22                 for (int l = 0; l < user.size(); l++) {
 23                     if (parseInput.ParseInputNumber(s).equals(user.get(l).getNumber())) {
 24                         flag = true;
 25                     }
 26                 }
 27                 if (!flag) {
 28                     user.add(new User(parseInput.ParseInputNumber(s)));
 29                     user.get(i).setUsersRecords(new UsersRecords());
 30                     i++;
 31                 }
 32                 flag =false;
 33             }
 34             //座机打座机
 35            
 36             //手机拨打座机
 37            
 38             else if(s.matches("m-1[3-9]\\d{9} 1[3-9]\\d{9} [a-z|0-9| |,|.]+")) {
 39                 int j = 0;
 40                 for (; j < user.size(); j++) {
 41                     if (user.get(j).getNumber().equals(parseInput.ParseInputCalNumber(s))) {
 42                         MessageRecord messageRecord = new MessageRecord();
 43                         String message = parseInput.getMessage(s);
 44                         int l = parseInput.getMessage(s).length();
 45                         int k = 0;
 46                         while (l>10){
 47                             messageRecord.setMessage(message.substring(k,k+10));
 48                             user.get(j).getUsersRecords().addSendMessageRecords(messageRecord);
 49                             messageRecord = new MessageRecord();
 50                             l-=10;
 51                         }
 52                         messageRecord.setMessage(message.substring(k));
 53                         user.get(j).getUsersRecords().addSendMessageRecords(messageRecord);
 54                     }
 55                 }
 56             }
 57                 s = input.nextLine();
 58         }
 59 
 60         Collections.sort(user);
 61 
 62         for (i = 0;i< user.size();i++){
 63             System.out.println(user.get(i).getNumber()+" "+String.format("%.1f",user.get(i).CalCost())+" "+String.format("%.1f",user.get(i).CalBalance()));
 64         }
 65     }
 66 }
 67 abstract class CallChargeRule extends ChargeRule{
 68     public abstract double calCost(ArrayList<CallRecord> callRecords) throws Exception;
 69 
 70 }
 71 class CallRecord extends CommunicationRecord {
 72     private Date startTime;
 73     private Date endTime;
 74 
 75     private String callingAddressAreaCode;
 76     private String answerAddressAreaCode;
 77 
 78     public Date getStartTime() {
 79         return startTime;
 80     }
 81 
 82     public void setStartTime(Date startTime) {
 83         this.startTime = startTime;
 84     }
 85 
 86     public Date getEndTime() {
 87         return endTime;
 88     }
 89 
 90     public void setEndTime(Date endTime) {
 91         this.endTime = endTime;
 92     }
 93 
 94     public String getCallingAddressAreaCode() {
 95         return callingAddressAreaCode;
 96     }
 97 
 98     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
 99         this.callingAddressAreaCode = callingAddressAreaCode;
100     }
101 
102     public String getAnswerAddressAreaCode() {
103         return answerAddressAreaCode;
104     }
105 
106     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
107         this.answerAddressAreaCode = answerAddressAreaCode;
108     }
109 
110     public int getTimeOf() throws Exception {
111         SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
112         String start = simpleFormat.format(startTime);
113         String end = simpleFormat.format(endTime);
114         Date fromM = simpleFormat.parse(start.substring(0, 16));
115         Date toM = simpleFormat.parse(end.substring(0, 16));
116 
117         simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
118         start = simpleFormat.format(startTime);
119         end = simpleFormat.format(endTime);
120         int secondStart = Integer.parseInt(start.substring(17, 19));
121         int secondEnd = Integer.parseInt(end.substring(17, 19));
122 
123         long from = fromM.getTime();
124         long to = toM.getTime();
125         int gap = (int) ((to - from) / (1000 * 60));
126 
127         if (secondEnd > secondStart) {
128             gap++;
129         }
130 
131         if (gap > 0) {
132             return gap;
133         } else return 0;
134     }
135 }
136 abstract class ChargeMode {
137     public ArrayList<ChargeRule> getChargeRules() {
138         return chargeRules;
139     }
140 
141     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
142         this.chargeRules = chargeRules;
143     }
144 
145     private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();
146 
147     public abstract double CalCost(UsersRecords usersRecords) throws Exception;
148 
149     public abstract double getMonthlyRent();
150 }
151 abstract class ChargeRule {
152 }
153 abstract class CommunicationRecord {
154     protected String callingNumber;
155     protected String answerNumber;
156 
157     public String getCallingNumber() {
158         return callingNumber;
159     }
160 
161     public void setCallingNumber(String callingNumber) {
162         this.callingNumber = callingNumber;
163     }
164 
165     public String getAnswerNumber() {
166         return answerNumber;
167     }
168 
169     public void setAnswerNumber(String answerNumber) {
170         this.answerNumber = answerNumber;
171     }
172 }
173 class DateUtil {
174 
175     private int year;
176     private int month;
177     private int day;
178 
179     public DateUtil(){
180 
181     }
182 
183     public int getYear() {
184         return year;
185     }
186 
187     public void setYear(int year) {
188         this.year = year;
189     }
190 
191     public int getMonth() {
192         return month;
193     }
194 
195     public void setMonth(int month) {
196         this.month = month;
197     }
198 
199     public int getDay() {
200         return day;
201     }
202 
203     public void setDay(int day) {
204         this.day = day;
205     }
206 
207     public DateUtil(int year, int month, int day){
208         this.year = year;
209         this.month = month;
210         this.day = day;
211     }
212 
213     public boolean checkInputValidity(){
214         if (month > 0 && month < 13 && day > 0 && day < 32) {
215             if (isLeapYear(year)) {
216                 if ((day>29&&month==2)||(day>30&&month==4)||(day>30&&month==6)||(day>30&&month==9)||(day>30&&month==11)){
217                     return false;
218                 } else {
219                     return true;
220                 }
221             }
222             else {
223                 if ((day>28&&month==2)||(day>30&&month==4)||(day>30&&month==6)||(day>30&&month==9)||(day>30&&month==11)) {
224                     return false;
225                 } else {
226                     return true;
227                 }
228             }
229         }
230         else {
231             return false;
232         }
233     }//检测输入的年、月、日是否合法
234     public boolean isLeapYear(int year){
235         if(year%400==0){
236             return true;
237         }
238         else if(year%4==0&&year%100!=0){
239             return true;
240         }
241         else {
242             return false;
243         }
244     }//判断year是否为闰年
245 }
246 class LandingPhoneCharging extends ChargeMode{
247 
248     CallChargeRule city = new LandPhoneInCityRule();
249     CallChargeRule province = new LandPhoneInProvinceRule();
250     CallChargeRule land = new LandPhoneInLandRule();
251 
252     @Override
253     public double CalCost(UsersRecords usersRecords) throws Exception{
254         double sum = 0;
255         sum += city.calCost(usersRecords.getCallingInCityRecords());
256         sum += province.calCost(usersRecords.getCallingInProvinceRecords());
257         sum += land.calCost(usersRecords.getCallingInLandRecords());
258 
259         return sum;
260     }
261 
262     @Override
263     public double getMonthlyRent() {
264         return monthlyRent;
265     }
266 
267     private double monthlyRent = 20;
268 }
269 class LandPhoneInCityRule extends CallChargeRule{
270     @Override
271     public double calCost(ArrayList<CallRecord> callRecords)throws Exception{
272         int i = 0;
273         double sum = 0;
274         for(;i<callRecords.size();i++){
275             sum += callRecords.get(i).getTimeOf()*0.1;
276         }
277         return sum;
278     }
279 }
280 class LandPhoneInLandRule extends CallChargeRule{
281     @Override
282     public double calCost(ArrayList<CallRecord> callRecords)throws Exception {
283         int i = 0;
284         double sum = 0;
285         for(;i<callRecords.size();i++){
286             sum += callRecords.get(i).getTimeOf()*0.6;
287         }
288         return sum;
289     }
290 }
291 class LandPhoneInProvinceRule extends CallChargeRule{
292     @Override
293     public double calCost(ArrayList<CallRecord> callRecords)throws Exception {
294         int i = 0;
295         double sum = 0;
296         for(;i<callRecords.size();i++){
297             sum += callRecords.get(i).getTimeOf()*0.3;
298         }
299         return sum;
300     }
301 }
302 abstract class MessageChargeRule extends ChargeRule{
303     public abstract double calCost(ArrayList<MessageRecord> messageRecords) throws Exception;
304 }
305 class MessageRecord extends CommunicationRecord{
306     private String message;
307 
308     public String getMessage() {
309         return message;
310     }
311 
312     public void setMessage(String message) {
313         this.message = message;
314     }
315 }
316 class MobilePhoneAnswerProvince extends CallChargeRule{
317     @Override
318     public double calCost(ArrayList<CallRecord> callRecords) throws Exception {
319         int i = 0;
320         double sum = 0;
321         for(;i<callRecords.size();i++){
322             sum += callRecords.get(i).getTimeOf()*0.3;
323         }
324         return sum;
325     }
326 }
327 class MobilePhoneMessageCharging extends ChargeMode{
328 
329     private double monthlyRent = 0;
330     MobilePhoneMessageRule mobilePhoneMessageRule = new MobilePhoneMessageRule();
331     @Override
332     public double CalCost(UsersRecords usersRecords) throws Exception {
333         double sum = 0;
334         sum=mobilePhoneMessageRule.calCost(usersRecords.getSendMessageRecords());
335         return sum;
336     }
337 
338     @Override
339     public double getMonthlyRent() {
340         return this.monthlyRent;
341     }
342 }
343 class MobilePhoneMessageRule extends MessageChargeRule{
344 
345     @Override
346     public double calCost(ArrayList<MessageRecord> messageRecords) throws Exception {
347         int l = messageRecords.size();
348         if(l<=3){
349             return 0.1*l;
350         }
351         else if(l>3&&l<=5){
352             return 0.3+0.2*(l-3);
353         }
354         else
355             return 0.7+0.3*(l-5);
356     }
357 }
358 
359 class ParseInput {
360 
361     public String ParseInputNumber(String s){
362         String ss[]=s.split("-");
363         String sss[] =ss[1].split(" ");
364         return sss[0];
365     }
366 
367     public Date ParseInputStartDate(String s){
368         String ss[]=s.split("-");
369         String sss[] =ss[1].split(" ");
370         String ssss[] = sss[sss.length-4].split("\\.");
371         String time[] = sss[sss.length-3].split(":");
372         int year = Integer.parseInt(ssss[0]);
373         int month = Integer.parseInt(ssss[1]);
374         int day = Integer.parseInt(ssss[2]);
375         int hour = Integer.parseInt(time[0]);
376         int minute = Integer.parseInt(time[1]);
377         int second = Integer.parseInt(time[2]);
378         Date date = new Date(year-1900,month-1,day,hour,minute,second);
379         return date;
380     }
381 
382     public Date ParseInputEndData(String s){
383         String ss[]=s.split("-");
384         String sss[] =ss[1].split(" ");
385         String ssss[] = sss[sss.length-2].split("\\.");
386         String time[] = sss[sss.length-1].split(":");
387         int year = Integer.parseInt(ssss[0]);
388         int month = Integer.parseInt(ssss[1]);
389         int day = Integer.parseInt(ssss[2]);
390         int hour = Integer.parseInt(time[0]);
391         int minute = Integer.parseInt(time[1]);
392         int second = Integer.parseInt(time[2]);
393         Date date = new Date(year-1900,month-1,day,hour,minute,second);
394         return date;
395     }
396 
397     public String ParseInputCalNumber(String s){
398         String ss[]=s.split("-");
399         String sss[] = ss[1].split(" ");
400         return sss[0];
401     }
402 
403     public String ParseInputAnswerNumber(String s){
404         String ss[] = s.split(" ");
405         if(ss[1].length()==4||ss[1].length()==3){
406             return ss[2];
407         }
408         return ss[1];
409     }
410 
411     public int ParseNumberArea(String s){
412         String regex1 = "0791[0-9]{7,8}";
413         String regex2 = "079[023456789][0-9]{7,8}";
414         String regex3 = "0701[0-9]{7,8}";
415         if(s.matches(regex1)) {
416             return 1;
417         }
418         else if(s.matches(regex2)||s.matches(regex3)) {
419             return 2;
420         }
421         return 0;
422     }
423 
424     public String StartParseArea(String s){
425         String ss[]=s.split(" ");
426         if(ss[1].length()==4||ss[1].length()==3){
427             return ss[1];
428         }
429         else {
430             String sss[] = ss[0].split("-");
431             return sss[1].substring(0,4);
432         }
433     }
434 
435     public String EndParseArea(String s){
436         String ss[] = s.split(" ");
437         if(ss[1].length()==4||ss[1].length()==3){
438             if(ss[3].length()==4||ss[3].length()==3){
439                 return ss[3];
440             }
441             else {
442                 return ss[2].substring(0,4);
443             }
444         }
445         else {
446             if(ss[2].length()==4||ss[2].length()==3){
447                 return ss[2];
448             }
449             else {
450                 return ss[1].substring(0,4);
451             }
452         }
453     }
454 
455     public boolean ParseTimeFormat(String s){
456         String ss[]=s.split("-");
457         String sss[] =ss[1].split(" ");
458         String startDate[] = sss[sss.length-4].split("\\.");
459         String endDate[] = sss[sss.length-2].split("\\.");
460 
461 
462         DateUtil dateUtilStart = new DateUtil(Integer.parseInt(startDate[0]), Integer.parseInt(startDate[1]), Integer.parseInt(startDate[2]));
463         DateUtil dateUtilEnd = new DateUtil(Integer.parseInt(endDate[0]),Integer.parseInt(endDate[1]),Integer.parseInt(endDate[2]));
464 
465 
466         return dateUtilEnd.checkInputValidity()&&dateUtilStart.checkInputValidity();
467     }
468 
469     public String getMessage(String s){
470         return s.substring(26);
471     }
472 }
473 class User implements Comparable<User>{
474 
475     private UsersRecords usersRecords = new UsersRecords();
476     private double balance = 100;
477     private ChargeMode chargeMode;
478     private String number;
479 
480     public User(String number){
481         this.number = number;
482         if (!number.matches("[1][0-9]{10}"))
483             chargeMode = new LandingPhoneCharging();
484         else chargeMode = new MobilePhoneMessageCharging();
485     }
486 
487     public User() {
488 
489     }
490 
491     public double CalCost()throws Exception{
492         return chargeMode.CalCost(getUsersRecords());
493     }
494 
495     public double CalBalance()throws Exception{
496         this.balance = balance - CalCost() - chargeMode.getMonthlyRent();
497         return balance;
498     }
499 
500     public double getBalance() {
501         return balance;
502     }
503 
504     public UsersRecords getUsersRecords() {
505         return usersRecords;
506     }
507 
508     public void setUsersRecords(UsersRecords usersRecords) {
509         this.usersRecords = usersRecords;
510     }
511 
512     public ChargeMode getChargeMode() {
513         return chargeMode;
514     }
515 
516     public void setChargeMode(ChargeMode chargeMode) {
517         this.chargeMode = chargeMode;
518     }
519 
520     public String getNumber() {
521         return number;
522     }
523 
524     public void setNumber(String number) {
525         this.number = number;
526     }
527 
528     @Override
529     public int compareTo(User o) {
530         return this.getNumber().compareTo(o.getNumber());
531     }
532 }
533 class UsersRecords {
534 
535     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();//市内拨打电话
536     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();//省内拨打电话
537     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();//国内拨打电话
538     private ArrayList<CallRecord> callingProvinceRecords = new ArrayList<CallRecord>();//在省内拨打电话
539     private ArrayList<CallRecord> callingLandRecords = new ArrayList<CallRecord>();//在省外拨打电话
540     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();//市内接听电话
541     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();//省内接听电话
542     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();//国内接听电话
543     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();//发出短信
544     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();//接收短信
545 
546     public ArrayList<CallRecord> getCallingInCityRecords() {
547         return callingInCityRecords;
548     }
549 
550     public ArrayList<CallRecord> getCallingInProvinceRecords() {
551         return callingInProvinceRecords;
552     }
553 
554     public ArrayList<CallRecord> getCallingInLandRecords() {
555         return callingInLandRecords;
556     }
557 
558     public ArrayList<CallRecord> getAnswerInCityRecords() {
559         return answerInCityRecords;
560     }
561 
562     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
563         return answerInProvinceRecords;
564     }
565 
566     public ArrayList<CallRecord> getAnswerInLandRecords() {
567         return answerInLandRecords;
568     }
569 
570     public ArrayList<MessageRecord> getSendMessageRecords() {
571         return sendMessageRecords;
572     }
573 
574     public ArrayList<MessageRecord> getReceiveMessageRecords() {
575         return receiveMessageRecords;
576     }
577 
578     public void addCallingInCityRecords(CallRecord callRecord){
579         callingInCityRecords.add(callRecord);
580     }
581 
582     public void addCallingInProvinceRecords(CallRecord callRecord){
583         callingInProvinceRecords.add(callRecord);
584     }
585 
586     public void addCallingInLandRecords(CallRecord callRecord){
587         callingInLandRecords.add(callRecord);
588     }
589 
590     public void addAnswerInCityRecords(CallRecord callRecord){
591         answerInCityRecords.add(callRecord);
592     }
593 
594     public void addAnswerInProvinceRecords(CallRecord callRecord){
595         answerInProvinceRecords.add(callRecord);
596     }
597 
598     public void addAnswerInLandRecords(CallRecord callRecord){
599         answerInLandRecords.add(callRecord);
600     }
601 
602     public void addSendMessageRecords(MessageRecord messageRecord){
603         sendMessageRecords.add(messageRecord);
604     }
605 
606     public void addReceiveMessageRecords(MessageRecord messageRecord){
607         receiveMessageRecords.add(messageRecord);
608     }
609 
610     public ArrayList<CallRecord> getCallingProvinceRecords() {
611         return callingProvinceRecords;
612     }
613 
614     public void addCallingProvinceRecords(CallRecord callRecord) {
615         callingProvinceRecords.add(callRecord);
616     }
617 
618     public ArrayList<CallRecord> getCallingLandRecords() {
619         return callingLandRecords;
620     }
621 
622     public void addCallingLandRecords(CallRecord callRecord) {
623         callingLandRecords.add(callRecord);
624     }
625 }
复制代码

 

类图与上图一样

分析:

这次只考察短信计费,所以这次的难点只有正则表达式。然后这次对代码长度进行了限制

所以需要对之前的代码进行删改

 

踩坑心得:

1.正则表达式在这三道题中有很大的作用,非常重要。

2.类的设计的完整性。

3.整个代码的耦合性。

 

改进建议:

在跨月时,对于月租这个属性应该也要考虑

 

总结:

一学期的Java课程结束了,感觉自己的编码能力还有待提高。

posted @   lewino  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示