针对最近三次PTA有关移动业务资费问题总结

一.前言

  • 知识点

  1.数组的运用

  2.正则表达式的运用

  3.对象和类

  4.多态与继承

  • 题量

  PTA练习3题,虽然题数较少,但是总体较复杂,但是三个题的主体是一样的

  • 难度

  整体较难,类与类之间的调用很复杂,但是只要一开始的整体框架写好了后面两次会轻松很多

 

二.设计与分析

  • 题目集08 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 import java.text.DecimalFormat;
  2 import java.text.ParseException;
  3 import java.text.SimpleDateFormat;
  4 import java.util.Date;
  5 import java.util.Map;
  6 import java.util.Scanner;
  7 import java.util.TreeMap;
  8 import java.util.ArrayList;
  9 
 10 public class Main {
 11 
 12     public static void main(String[] args) throws ParseException {
 13         // TODO Auto-generated method stub
 14         Scanner in = new Scanner(System.in);
 15         String s = in.nextLine();
 16         TreeMap<String,User> set = new TreeMap<>();
 17         String number;
 18         User user;
 19         while(!s.equals("end")) {
 20         String str1 = "u-0791\\d{7,8}\\s[0-2]";    
 21         String str2 = "t-0791([0-9]{7,8})\\s([0-9]{10,12})\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])";
 22         String str3 = "07(9[0-9]|01)";
 23         if(s.matches(str1)) {
 24             String ss[] = s.split(" ");
 25             user = new User();
 26             number = ss[0].substring(ss[0].indexOf("-")+1);
 27             user.setNumber(number);
 28             set.put(number,user);
 29         }
 30         else if(s.matches(str2)) {
 31             String ss1 = s.substring(s.indexOf("-")+1,s.indexOf(" "));
 32             String s2 = s.substring(s.indexOf("-")+1,s.indexOf(" "));
 33             CallRecord record =  new CallRecord();
 34             record.setCallingAdressAreaCode(ss1);
 35             ss1 = s.substring(s.indexOf(" ")+1);
 36             String s3 = ss1.substring(0,ss1.indexOf(" "));
 37             record.setAnswerAdressAreaCode(ss1.substring(0,ss1.indexOf(" ")));
 38             ss1 = ss1.substring(ss1.indexOf(" ")+1);
 39             String[] ss2 = ss1.split(" ");
 40             SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss");
 41             Date startTime = m.parse(ss2[0]+" "+ss2[1]);
 42             Date endTime = m.parse(ss2[2]+" "+ss2[3]);
 43             record.setStartTime(startTime);
 44             record.setEndTime(endTime);
 45             for (Map.Entry<String, User> e : set.entrySet()) {
 46                 if(e.getKey().equals(s2)) {
 47                     if(s3.substring(0, 4).matches(str3)) {
 48                         if(s3.substring(0, 4).equals("0791")) {
 49                             e.getValue().getUserRecords().addAnswerInCityRecords(record);
 50                         }
 51                         else {
 52                             e.getValue().getUserRecords().addAnswerInProvinceRecords(record);
 53                         }
 54                     }
 55                     else {
 56                         e.getValue().getUserRecords().addAnswerInLandRecords(record);
 57                     }    
 58                 }
 59             }
 60         }
 61             s = in.nextLine();
 62         }
 63         DecimalFormat d = new DecimalFormat("###0.0#");
 64         for (Map.Entry<String, User> e : set.entrySet()) {
 65             System.out.println(e.getValue().getNumber()+" "+d.format(e.getValue().callCost())+" "+d.format(e.getValue().callBalance()));
 66         }
 67     }
 68 
 69 }
 70 
 71 abstract class CallChargeRule{
 72     public abstract double callCost (ArrayList<CallRecord> callRecords);
 73 }
 74 
 75 class CallRecord {
 76     private String callingAdressAreaCode;
 77     private String AnswerAdressAreaCode;
 78     private Date startTime;
 79     private Date endTime;
 80     
 81     public String getCallingAdressAreaCode() {
 82         return callingAdressAreaCode;
 83     }
 84     
 85     public void setCallingAdressAreaCode(String callingAdressAreaCode) {
 86         this.callingAdressAreaCode = callingAdressAreaCode;
 87     }
 88     
 89     public String getAnswerAdressAreaCode() {
 90         return AnswerAdressAreaCode;
 91     }
 92     
 93     public void setAnswerAdressAreaCode(String answerAdressAreaCode) {
 94         AnswerAdressAreaCode = answerAdressAreaCode;
 95     }
 96 
 97     public Date getStartTime() {
 98         return startTime;
 99     }
100 
101     public void setStartTime(Date startTime) {
102         this.startTime = startTime;
103     }
104 
105     public Date getEndTime() {
106         return endTime;
107     }
108 
109     public void setEndTime(Date endTime) {
110         this.endTime = endTime;
111     }
112 }
113 
114 abstract class ChargeMode {
115     private ArrayList<CallChargeRule>  chargeRules = new ArrayList<>();
116 
117     public ArrayList<CallChargeRule> getChargeRules() {
118         return chargeRules;
119     }
120 
121     public void setChargeRules(ArrayList<CallChargeRule> chargeRules) {
122         this.chargeRules = chargeRules;
123     }
124     
125     public abstract double callCost(UserRecords userRecords);
126     
127     public abstract double getMonthlyRent ();
128 }
129 
130 class CommunicateRecord {
131     protected String callingNumber;
132     protected String answerNumber;
133     
134     public String getCallingNumber() {
135         return callingNumber;
136     }
137     
138     public void setCallingNumber(String callingNumber) {
139         this.callingNumber = callingNumber;
140     }
141     
142     public String getAnswerNumber() {
143         return answerNumber;
144     }
145     
146     public void setAnswerNumber(String answerNumber) {
147         this.answerNumber = answerNumber;
148     }
149 }
150 
151 class LandlinePhoneCharging extends ChargeMode{
152     private double monthlyRent = 20;
153     @Override
154     public double callCost(UserRecords userRecords) {
155         // TODO Auto-generated method stub
156         CallChargeRule a = new LandPhoneInCityRule();
157         CallChargeRule b = new LandPhoneInProvinceRule();
158         CallChargeRule c = new LandPhoneInlandRule();
159         double callcost = a.callCost(userRecords.getAnswerInCityRecords()) + b.callCost(userRecords.getAnswerInProvinceRecords()) + c.callCost(userRecords.getAnswerInLandRecords());
160         return callcost;
161     }
162 
163     @Override
164     public double getMonthlyRent() {
165         // TODO Auto-generated method stub
166         return monthlyRent;
167     }
168     
169 }
170 
171 class LandPhoneInCityRule extends CallChargeRule{
172 
173     @Override
174     public double callCost(ArrayList<CallRecord> callRecords) {
175         // TODO Auto-generated method stub
176         double cost = 0;
177         double m;
178         for(CallRecord a : callRecords) {
179             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
180             int n = (int)m;
181             if(m-n>0.000001) {
182                 n = n+1;
183             }
184             cost += 0.1 * n;
185         }
186         return cost;
187     }
188 
189 }
190 
191 class LandPhoneInlandRule extends CallChargeRule{
192 
193     @Override
194     public double callCost(ArrayList<CallRecord> callRecords) {
195         // TODO Auto-generated method stub
196         double cost = 0;
197         double m;
198         for(CallRecord a : callRecords) {
199             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
200             int n = (int)m;
201             if(m-n>0.000001) {
202                 n = n+1;
203             }
204             cost += 0.6 * n;
205         }
206         return cost;
207     }
208 
209 }
210 
211 class LandPhoneInProvinceRule extends CallChargeRule{
212 
213     @Override
214     public double callCost(ArrayList<CallRecord> callRecords) {
215         // TODO Auto-generated method stub
216         double cost = 0;
217         double m;
218         for(CallRecord a : callRecords) {
219             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
220             int n = (int)m;
221             if(m-n>0.000001) {
222                 n = n+1;
223             }
224             cost += 0.3 * n;
225         }
226         return cost;
227     }
228 
229 }
230 
231 class User {
232      private UserRecords userRecords = new UserRecords();
233      private double balance = 100;
234      private ChargeMode chargemode = new LandlinePhoneCharging();
235      private String number;
236      
237      public double callBalance() {
238          balance = balance - (this.callCost() + chargemode.getMonthlyRent()); 
239          return balance;
240      }
241      
242      public double callCost() {
243          return chargemode.callCost(userRecords);
244      }
245      
246     public UserRecords getUserRecords() {
247         return userRecords;
248     }
249     
250     public void setUserRecords(UserRecords userRecords) {
251         this.userRecords = userRecords;
252     }
253 
254     public double getBalance() {
255         return balance;
256     }
257 
258     public ChargeMode getChargemode() {
259         return chargemode;
260     }
261 
262     public void setChargemode(ChargeMode chargemode) {
263         this.chargemode = chargemode;
264     }
265 
266     public String getNumber() {
267         return number;
268     }
269 
270     public void setNumber(String number) {
271         this.number = number;
272     }
273 
274 }
275 
276 class UserRecords {
277 
278     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
279     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
280     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
281     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
282     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
283     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
284     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
285     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
286 
287     public void addCallingInCityRecords (CallRecord callRecord) {
288         callingInCityRecords.add(callRecord);
289     }
290     
291     public void addCallingInProvinceRecords (CallRecord callRecord) {
292         callingInProvinceRecords.add(callRecord);
293     }
294     
295     public void addCallingInLandRecords (CallRecord callRecord) {
296         callingInLandRecords.add(callRecord);
297     }
298     
299     public void addAnswerInCityRecords (CallRecord answerRecord) {
300         answerInCityRecords.add(answerRecord);
301     }
302     public void addAnswerInProvinceRecords (CallRecord answerRecord) {
303         answerInProvinceRecords.add(answerRecord);
304     }
305     
306     public void addAnswerInLandRecords (CallRecord answerRecord) {
307         answerInLandRecords.add(answerRecord);
308     }
309     
310     public void addSendMessageRecords (MessageRecord sendMessageRecord) {
311         sendMessageRecords.add(sendMessageRecord);
312     }
313     
314     public void addReceiveMessageRecords (MessageRecord receiveMessageRecord) {
315         receiveMessageRecords.add(receiveMessageRecord);
316     }
317     
318     public ArrayList<CallRecord> getCallingInCityRecords() {
319         return callingInCityRecords;
320     }
321     
322     public ArrayList<CallRecord> getCallingInProvinceRecords() {
323         return callingInProvinceRecords;
324     }
325     
326     public ArrayList<CallRecord> getCallingInLandRecords() {
327         return callingInLandRecords;
328     }
329     
330     public ArrayList<CallRecord> getAnswerInCityRecords() {
331         return answerInCityRecords;
332     }
333     
334     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
335         return answerInProvinceRecords;
336     }
337     
338     public ArrayList<CallRecord> getAnswerInLandRecords() {
339         return answerInLandRecords;
340     }
341     
342     
343     public ArrayList<MessageRecord> getReceiveMessageRecords() {
344         return receiveMessageRecords;
345     }
346     
347 
348     public ArrayList<MessageRecord> getSendMessageRecords() {
349         return sendMessageRecords;
350     }
351 
352 }
353 
354 class MessageRecord extends CommunicateRecord{
355     private String message;
356 
357     public String getMessage() {
358         return message;
359     }
360 
361     public void setMessage(String message) {
362         this.message = message;
363     }
364 }

分析:首先是针对基本框架的构建,题目给了基本的类图,按照类图进行代码的书写就可以了,主要问题是需要理清楚每个类图之间的关系,包括多态的运用,在判断不同地区的电话拨打情况中话费的计算有所体现,其次就是输入格式的问题,刚开始没有注意日期时间的格式,导致在格式的测试点卡了很久,还是要多注意细节。

心得:这种题很考验自己对于每个类图的关系的梳理,如果题目没有给基本的类图的话,难度就大大的增加了,需要自己去思考对于不同的功能需要什么样的类去实现,对于不同的类之间继承多态也很难弄清,根据类图写的话就轻松很多了,输入格式运用正则去判断的话会舒心很多。

 

  • 题目集09 7-1 电信计费系列2-手机+座机计费

实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
1、针对市内座机用户采用的计费方式(与电信计费系列1内容相同):
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
假设本市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
2、针对手机用户采用实时计费方式:
月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟;
注:被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3 10:05:11

输入:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,含手机和座机用户
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题在电信计费系列1基础上增加类型1-手机实时计费。
手机设置0或者座机设置成1,此种错误可不做判断。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
输入格式增加手机接打电话以及收发短信的格式,手机接打电话的信息除了号码之外需要额外记录拨打/接听的地点的区号,比如:
座机打手机:
t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:
t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11

注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。

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

题目源码:

  1 import java.text.DecimalFormat;
  2 import java.text.ParseException;
  3 import java.text.SimpleDateFormat;
  4 import java.util.Date;
  5 import java.util.Map;
  6 import java.util.Scanner;
  7 import java.util.TreeMap;
  8 import java.util.ArrayList;
  9 
 10 public class Main {
 11 
 12     public static void main(String[] args) throws ParseException {
 13         // TODO Auto-generated method stub
 14          Scanner in = new Scanner(System.in);
 15          String s = in.nextLine();
 16          String str1 = "u-0791\\d{7,8}\\s0";    //注册座机用户
 17          String str2 = "t-0791([0-9]{7,8})\\s0([0-9]{9,11})\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])";
 18          //座机打座机的记录
 19          String str3 = "07(9[0-9]|01)";//判断地区
 20          String str4 = "u-1\\d{10}\\s1";//注册手机用户。手机和座机统一在南昌开户
 21          String str5 = "t-0\\d{9,11}\\s1\\d{10}\\s0\\d{2,3}\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])";
 22          //座机打手机
 23          String str6 = "t-1\\d{10}\\s0\\d{2,3}\\s1\\d{10}\\s0\\d{2,3}\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])";
 24          //手机打手机
 25          String str7 = "t-1\\d{10}\\s0\\d{2,3}\\s0([0-9]{9,11})\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])";
 26          //手机打座机
 27         TreeMap<String,User> set = new TreeMap<>();
 28         String number;
 29         User user;
 30         int k = 0;
 31         while(!s.equals("end")) {
 32             if(k==0) {
 33                 while(!s.equals("end")&&s.charAt(0)=='u') {
 34                     if(s.matches(str1)) {
 35                         String ss[] = s.split(" ");
 36                         user = new User();
 37                         number = ss[0].substring(ss[0].indexOf("-")+1);
 38                         user.setNumber(number);
 39                         set.put(number,user);
 40                     }
 41                     else if(s.matches(str4)) {
 42                         String ss[] = s.split(" ");
 43                         user = new User();
 44                         number = ss[0].substring(ss[0].indexOf("-")+1);
 45                         user.setNumber(number);
 46                         double a = 15;
 47                         user.getChargemode().setMonthlyRent(a);
 48                         set.put(number,user);
 49                     }
 50                 s = in.nextLine();
 51                 if(s.charAt(0)=='t') {
 52                     k = 1;
 53                 }
 54             }
 55         }
 56             
 57         while(!s.equals("end")&&s.charAt(0)=='t') {
 58             if(s.matches(str2)) {//座机打座机
 59                 //t-079186300001 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:25
 60                 CallRecord record =  new CallRecord();
 61                 String ss[] = s.split(" ");
 62                 String s1 = ss[0].substring(ss[0].indexOf("-")+1);
 63                 SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss");
 64                 Date startTime = m.parse(ss[2]+" "+ss[3]);
 65                 Date endTime = m.parse(ss[4]+" "+ss[5]);
 66                 record.setStartTime(startTime);
 67                 record.setEndTime(endTime);
 68                 record.setCallingAdressAreaCode(s1);
 69                 record.setAnswerAdressAreaCode(ss[1]);
 70                 String s2 = ss[1].substring(0,4);
 71                 for (Map.Entry<String, User> e : set.entrySet()) {
 72                     if(e.getKey().equals(s1)) {
 73                         if(s2.matches(str3)) {
 74                             if(s2.equals("0791")) {
 75                                 e.getValue().getUserRecords().addCallingInCityRecords(record);
 76                             }
 77                             else {
 78                                 e.getValue().getUserRecords().addCallingInProvinceRecords(record);;
 79                             }
 80                         }
 81                         else {
 82                             e.getValue().getUserRecords().addCallingInLandRecords(record);
 83                         }    
 84                     }
 85                 }
 86             }
 87             else if(s.matches(str5)) {//座机打手机
 88                 //t-079186300001 13986300001 0371 2022.1.3 10:00:25 2022.1.3 10:05:05
 89                 CallRecord record =  new CallRecord();
 90                 String ss[] = s.split(" ");
 91                 String s1 = ss[0].substring(ss[0].indexOf("-")+1);
 92                 SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss");
 93                 Date startTime = m.parse(ss[3]+" "+ss[4]);
 94                 Date endTime = m.parse(ss[5]+" "+ss[6]);
 95                 record.setStartTime(startTime);
 96                 record.setEndTime(endTime);
 97                 record.setCallingAdressAreaCode(s1);
 98                 record.setAnswerAdressAreaCode(ss[2]);
 99                 for (Map.Entry<String, User> e : set.entrySet()) {
100                     if(e.getKey().equals(s1)) {
101                         if(ss[2].matches(str3)) {
102                             if(ss[2].equals("0791")) {
103                                 e.getValue().getUserRecords().addCallingInCityRecords(record);
104                             }
105                             else {
106                                 e.getValue().getUserRecords().addCallingInProvinceRecords(record);;
107                             }
108                         }
109                         else {
110                             e.getValue().getUserRecords().addCallingInLandRecords(record);
111                         }    
112                     }
113                 }
114                 for (Map.Entry<String, User> e : set.entrySet()) {
115                     if(e.getKey().equals(ss[1])) {
116                         if(ss[2].matches(str3)) {
117                             if(ss[2].equals("0791")) {
118                                 if(ss[3].matches(s1)) {
119                                     e.getValue().getUserRecords().addAnswerInCityRecords(record);
120                                 }
121                                 else {
122                                     e.getValue().getUserRecords().addAnswerInProvinceRecords(record);
123                                 }
124                             }
125                             else {
126                                 e.getValue().getUserRecords().addAnswerInLandRecords(record);
127                             }
128                         }
129                         else {
130                             e.getValue().getUserRecords().addAnswerInLandRecords(record);
131                         }    
132                     }
133                 }//录入拨打号码的信息
134             }
135             else if(s.matches(str6)) {//手机打手机
136                 //t-18907910010 0791 13986300001 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
137                 CallRecord record =  new CallRecord();
138                 String ss[] = s.split(" ");
139                 String s1 = ss[0].substring(ss[0].indexOf("-")+1);
140                 SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss");
141                 Date startTime = m.parse(ss[4]+" "+ss[5]);
142                 Date endTime = m.parse(ss[6]+" "+ss[7]);
143                 record.setStartTime(startTime);
144                 record.setEndTime(endTime);
145                 record.setCallingAdressAreaCode(s1);
146                 record.setAnswerAdressAreaCode(ss[2]);
147                 for (Map.Entry<String, User> e : set.entrySet()) {
148                     if(e.getKey().equals(s1)) {
149                         if(ss[1].matches(str3)) {
150                             if(ss[1].equals("0791")) {
151                                 if(ss[3].matches(s1)) {
152                                     if(ss[3].equals("0791")) {
153                                         e.getValue().getUserRecords().addPhonecallingInCityInCityRecords(record);;
154                                     }
155                                     else {
156                                         e.getValue().getUserRecords().addPhonecallingInCityInProvinceRecords(record);
157                                     }
158                                 }
159                                 else {
160                                     e.getValue().getUserRecords().addPhonecallingInCityInLandRecords(record);;
161                                 }
162                             }
163                             else {
164                                 e.getValue().getUserRecords().addPhonecallingInProvinceRecords(record);
165                             }
166                         }
167                         else {
168                             e.getValue().getUserRecords().addPhonecallingInLandOtherRecords(record);
169                         }    
170                     }
171                 }//录入拨打号码的信息
172                 for (Map.Entry<String, User> e : set.entrySet()) {
173                     if(e.getKey().equals(ss[2])) {
174                         if(ss[3].matches(s1)) {
175                             if(ss[3].equals("0791")) {
176                                 e.getValue().getUserRecords().addAnswerInCityRecords(record);
177                             }
178                             else {
179                                 e.getValue().getUserRecords().addAnswerInProvinceRecords(record);
180                             }
181                             
182                         }
183                         else {
184                             e.getValue().getUserRecords().addAnswerInLandRecords(record);
185                         }
186                     }
187                 }
188             }
189             else if(s.matches(str7)) {//手机打座机
190                 //t-13986300001 0371 079186300001 2022.1.3 23:50:25 2022.1.4 00:05:11
191                 CallRecord record =  new CallRecord();
192                 String ss[] = s.split(" ");
193                 String s1 = ss[0].substring(ss[0].indexOf("-")+1);
194                 SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss");
195                 Date startTime = m.parse(ss[3]+" "+ss[4]);
196                 Date endTime = m.parse(ss[5]+" "+ss[6]);
197                 record.setStartTime(startTime);
198                 record.setEndTime(endTime);
199                 record.setCallingAdressAreaCode(s1);
200                 record.setAnswerAdressAreaCode(ss[2]);
201                 String s2 = ss[2].substring(0,4);
202                 for (Map.Entry<String, User> e : set.entrySet()) {
203                     if(e.getKey().equals(s1)) {
204                         if(ss[1].matches(str3)) {
205                             if(ss[1].equals("0791")) {
206                                 if(s2.matches(str3)) {
207                                     if(s2.equals("0791")) {
208                                         e.getValue().getUserRecords().addPhonecallingInCityInCityRecords(record);;
209                                     }
210                                     else {
211                                         e.getValue().getUserRecords().addPhonecallingInCityInProvinceRecords(record);
212                                     }
213                                 }
214                                 else {
215                                     e.getValue().getUserRecords().addPhonecallingInCityInLandRecords(record);;
216                                 }
217                             }
218                             else {
219                                 e.getValue().getUserRecords().addPhonecallingInProvinceRecords(record);
220                             }
221                         }
222                         else {
223                             e.getValue().getUserRecords().addPhonecallingInLandOtherRecords(record);
224                         }    
225                     }
226                 }//录入拨打号码的信息
227             }
228             s = in.nextLine();
229         }
230         
231         if(!s.equals("end")) {
232             s = in.nextLine();
233         }
234     }
235         DecimalFormat d = new DecimalFormat("###0.0#");
236         for (Map.Entry<String, User> e : set.entrySet()) {
237             System.out.println(e.getValue().getNumber()+" "+d.format(e.getValue().callCost())+" "+d.format(e.getValue().callBalance()));
238         }
239     }
240 
241 }
242 abstract class AnswerChargeRule {
243     public abstract double AnswerCost (ArrayList<CallRecord> callRecords);
244 
245 }
246 class AnswerInLandRule extends AnswerChargeRule{
247 
248     @Override
249     public double AnswerCost(ArrayList<CallRecord> answerRecords) {
250         // TODO Auto-generated method stub
251         double cost = 0;
252         double m;
253         for(CallRecord a : answerRecords) {
254             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
255             int n = (int)m;
256             if(m-n>0.000001) {
257                 n = n+1;
258             }
259             cost += 0.3 * n;
260         }
261         return cost;
262     }
263 
264 }
265 abstract class CallChargeRule{
266     
267     private double price;
268     
269     public abstract double callCost (ArrayList<CallRecord> callRecords);
270     
271     public double getPrice() {
272         return price;
273     }
274     
275     public void setPrice(double price) {
276         this.price = price;
277     }
278 }
279 class CallRecord {
280     private String callingAdressAreaCode;
281     private String AnswerAdressAreaCode;
282     private Date startTime;
283     private Date endTime;
284     
285     public String getCallingAdressAreaCode() {
286         return callingAdressAreaCode;
287     }
288     
289     public void setCallingAdressAreaCode(String callingAdressAreaCode) {
290         this.callingAdressAreaCode = callingAdressAreaCode;
291     }
292     
293     public String getAnswerAdressAreaCode() {
294         return AnswerAdressAreaCode;
295     }
296     
297     public void setAnswerAdressAreaCode(String answerAdressAreaCode) {
298         AnswerAdressAreaCode = answerAdressAreaCode;
299     }
300 
301     public Date getStartTime() {
302         return startTime;
303     }
304 
305     public void setStartTime(Date startTime) {
306         this.startTime = startTime;
307     }
308 
309     public Date getEndTime() {
310         return endTime;
311     }
312 
313     public void setEndTime(Date endTime) {
314         this.endTime = endTime;
315     }
316 }
317 abstract class ChargeMode {
318     private ArrayList<CallChargeRule>  chargeRules = new ArrayList<>();
319     private ArrayList<AnswerChargeRule> answerule = new ArrayList<>();
320     
321     public ArrayList<CallChargeRule> getChargeRules() {
322         return chargeRules;
323     }
324 
325     public void setChargeRules(ArrayList<CallChargeRule> chargeRules) {
326         this.chargeRules = chargeRules;
327     }
328     
329     public abstract double callCost(UserRecords userRecords);
330     
331     public abstract double getMonthlyRent ();
332 
333     public abstract void setMonthlyRent(double a);
334 
335     public ArrayList<AnswerChargeRule> getAnswerule() {
336         return answerule;
337     }
338 
339     public void setAnswerule(ArrayList<AnswerChargeRule> answerule) {
340         this.answerule = answerule;
341     }
342 }
343 class CommunicateRecord {
344     protected String callingNumber;
345     protected String answerNumber;
346     
347     public String getCallingNumber() {
348         return callingNumber;
349     }
350     
351     public void setCallingNumber(String callingNumber) {
352         this.callingNumber = callingNumber;
353     }
354     
355     public String getAnswerNumber() {
356         return answerNumber;
357     }
358     
359     public void setAnswerNumber(String answerNumber) {
360         this.answerNumber = answerNumber;
361     }
362 }
363 class LandlinePhoneCharging extends ChargeMode{
364     private double monthlyRent = 20;
365     @Override
366     public double callCost(UserRecords userRecords) {
367         // TODO Auto-generated method stub
368         CallChargeRule a = new LandPhoneInCityRule();
369         CallChargeRule b = new LandPhoneInProvinceRule();
370         CallChargeRule c = new LandPhoneInlandRule();
371 
372         double callcost = a.callCost(userRecords.getCallingInCityRecords()) + b.callCost(userRecords.getCallingInProvinceRecords()) + c.callCost(userRecords.getCallingInLandRecords());
373         return callcost;
374     }
375 
376     @Override
377     public double getMonthlyRent() {
378         // TODO Auto-generated method stub
379         return monthlyRent;
380     }
381     
382     public void setMonthlyRent(double monthlyRent) {
383         this.monthlyRent = monthlyRent;
384     }
385 }
386 class LandPhoneInCityRule extends CallChargeRule{
387     
388     @Override
389     public double callCost(ArrayList<CallRecord> callRecords) {
390         // TODO Auto-generated method stub
391         double cost = 0;
392         double m;
393         for(CallRecord a : callRecords) {
394             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
395             int n = (int)m;
396             if(m-n>0.000001) {
397                 n = n+1;
398             }
399             cost += 0.1 * n;
400         }
401         return cost;
402     }
403     
404 
405 }
406 class LandPhoneInlandRule extends CallChargeRule{
407 
408     @Override
409     public double callCost(ArrayList<CallRecord> callRecords) {
410         // TODO Auto-generated method stub
411         double cost = 0;
412         double m;
413         for(CallRecord a : callRecords) {
414             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
415             int n = (int)m;
416             if(m-n>0.000001) {
417                 n = n+1;
418             }
419             cost += 0.6 * n;
420         }
421         return cost;
422     }
423 
424 }
425 class LandPhoneInProvinceRule extends CallChargeRule{
426 
427     @Override
428     public double callCost(ArrayList<CallRecord> callRecords) {
429         // TODO Auto-generated method stub
430         double cost = 0;
431         double m;
432         for(CallRecord a : callRecords) {
433             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
434             int n = (int)m;
435             if(m-n>0.000001) {
436                 n = n+1;
437             }
438             cost += 0.3 * n;
439         }
440         return cost;
441     }
442 
443 }
444 class MessageRecord extends CommunicateRecord{
445     private String message;
446 
447     public String getMessage() {
448         return message;
449     }
450 
451     public void setMessage(String message) {
452         this.message = message;
453     }
454 }
455 class PhoneCharging extends ChargeMode{
456     private double monthlyRent = 15;
457     @Override
458     public double callCost(UserRecords userRecords) {
459         // TODO Auto-generated method stub
460         double cost = 0;
461         CallChargeRule a = new PhoneInCittCallInLand();
462         CallChargeRule b = new PhoneInCityCallInCity();
463         CallChargeRule c = new PhoneInCityCallInProvince();
464         CallChargeRule d = new PhoneInLandCallOther();
465         CallChargeRule e = new PhoneInProvinceCallOther();
466         AnswerChargeRule f = new AnswerInLandRule();
467         cost += f.AnswerCost(userRecords.getAnswerInLandRecords()) + a.callCost(userRecords.getPhonecallingInCityInLandRecords());
468         cost += b.callCost(userRecords.getPhonecallingInCityInCityRecords()) + c.callCost(userRecords.getPhonecallingInCityInProvinceRecords());
469         cost += d.callCost(userRecords.getPhonecallingInLandOtherRecords()) + e.callCost(userRecords.getPhonecallingInProvinceRecords());
470         return cost;
471     }
472 
473     @Override
474     public double getMonthlyRent() {
475         // TODO Auto-generated method stub
476         return monthlyRent;
477     }
478 
479     @Override
480     public void setMonthlyRent(double monthlyRent) {
481         // TODO Auto-generated method stub
482         this.monthlyRent = monthlyRent;
483     }
484 
485 }
486 class PhoneInCittCallInLand extends CallChargeRule{
487     
488     @Override
489     public double callCost(ArrayList<CallRecord> callRecords) {
490         // TODO Auto-generated method stub
491         double cost = 0;
492         double m;
493         for(CallRecord a : callRecords) {
494             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
495             int n = (int)m;
496             if(m-n>0.000001) {
497                 n = n+1;
498             }
499             cost += 0.3 * n;
500         }
501         return cost;
502     }
503 }
504 class PhoneInCityCallInCity extends CallChargeRule{
505     
506     @Override
507     public double callCost(ArrayList<CallRecord> callRecords) {
508         // TODO Auto-generated method stub
509         double cost = 0;
510         double m;
511         for(CallRecord a : callRecords) {
512             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
513             int n = (int)m;
514             if(m-n>0.000001) {
515                 n = n+1;
516             }
517             cost += 0.1 * n;
518         }
519         return cost;
520     }
521 }
522 class PhoneInCityCallInProvince extends CallChargeRule{
523     
524     @Override
525     public double callCost(ArrayList<CallRecord> callRecords) {
526         // TODO Auto-generated method stub
527         double cost = 0;
528         double m;
529         for(CallRecord a : callRecords) {
530             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
531             int n = (int)m;
532             if(m-n>0.000001) {
533                 n = n+1;
534             }
535             cost += 0.2 * n;
536         }
537         return cost;
538     }
539 }
540 class PhoneInLandCallOther  extends CallChargeRule{
541     
542     @Override
543     public double callCost(ArrayList<CallRecord> callRecords) {
544         // TODO Auto-generated method stub
545         double cost = 0;
546         double m;
547         for(CallRecord a : callRecords) {
548             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
549             int n = (int)m;
550             if(m-n>0.000001) {
551                 n = n+1;
552             }
553             cost += 0.6 * n;
554         }
555         return cost;
556     }
557 }
558 class PhoneInProvinceCallOther extends CallChargeRule{
559     
560     @Override
561     public double callCost(ArrayList<CallRecord> callRecords) {
562         // TODO Auto-generated method stub
563         double cost = 0;
564         double m;
565         for(CallRecord a : callRecords) {
566             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
567             int n = (int)m;
568             if(m-n>0.000001) {
569                 n = n+1;
570             }
571             cost += 0.3 * n;
572         }
573         return cost;
574     }
575 }
576 class User {
577      private UserRecords userRecords = new UserRecords();
578      private double balance = 100;
579      private ChargeMode chargemode1 = new LandlinePhoneCharging();
580      private ChargeMode chargemode2 = new PhoneCharging();
581      private String number;
582      
583      public double callBalance() {
584          if(number.charAt(0)=='1') {
585              balance = balance - (this.callCost() + chargemode2.getMonthlyRent());  
586          }
587          else {
588              balance = balance - (this.callCost() + chargemode1.getMonthlyRent()); 
589          }
590          return balance;
591      }
592      
593      public double callCost() {
594          if(number.charAt(0)=='1') {
595              return chargemode2.callCost(userRecords);
596 
597          }
598          else {
599              return chargemode1.callCost(userRecords);
600 
601          }
602      }
603      
604     public UserRecords getUserRecords() {
605         return userRecords;
606     }
607     
608     public void setUserRecords(UserRecords userRecords) {
609         this.userRecords = userRecords;
610     }
611 
612     public double getBalance() {
613         return balance;
614     }
615 
616     public ChargeMode getChargemode() {
617          if(number.charAt(0)=='1') {
618              return chargemode2; 
619          }
620          else {
621              return chargemode1;
622          }
623         
624     }
625 
626     public void setChargemode(ChargeMode chargemode) {
627         if(number.charAt(0)=='1') {
628             this.chargemode2 = chargemode; 
629          }
630          else {
631              this.chargemode1 = chargemode;
632          }
633     }
634 
635     public String getNumber() {
636         return number;
637     }
638 
639     public void setNumber(String number) {
640         this.number = number;
641     }
642 
643 }
644 class UserRecords {
645 
646     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
647     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
648     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
649     
650     private ArrayList<CallRecord> PhonecallingInLandOtherRecords = new ArrayList<CallRecord>();
651     private ArrayList<CallRecord> PhonecallingInCityInLandRecords = new ArrayList<CallRecord>();
652     private ArrayList<CallRecord> PhonecallingInProvinceRecords = new ArrayList<CallRecord>();
653     private ArrayList<CallRecord> PhonecallingInCityInProvinceRecords = new ArrayList<CallRecord>();
654     private ArrayList<CallRecord> PhonecallingInCityInCityRecords = new ArrayList<CallRecord>();
655 
656     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
657     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
658     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
659     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
660     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
661 
662     public void addCallingInCityRecords (CallRecord callRecord) {
663         callingInCityRecords.add(callRecord);
664     }
665     
666     public void addCallingInProvinceRecords (CallRecord callRecord) {
667         callingInProvinceRecords.add(callRecord);
668     }
669     
670     public void addCallingInLandRecords (CallRecord callRecord) {
671         callingInLandRecords.add(callRecord);
672     }
673     
674     public void addAnswerInCityRecords (CallRecord answerRecord) {
675         answerInCityRecords.add(answerRecord);
676     }
677     public void addAnswerInProvinceRecords (CallRecord answerRecord) {
678         answerInProvinceRecords.add(answerRecord);
679     }
680     
681     public void addAnswerInLandRecords (CallRecord answerRecord) {
682         answerInLandRecords.add(answerRecord);
683     }
684     
685     public void addSendMessageRecords (MessageRecord sendMessageRecord) {
686         sendMessageRecords.add(sendMessageRecord);
687     }
688     
689     public void addReceiveMessageRecords (MessageRecord receiveMessageRecord) {
690         receiveMessageRecords.add(receiveMessageRecord);
691     }
692     
693     public ArrayList<CallRecord> getCallingInCityRecords() {
694         return callingInCityRecords;
695     }
696     
697     public ArrayList<CallRecord> getCallingInProvinceRecords() {
698         return callingInProvinceRecords;
699     }
700     
701     public ArrayList<CallRecord> getCallingInLandRecords() {
702         return callingInLandRecords;
703     }
704     
705     public ArrayList<CallRecord> getAnswerInCityRecords() {
706         return answerInCityRecords;
707     }
708     
709     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
710         return answerInProvinceRecords;
711     }
712     
713     public ArrayList<CallRecord> getAnswerInLandRecords() {
714         return answerInLandRecords;
715     }
716     
717     
718     public ArrayList<MessageRecord> getReceiveMessageRecords() {
719         return receiveMessageRecords;
720     }
721     
722 
723     public ArrayList<MessageRecord> getSendMessageRecords() {
724         return sendMessageRecords;
725     }
726 
727     public ArrayList<CallRecord> getPhonecallingInLandOtherRecords() {
728         return PhonecallingInLandOtherRecords;
729     }
730 
731     public void addPhonecallingInLandOtherRecords(CallRecord phonecallingInLandOtherRecords) {
732         PhonecallingInLandOtherRecords.add(phonecallingInLandOtherRecords);
733     }
734 
735     public ArrayList<CallRecord> getPhonecallingInCityInLandRecords() {
736         return PhonecallingInCityInLandRecords;
737     }
738 
739     public void addPhonecallingInCityInLandRecords(CallRecord phonecallingInCityInLandRecords) {
740         PhonecallingInCityInLandRecords.add(phonecallingInCityInLandRecords);
741     }
742 
743     public ArrayList<CallRecord> getPhonecallingInCityInProvinceRecords() {
744         return PhonecallingInCityInProvinceRecords;
745     }
746 
747     public void addPhonecallingInCityInProvinceRecords(CallRecord phonecallingInCityInProvinceRecords) {
748         PhonecallingInCityInProvinceRecords.add(phonecallingInCityInProvinceRecords);
749     }
750 
751     public ArrayList<CallRecord> getPhonecallingInCityInCityRecords() {
752         return PhonecallingInCityInCityRecords;
753     }
754 
755     public void addPhonecallingInCityInCityRecords(CallRecord phonecallingInCityInCityRecords) {
756         PhonecallingInCityInCityRecords.add(phonecallingInCityInCityRecords);
757     }
758 
759     public ArrayList<CallRecord> getPhonecallingInProvinceRecords() {
760         return PhonecallingInProvinceRecords;
761     }
762 
763     public void addPhonecallingInProvinceRecords(CallRecord phonecallingInProvinceRecords) {
764         PhonecallingInProvinceRecords.add(phonecallingInProvinceRecords);
765     }
766 
767 }

 

分析:在第一题的基础上增加了新的种类的用户,使得计费的过程更加复杂,主要是完善所给类图中实现的功能,在Main判断好拨打的类型,地区等,增加到相应的ArrayList对应的通话记录再进行计算话费的计算,总体上有第一题的基础上难度主要在判断通话记录方面,运用正则来判断地区号是个很好的选择

心得:需要一个个的分析拨打地区和接收地区,在分类方面做了很多的功夫,也一直调式看自己分类部分的代码是否有错误,真的很需要头脑清楚的时候去写,不然很容易混乱

  • 题目集10 7-1 电信计费系列3-短信计费

实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
1、接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。
2、如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。

输入:
输入信息包括两种类型
1、逐行输入南昌市手机用户开户的信息,每行一个用户。
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐 3-手机短信计费)
例如:u-13305862264 3
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题只针对类型3-手机短信计费。
2、逐行输入本月某些用户的短信信息,短信的格式:
m-主叫号码,接收号码,短信内容 (短信内容只能由数字、字母、空格、英文逗号、英文句号组成)
m-18907910010 13305862264 welcome to jiangxi.
m-13305862264 18907910010 thank you.

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

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

源码:

  1 import java.text.DecimalFormat;
  2 import java.text.ParseException;
  3 import java.text.SimpleDateFormat;
  4 import java.util.Date;
  5 import java.util.Map;
  6 import java.util.Scanner;
  7 import java.util.TreeMap;
  8 import java.util.ArrayList;
  9 import java.util.Date;
 10 public class Main {
 11 
 12     public static void main(String[] args) throws ParseException {
 13         // TODO Auto-generated method stub
 14          Scanner in = new Scanner(System.in);
 15          String s = in.nextLine();
 16          String numberjudge = "[u][-]1[3-9]\\d{9}[ ][3]"; 
 17          String messagejudge = "m-1[3-9]\\d{9} 1[3-9]\\d{9} [a-z|0-9| |,|.]++";
 18         TreeMap<String,User> set = new TreeMap<>();
 19         String number;
 20         User user;
 21         int k = 0;
 22         while(!s.equals("end")) {
 23             if(k==0) {
 24                 while(!s.equals("end")&&s.charAt(0)=='u') {
 25                     if(s.matches(numberjudge)) {
 26                         String ss[] = s.split(" ");
 27                         user = new User();
 28                         number = ss[0].substring(ss[0].indexOf("-")+1);
 29                         user.setNumber(number);
 30                         set.put(number,user);
 31                     }
 32                 s = in.nextLine();
 33                 if(s.charAt(0)=='m') {
 34                     k = 1;
 35                 }
 36             }
 37         }
 38             
 39         while(!s.equals("end")&&s.charAt(0)=='m') {
 40             if(s.matches(messagejudge)) {
 41                 //m-18907910010 13305862264 bb,bbbb
 42                 MessageRecord record =  new MessageRecord();
 43                 String s1 = s.substring(0,s.indexOf(" "));
 44                 String ss1 = s1.substring(s1.indexOf("-")+1);//发短信的电话号码
 45                 String s2 = s.substring(s.indexOf(" ")+1);
 46                 String ss2 = s2.substring(0,s2.indexOf(" ")-1);//收短信的号码
 47                 String message = s2.substring(s2.indexOf(" ")+1);
 48                 for (Map.Entry<String, User> e : set.entrySet()) {
 49                     if(e.getKey().equals(ss1)) {
 50                         record.setCallingNumber(ss1);
 51                         record.setAnswerNumber(ss2);
 52                         record.setMessage(message);
 53                         e.getValue().getUserRecords().addSendMessageRecords(record);
 54                     }
 55                 }
 56             }
 57             s = in.nextLine();
 58         }
 59         
 60         if(!s.equals("end")) {
 61             s = in.nextLine();
 62         }
 63     }
 64         DecimalFormat d = new DecimalFormat("###0.0#");
 65         for (Map.Entry<String, User> e : set.entrySet()) {
 66             System.out.println(e.getValue().getNumber()+" "+d.format(e.getValue().callCost())+" "+d.format(e.getValue().callBalance()));
 67         }
 68     }
 69 
 70 }
 71 
 72 abstract class AnswerChargeRule {
 73     public abstract double AnswerCost (ArrayList<CallRecord> callRecords);
 74 
 75 }
 76 class AnswerInLandRule extends AnswerChargeRule{
 77 
 78     @Override
 79     public double AnswerCost(ArrayList<CallRecord> answerRecords) {
 80         // TODO Auto-generated method stub
 81         double cost = 0;
 82         double m;
 83         for(CallRecord a : answerRecords) {
 84             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
 85             int n = (int)m;
 86             if(m-n>0.000001) {
 87                 n = n+1;
 88             }
 89             cost += 0.3 * n;
 90         }
 91         return cost;
 92     }
 93 
 94 }
 95 abstract class CallChargeRule{
 96     
 97     private double price;
 98     
 99     public abstract double callCost (ArrayList<CallRecord> callRecords);
100     
101     public double getPrice() {
102         return price;
103     }
104     
105     public void setPrice(double price) {
106         this.price = price;
107     }
108 }
109 
110  class CallRecord {
111     private String callingAdressAreaCode;
112     private String AnswerAdressAreaCode;
113     private Date startTime;
114     private Date endTime;
115     
116     public String getCallingAdressAreaCode() {
117         return callingAdressAreaCode;
118     }
119     
120     public void setCallingAdressAreaCode(String callingAdressAreaCode) {
121         this.callingAdressAreaCode = callingAdressAreaCode;
122     }
123     
124     public String getAnswerAdressAreaCode() {
125         return AnswerAdressAreaCode;
126     }
127     
128     public void setAnswerAdressAreaCode(String answerAdressAreaCode) {
129         AnswerAdressAreaCode = answerAdressAreaCode;
130     }
131 
132     public Date getStartTime() {
133         return startTime;
134     }
135 
136     public void setStartTime(Date startTime) {
137         this.startTime = startTime;
138     }
139 
140     public Date getEndTime() {
141         return endTime;
142     }
143 
144     public void setEndTime(Date endTime) {
145         this.endTime = endTime;
146     }
147 }
148 abstract class ChargeMode {
149     private ArrayList<CallChargeRule>  chargeRules = new ArrayList<>();
150     private ArrayList<AnswerChargeRule> answerule = new ArrayList<>();
151     
152     public ArrayList<CallChargeRule> getChargeRules() {
153         return chargeRules;
154     }
155 
156     public void setChargeRules(ArrayList<CallChargeRule> chargeRules) {
157         this.chargeRules = chargeRules;
158     }
159     
160     public abstract double callCost(UserRecords userRecords);
161     
162     public abstract double getMonthlyRent ();
163 
164     public abstract void setMonthlyRent(double a);
165 
166     public ArrayList<AnswerChargeRule> getAnswerule() {
167         return answerule;
168     }
169 
170     public void setAnswerule(ArrayList<AnswerChargeRule> answerule) {
171         this.answerule = answerule;
172     }
173 }
174 class CommunicateRecord {
175     protected String callingNumber;
176     protected String answerNumber;
177     
178     public String getCallingNumber() {
179         return callingNumber;
180     }
181     
182     public void setCallingNumber(String callingNumber) {
183         this.callingNumber = callingNumber;
184     }
185     
186     public String getAnswerNumber() {
187         return answerNumber;
188     }
189     
190     public void setAnswerNumber(String answerNumber) {
191         this.answerNumber = answerNumber;
192     }
193 }
194 class LandlinePhoneCharging extends ChargeMode{
195     private double monthlyRent = 20;
196     @Override
197     public double callCost(UserRecords userRecords) {
198         // TODO Auto-generated method stub
199         CallChargeRule a = new LandPhoneInCityRule();
200         CallChargeRule b = new LandPhoneInProvinceRule();
201         CallChargeRule c = new LandPhoneInlandRule();
202 
203         double callcost = a.callCost(userRecords.getCallingInCityRecords()) + b.callCost(userRecords.getCallingInProvinceRecords()) + c.callCost(userRecords.getCallingInLandRecords());
204         return callcost;
205     }
206 
207     @Override
208     public double getMonthlyRent() {
209         // TODO Auto-generated method stub
210         return monthlyRent;
211     }
212     
213     public void setMonthlyRent(double monthlyRent) {
214         this.monthlyRent = monthlyRent;
215     }
216 }
217 class LandPhoneInCityRule extends CallChargeRule{
218     
219     @Override
220     public double callCost(ArrayList<CallRecord> callRecords) {
221         // TODO Auto-generated method stub
222         double cost = 0;
223         double m;
224         for(CallRecord a : callRecords) {
225             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
226             int n = (int)m;
227             if(m-n>0.000001) {
228                 n = n+1;
229             }
230             cost += 0.1 * n;
231         }
232         return cost;
233     }
234     
235 
236 }
237 class LandPhoneInlandRule extends CallChargeRule{
238 
239     @Override
240     public double callCost(ArrayList<CallRecord> callRecords) {
241         // TODO Auto-generated method stub
242         double cost = 0;
243         double m;
244         for(CallRecord a : callRecords) {
245             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
246             int n = (int)m;
247             if(m-n>0.000001) {
248                 n = n+1;
249             }
250             cost += 0.6 * n;
251         }
252         return cost;
253     }
254 
255 }
256 class LandPhoneInProvinceRule extends CallChargeRule{
257 
258     @Override
259     public double callCost(ArrayList<CallRecord> callRecords) {
260         // TODO Auto-generated method stub
261         double cost = 0;
262         double m;
263         for(CallRecord a : callRecords) {
264             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
265             int n = (int)m;
266             if(m-n>0.000001) {
267                 n = n+1;
268             }
269             cost += 0.3 * n;
270         }
271         return cost;
272     }
273 
274 }
275 class MessageChargeRule {
276     public double MessageCost(ArrayList<MessageRecord> messageRecords) {
277         // TODO Auto-generated method stub
278         double cost = 0;
279         int i = 0;
280         int j = 0;
281         int n = messageRecords.size();
282         for(MessageRecord a : messageRecords) {
283             j = 0;
284             String m = a.getMessage();
285             int k = m.length();
286             if(k>10) {
287                 if(k%10>0) {
288                     j = k/10 + 1;
289                 }
290                 else {
291                     j = k/10;
292                 }
293             }
294             else {
295                 j = 1;
296             }
297             for(int x=1;x<=j;x++) {
298                 if(i+x<=3) {
299                     cost += 0.1;
300                 }
301                 else if(i+x>3&&i+x<=5) {
302                     cost += 0.2;
303                 }
304                 else {
305                     cost += 0.3;
306                 }    
307             }
308             i +=j;
309         }
310         return cost;
311     }
312 }
313 class MessageRecord extends CommunicateRecord{
314     private String message;
315 
316     public String getMessage() {
317         return message;
318     }
319 
320     public void setMessage(String message) {
321         this.message = message;
322     }
323 }
324 class PhoneCharging extends ChargeMode{
325     private double monthlyRent = 15;
326     @Override
327     public double callCost(UserRecords userRecords) {
328         // TODO Auto-generated method stub
329         double cost = 0;
330         CallChargeRule a = new PhoneInCittCallInLand();
331         CallChargeRule b = new PhoneInCityCallInCity();
332         CallChargeRule c = new PhoneInCityCallInProvince();
333         CallChargeRule d = new PhoneInLandCallOther();
334         CallChargeRule e = new PhoneInProvinceCallOther();
335         AnswerChargeRule f = new AnswerInLandRule();
336         cost += f.AnswerCost(userRecords.getAnswerInLandRecords()) + a.callCost(userRecords.getPhonecallingInCityInLandRecords());
337         cost += b.callCost(userRecords.getPhonecallingInCityInCityRecords()) + c.callCost(userRecords.getPhonecallingInCityInProvinceRecords());
338         cost += d.callCost(userRecords.getPhonecallingInLandOtherRecords()) + e.callCost(userRecords.getPhonecallingInProvinceRecords());
339         return cost;
340     }
341 
342     @Override
343     public double getMonthlyRent() {
344         // TODO Auto-generated method stub
345         return monthlyRent;
346     }
347 
348     @Override
349     public void setMonthlyRent(double monthlyRent) {
350         // TODO Auto-generated method stub
351         this.monthlyRent = monthlyRent;
352     }
353 
354 }
355 class PhoneInCittCallInLand extends CallChargeRule{
356     
357     @Override
358     public double callCost(ArrayList<CallRecord> callRecords) {
359         // TODO Auto-generated method stub
360         double cost = 0;
361         double m;
362         for(CallRecord a : callRecords) {
363             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
364             int n = (int)m;
365             if(m-n>0.000001) {
366                 n = n+1;
367             }
368             cost += 0.3 * n;
369         }
370         return cost;
371     }
372 }
373 class PhoneInCityCallInCity extends CallChargeRule{
374     
375     @Override
376     public double callCost(ArrayList<CallRecord> callRecords) {
377         // TODO Auto-generated method stub
378         double cost = 0;
379         double m;
380         for(CallRecord a : callRecords) {
381             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
382             int n = (int)m;
383             if(m-n>0.000001) {
384                 n = n+1;
385             }
386             cost += 0.1 * n;
387         }
388         return cost;
389     }
390 }class PhoneInCityCallInProvince extends CallChargeRule{
391     
392     @Override
393     public double callCost(ArrayList<CallRecord> callRecords) {
394         // TODO Auto-generated method stub
395         double cost = 0;
396         double m;
397         for(CallRecord a : callRecords) {
398             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
399             int n = (int)m;
400             if(m-n>0.000001) {
401                 n = n+1;
402             }
403             cost += 0.2 * n;
404         }
405         return cost;
406     }
407 }class PhoneInLandCallOther  extends CallChargeRule{
408     
409     @Override
410     public double callCost(ArrayList<CallRecord> callRecords) {
411         // TODO Auto-generated method stub
412         double cost = 0;
413         double m;
414         for(CallRecord a : callRecords) {
415             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
416             int n = (int)m;
417             if(m-n>0.000001) {
418                 n = n+1;
419             }
420             cost += 0.6 * n;
421         }
422         return cost;
423     }
424 }
425 class PhoneInProvinceCallOther extends CallChargeRule{
426     
427     @Override
428     public double callCost(ArrayList<CallRecord> callRecords) {
429         // TODO Auto-generated method stub
430         double cost = 0;
431         double m;
432         for(CallRecord a : callRecords) {
433             m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60;
434             int n = (int)m;
435             if(m-n>0.000001) {
436                 n = n+1;
437             }
438             cost += 0.3 * n;
439         }
440         return cost;
441     }
442 }
443 class User {
444      private UserRecords userRecords = new UserRecords();
445      private double balance = 100;
446      private ChargeMode chargemode1 = new LandlinePhoneCharging();
447      private ChargeMode chargemode2 = new PhoneCharging();
448      private MessageChargeRule message = new MessageChargeRule(); 
449      private String number;
450      
451      public double callBalance() {
452          if(number.charAt(0)=='1') {
453              balance = balance - message.MessageCost(userRecords.getSendMessageRecords());  
454          }
455          else {
456              balance = balance - (this.callCost() + chargemode1.getMonthlyRent()); 
457          }
458          return balance;
459      }
460      
461      public double callCost() {
462          if(number.charAt(0)=='1') {
463              return message.MessageCost(userRecords.getSendMessageRecords());
464 
465          }
466          else {
467              return chargemode1.callCost(userRecords);
468 
469          }
470      }
471      
472     public UserRecords getUserRecords() {
473         return userRecords;
474     }
475     
476     public void setUserRecords(UserRecords userRecords) {
477         this.userRecords = userRecords;
478     }
479 
480     public double getBalance() {
481         return balance;
482     }
483 
484     public ChargeMode getChargemode() {
485          if(number.charAt(0)=='1') {
486              return chargemode2; 
487          }
488          else {
489              return chargemode1;
490          }
491         
492     }
493 
494     public void setChargemode(ChargeMode chargemode) {
495         if(number.charAt(0)=='1') {
496             this.chargemode2 = chargemode; 
497          }
498          else {
499              this.chargemode1 = chargemode;
500          }
501     }
502 
503     public String getNumber() {
504         return number;
505     }
506 
507     public void setNumber(String number) {
508         this.number = number;
509     }
510 
511 }
512 class UserRecords {
513 
514     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
515     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
516     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
517     
518     private ArrayList<CallRecord> PhonecallingInLandOtherRecords = new ArrayList<CallRecord>();
519     private ArrayList<CallRecord> PhonecallingInCityInLandRecords = new ArrayList<CallRecord>();
520     private ArrayList<CallRecord> PhonecallingInProvinceRecords = new ArrayList<CallRecord>();
521     private ArrayList<CallRecord> PhonecallingInCityInProvinceRecords = new ArrayList<CallRecord>();
522     private ArrayList<CallRecord> PhonecallingInCityInCityRecords = new ArrayList<CallRecord>();
523 
524     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
525     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
526     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
527     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
528     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
529 
530     public void addCallingInCityRecords (CallRecord callRecord) {
531         callingInCityRecords.add(callRecord);
532     }
533     
534     public void addCallingInProvinceRecords (CallRecord callRecord) {
535         callingInProvinceRecords.add(callRecord);
536     }
537     
538     public void addCallingInLandRecords (CallRecord callRecord) {
539         callingInLandRecords.add(callRecord);
540     }
541     
542     public void addAnswerInCityRecords (CallRecord answerRecord) {
543         answerInCityRecords.add(answerRecord);
544     }
545     public void addAnswerInProvinceRecords (CallRecord answerRecord) {
546         answerInProvinceRecords.add(answerRecord);
547     }
548     
549     public void addAnswerInLandRecords (CallRecord answerRecord) {
550         answerInLandRecords.add(answerRecord);
551     }
552     
553     public void addSendMessageRecords (MessageRecord sendMessageRecord) {
554         sendMessageRecords.add(sendMessageRecord);
555     }
556     
557     public void addReceiveMessageRecords (MessageRecord receiveMessageRecord) {
558         receiveMessageRecords.add(receiveMessageRecord);
559     }
560     
561     public ArrayList<CallRecord> getCallingInCityRecords() {
562         return callingInCityRecords;
563     }
564     
565     public ArrayList<CallRecord> getCallingInProvinceRecords() {
566         return callingInProvinceRecords;
567     }
568     
569     public ArrayList<CallRecord> getCallingInLandRecords() {
570         return callingInLandRecords;
571     }
572     
573     public ArrayList<CallRecord> getAnswerInCityRecords() {
574         return answerInCityRecords;
575     }
576     
577     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
578         return answerInProvinceRecords;
579     }
580     
581     public ArrayList<CallRecord> getAnswerInLandRecords() {
582         return answerInLandRecords;
583     }
584     
585     
586     public ArrayList<MessageRecord> getReceiveMessageRecords() {
587         return receiveMessageRecords;
588     }
589     
590 
591     public ArrayList<MessageRecord> getSendMessageRecords() {
592         return sendMessageRecords;
593     }
594 
595     public ArrayList<CallRecord> getPhonecallingInLandOtherRecords() {
596         return PhonecallingInLandOtherRecords;
597     }
598 
599     public void addPhonecallingInLandOtherRecords(CallRecord phonecallingInLandOtherRecords) {
600         PhonecallingInLandOtherRecords.add(phonecallingInLandOtherRecords);
601     }
602 
603     public ArrayList<CallRecord> getPhonecallingInCityInLandRecords() {
604         return PhonecallingInCityInLandRecords;
605     }
606 
607     public void addPhonecallingInCityInLandRecords(CallRecord phonecallingInCityInLandRecords) {
608         PhonecallingInCityInLandRecords.add(phonecallingInCityInLandRecords);
609     }
610 
611     public ArrayList<CallRecord> getPhonecallingInCityInProvinceRecords() {
612         return PhonecallingInCityInProvinceRecords;
613     }
614 
615     public void addPhonecallingInCityInProvinceRecords(CallRecord phonecallingInCityInProvinceRecords) {
616         PhonecallingInCityInProvinceRecords.add(phonecallingInCityInProvinceRecords);
617     }
618 
619     public ArrayList<CallRecord> getPhonecallingInCityInCityRecords() {
620         return PhonecallingInCityInCityRecords;
621     }
622 
623     public void addPhonecallingInCityInCityRecords(CallRecord phonecallingInCityInCityRecords) {
624         PhonecallingInCityInCityRecords.add(phonecallingInCityInCityRecords);
625     }
626 
627     public ArrayList<CallRecord> getPhonecallingInProvinceRecords() {
628         return PhonecallingInProvinceRecords;
629     }
630 
631     public void addPhonecallingInProvinceRecords(CallRecord phonecallingInProvinceRecords) {
632         PhonecallingInProvinceRecords.add(phonecallingInProvinceRecords);
633     }
634 
635 }

分析:最后一次的题目难度有所降低,主要问题是在于短信条数的计算,以10个为标准进行计算,总体较为简单

心得:主要就是卡在计算短信费用问题,在判断输入方面都没啥,最后还是用了for语句来解决了费用问题,当时打错了一个计算符号导致卡了很久,改好了就一下子过了,还是要细心。

三.踩坑心得

  • 这三次作业主要考察的还是对类与类之间的关系和联系,梳理类之间的联系是很大的难点,中间运用TreeMap,将电话号码作为key来进行User的增加查找,TreeMap的好处就是在输入这个数组的数时会自己排列好,可以省去自己排列的麻烦,但是因为不太熟练使用TreeMap导致在使用的实在不知道如何获取value的值得到user对record进行储存,而第二个难点就格式输入的一个判断,在运用正则表达式的时候,总是会不符合标准,或者没能使用最简洁的表达式去判断,一开始甚至没有考虑过格式的问题,对于日期等判断 都是直接使用\\d{4}去表达,导致格式的测试点全错,第二次作业并没有满分,主要是因为在自身设计的方面出现了问题,没能解决好手机与座机在不同区域打电话和接电话,自己也在第一题所给的类图的基础上进行了手机计费的类图设计,因为手机和座机的话费计算并不相同,当时在这里卡了很久,最后勉勉强强算是到了及格线,还是没处理好手机和座机之间的关系,第三次主要针对短信计费,有了前面的基础,主要问题就是短信条数的计算,我是运用了for来处理接收到的短信,十个字符算一条,一开始用的/10直接处理,但是这样在小于十个字符中的短信不会计算费用,后面就是判断了一下/10后的大小来加1,最后也算是解决了。

·

 

 

 

四.改进建议

  • 可以把三次结合一下出第四次的pta练习

五.总结

  •   通过本阶段的学习自己的收获  

 

  熟练了基本的数据类型,for,if,等基础知识

 

 

  了解到正则表达式,很方便,会继续加深了解和使用

  可以基础的使用对象和类、类的继承、多态、异常处理、抽象类以及接口这些知识

  认识到了TreeMap的一个使用

  能应付不算太复杂的类与类之间的关系

 

 

  •   通过本阶段的学习发现自己在知识掌握方面存在的不足  

  要学会自己根据题目的需求先做好类图,再进行代码的实现

  需要有耐心去分析需求不然很容易就出错

posted @ 2022-06-16 16:40  123ccc  阅读(193)  评论(0)    收藏  举报