其他分享
首页 > 其他分享> > 第三次总结性Blog

第三次总结性Blog

作者:互联网

(1)前言:

       1:难度分析:这次电信计费类型的题目难度比之前的多边形类型题目难度有所降低,手机难度比座机的大,第三次的题目简化成了短信计费难度降低了许多,总体难度中等。

       2:题量:三次大作业的题量都差不多,题量中等。

       3:知识点:选择结构应用、字符型数据与数值型数据之间的类型转换、一维数组、方法的定义与调用、循环结构、正则表达式、继承、多态、容器。

(2)设计与分析:

题1:PTA-7-1电信计费系统

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

输入格式:

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

输出格式:

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

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

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

源码:

  1 import java.lang.reflect.Array;
  2 import java.text.DateFormat;
  3 import java.text.ParseException;
  4 import java.text.SimpleDateFormat;
  5 import java.util.ArrayList;
  6 import java.util.Arrays;
  7 import java.util.Date;
  8 import java.util.Scanner;
  9 
 10 
 11 public class Main {
 12     public  static  void main (String [] args) {
 13         String s;
 14         Scanner in = new Scanner(System.in);
 15         DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
 16         ArrayList<User> users = new ArrayList<>();
 17         while(true)
 18         {
 19             s = in.nextLine();
 20 //            if(s.matches("u-\\d{12} 0||t-\\d{12} \\d{12}( \\d{4}\\.[1-9]*[0-2]*\\.[1-3]*[0-9]* [0-2][0-3]:[0-5][0-9]:[0-5][0-9]){2}")) {
 21                 if(s.charAt(0) == 'u') {
 22             //注册
 23                 String [] ss = s.split(" ");//一个字符串进行分割成多个字符串数组
 24                 String phoneNumber = ss[0].substring(2);
 25                 User user = new User(phoneNumber);
 26                 user.setChargeMode(new LandlinePhoneCharging());
 27                 users.add(user);
 28                 }
 29                 else
 30                     break;
 31 //            }
 32         }
 33         Arrays.sort(new ArrayList[]{users});//T
 34         s = s.substring(2);
 35         String [] ss = s.split(" ");
 36         String startTime;
 37         String endTime;
 38         Date StartTime,EndTime;
 39         
 40         for(User user : users)
 41         {
 42             if(user.getNumber().equals(ss[0]))
 43             {
 44                 String call = ss[0].substring(0, 4);
 45                 String  receive = ss[1].substring(0, 4);
 46                 startTime = ss[2] + " " + ss[3];
 47                 endTime = ss[4] + " " + ss[5];
 48                 try {
 49                     StartTime = dateFormat.parse(startTime);
 50                 } catch (ParseException e) {
 51                     continue;
 52                 }
 53                 try {
 54                     EndTime = dateFormat.parse(endTime);
 55                 } catch (ParseException e) {
 56                     continue;
 57                 }
 58                 if(check(receive)== 1)
 59                 {
 60                     user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive));
 61                 }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime,call,receive));
 62                 else user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime,call,receive));
 63             }
 64         }
 65         while(true)
 66         {
 67             s = in.nextLine();
 68             if(s.equals("end"))break;//T
 69             s = s.substring(2);
 70             String [] sss = s.split(" ");
 71             String sstartTime;
 72             String eendTime;
 73             Date SStartTime,EEndTime;
 74             for(User user : users)
 75             {
 76                 if(user.getNumber().equals(sss[0]))
 77                 {
 78                     String call = sss[0].substring(0, 4);
 79                     String  receive = sss[1].substring(0, 4);
 80                     sstartTime = sss[2] + " " + sss[3];
 81                     eendTime = sss[4] + " " + sss[5];
 82                   
 83                     try {
 84                         SStartTime = dateFormat.parse(sstartTime);
 85                     } catch (ParseException e) {
 86                         continue;
 87                     }
 88                     try {
 89                         EEndTime = dateFormat.parse(eendTime);
 90                     } catch (ParseException e) {
 91                         continue;
 92                     }
 93                     if(check(receive) == 1)
 94                     {
 95                         user.getUserRecords().addCallingInCityRecord(new CallRecord(SStartTime, EEndTime, call, receive));
 96                     }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(SStartTime, EEndTime,call,receive));
 97                     else user.getUserRecords().addCallingInLandRecord(new CallRecord(SStartTime, EEndTime,call,receive));
 98                 }
 99             }
100         }
101         int a = 0;
102         int b = 0;
103         Call call = new Call(a,b);
104         call.getDistance(call);
105         
106         for(User user : users)
107         {
108             System.out.printf("%s %.1f %.1f\n",user.getNumber(),user.calCost(),user.calBalance());
109         }
110     }
111     public  static  int check(String s)
112     {
113         if(s.equals("0791"))return 1;//市内0.1
114         else if(s.equals("0790") || s.equals("0792") || s.equals("0793") || s.equals("0794")||
115                 s.equals("0795")|| s.equals("0796") || s.equals("0797")|| s.equals("0798")|| s.equals("0799")||
116                 s.equals("0701"))return 2;//省内0.3
117         else return 3;//国内0.6
118     }
119 }
120 
121 abstract class CallChargeRule extends  ChargeRule{
122     abstract double calCost(ArrayList<CallRecord>callRecords);
123 }
124 
125 class CallRecord extends  CommunicationRecord{
126     Date startTime;
127     Date endTime;
128     String callingAddressAreaCode;
129     String answerAddressAreaCode;
130 
131     public Date getStartTime() {
132         return startTime;
133     }
134 
135     public void setStartTime(Date startTime) {
136         this.startTime = startTime;
137     }
138 
139     public Date getEndTime() {
140         return endTime;
141     }
142 
143     public void setEndTime(Date endTime) {
144         this.endTime = endTime;
145     }
146 
147     public String getCallingAddressAreaCode() {
148         return callingAddressAreaCode;
149     }
150 
151     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
152         this.callingAddressAreaCode = callingAddressAreaCode;
153     }
154 
155     public String getAnswerAddressAreaCode() {
156         return answerAddressAreaCode;
157     }
158 
159     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
160         this.answerAddressAreaCode = answerAddressAreaCode;
161     }
162     public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
163         this.startTime = startTime;
164         this.endTime = endTime;
165         this.callingAddressAreaCode = callingAddressAreaCode;
166         this.answerAddressAreaCode = answerAddressAreaCode;
167     }
168 }
169 class InputData {
170     private int choice;;//用户输入的选择项
171     public int getChoice() {
172         return choice;
173     }
174     public void setChoice(int choice) {
175         this.choice = choice;
176     }
177     private String color;
178     private String brand;
179     
180     
181     public String getColor() {//私有成员get方法
182         return this.color;
183     }
184     public String getBrand() {
185         return this.brand;
186     }
187     
188 }
189 
190 class Call{
191     public double x;
192     public double y;
193 
194     public Call() {
195 
196     }
197 
198     public Call(double x,double y) {
199         this.x=x;
200         this.y=y;
201     }
202 
203     /* 设置坐标x,将输入参数赋值给属性x */
204     public void setX(double x) {
205         this.x = x;
206     }
207 
208     /* 设置坐标y,将输入参数赋值给属性y */
209     public void setY(double y) {
210         this.y = y;
211     }
212 
213     /* 获取坐标x,返回属性x的值 */
214     public double getX() {
215         return x;
216     }
217 
218     /* 获取坐标y,返回属性y的值 */
219     public double getY() {
220         return y;
221     }
222     public boolean equals(Call p) {
223         boolean b = false;
224         if(this.x==p.getX()&&this.y==p.getY()) {
225             b=true;
226         }
227         return b;
228     }
229 
230     public double getDistance(Call p) {
231         return x;        
232     }
233 }
234 
235 
236 abstract class ChargeMode {
237     ArrayList<ChargeRule> chargeRules = new ArrayList<>();
238 
239     public ArrayList<ChargeRule> getChargeRules() {
240         return chargeRules;
241     }
242 
243     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
244         this.chargeRules = chargeRules;
245     }
246     abstract double calCost(UserRecords userRecords);
247 
248     abstract double getMonthlyRent();
249 }
250 abstract class ChargeRule {
251     abstract double calCost(ArrayList<CallRecord> callRecords);
252 }
253 class CommunicationRecord {
254     String callingNumber;
255     String answerNumber;
256 
257     public String getCallingNumber() {
258         return callingNumber;
259     }
260 
261     public void setCallingNumber(String callingNumber) {
262         this.callingNumber = callingNumber;
263     }
264 
265     public String getAnswerNumber() {
266         return answerNumber;
267     }
268 
269     public void setAnswerNumber(String answerNumber) {
270         this.answerNumber = answerNumber;
271     }
272 }
273 class LandlinePhoneCharging extends ChargeMode{
274     double monthlyRent = 20;
275     public LandlinePhoneCharging()
276     {
277         getChargeRules().add(new LandPhoneCityRule());
278         getChargeRules().add(new LandPhoneLandRule());
279         getChargeRules().add(new LandPhoneProvinceRule());
280     }
281 
282     @Override
283     double calCost(UserRecords userRecords) {
284         double cost = 0;
285         cost = getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) +
286                 getChargeRules().get(1).calCost(userRecords.getCallingInLandRecord()) +
287                 getChargeRules().get(2).calCost(userRecords.getCallingInProvinceRecord());
288         return cost;
289     }
290 
291     @Override
292     public double getMonthlyRent() {
293         return monthlyRent;
294     }
295 }
296 class LandPhoneCityRule extends CallChargeRule{
297     @Override
298     double calCost(ArrayList<CallRecord> callRecords) {
299         double cost = 0;
300         for(CallRecord land : callRecords)
301         {
302             double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() -
303                     land.getStartTime().getTime()) / 1000.0 / 60.0);
304             cost += 0.1 * sumTimeMinutes;
305         }
306         return cost;
307     }
308 }
309 class LandPhoneLandRule extends CallChargeRule{
310     @Override
311     double calCost(ArrayList<CallRecord> callRecords) {
312         double cost = 0;
313         for(CallRecord land : callRecords)
314         {
315             double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() -
316                     land.getStartTime().getTime()) / 1000.0 / 60.0);
317             cost += 0.6 * sumTimeMinutes;
318         }
319         return cost;
320     }
321 }
322 
323 
324 class LandPhoneProvinceRule extends CallChargeRule{
325     @Override
326     double calCost(ArrayList<CallRecord> callRecords) {
327         double cost = 0;
328         for(CallRecord land : callRecords)
329         {
330             double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() -
331                     land.getStartTime().getTime()) / 1000.0 / 60.0);
332             cost += 0.3 * sumTimeMinutes;
333         }
334         return cost;
335     }
336 }
337 class MessageRecord extends CommunicationRecord{
338     String message ;
339 
340     public String getMessage() {
341         return message;
342     }
343 
344     public void setMessage(String message) {
345         this.message = message;
346     }
347 }
348 class User {
349     UserRecords userRecords = new UserRecords();
350     double balance = 100;
351     ChargeMode chargeMode;
352     String number;
353 
354     public User(String number) {
355         this.number = number;
356     }
357 
358     double calBalance()
359     {
360         return getBalance() - calCost() - chargeMode.getMonthlyRent();
361     }
362     double calCost(){
363         return chargeMode.calCost(userRecords);
364     }
365 
366     public UserRecords getUserRecords() {
367         return userRecords;
368     }
369 
370     public void setUserRecords(UserRecords userRecords) {
371         this.userRecords = userRecords;
372     }
373 
374     public double getBalance() {
375         return balance;
376     }
377 
378     public void setBalance(double balance) {
379         this.balance = balance;
380     }
381 
382     public ChargeMode getChargeMode() {
383         return chargeMode;
384     }
385 
386     public void setChargeMode(ChargeMode chargeMode) {
387         this.chargeMode = chargeMode;
388     }
389 
390     public String getNumber() {
391         return number;
392     }
393 
394     public void setNumber(String number) {
395         this.number = number;
396     }
397 }
398 class InputError {
399     //判断从字符串中解析出的点的数量是否合格。
400     public static void wrongNumberOfPoints(ArrayList ps, int num) {
401         if (ps.size() != num) {
402             System.out.println("wrong number of points");
403             System.exit(0);
404         }
405     }
406     //判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序
407     public static void wrongPointFormat(String s) {
408         if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) {
409             System.out.println("Wrong Format");
410             System.exit(0);
411         }
412     }
413 
414     // 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一
415     public static void wrongChoice(String s) {
416         if (!s.matches("[1-5]:.+")) {
417             System.out.println("Wrong Format");
418             System.exit(0);
419         }
420     }
421 }
422 class UserRecords {
423     ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
424     ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
425     ArrayList<CallRecord>callingInLandRecords = new ArrayList<CallRecord>();
426     ArrayList<CallRecord>answerInCityRecords = new ArrayList<CallRecord>();
427     ArrayList<CallRecord>answerInProvinceRecords = new ArrayList<CallRecord>();
428     ArrayList<CallRecord>answerInLandRecords = new ArrayList<CallRecord>();
429     ArrayList<MessageRecord>sendMessageRecords = new ArrayList<MessageRecord>();
430     ArrayList<MessageRecord>receiveMessageRecords = new ArrayList<MessageRecord>();
431     public void addCallingInCityRecord(CallRecord callRecord)
432     {
433         callingInCityRecords.add(callRecord);
434     }
435     public void addCallingInProvinceRecord(CallRecord callRecord)
436     {
437         callingInProvinceRecords.add(callRecord);
438     }
439     public void addCallingInLandRecord(CallRecord callRecord)
440     {
441         callingInLandRecords.add(callRecord);
442     }
443     public void answerInCityRecord(CallRecord callRecord)
444     {
445         answerInCityRecords.add(callRecord);
446     }
447     public void answerInProvinceRecord(CallRecord callRecord)
448     {
449         answerInProvinceRecords.add(callRecord);
450     }
451     public void answerInLandRecord(CallRecord callRecord)
452     {
453         answerInLandRecords.add(callRecord);
454     }
455     public void addSendMessageRecords(MessageRecord sendMessageRecord)
456     {
457         sendMessageRecords.add(sendMessageRecord);
458     }
459     public void addReceiveMessageRecords(MessageRecord receiveMessageRecord)
460     {
461         receiveMessageRecords.add(receiveMessageRecord);
462     }
463     public ArrayList<CallRecord> getCallingInCityRecords() {
464         return callingInCityRecords;
465     }
466 
467     public ArrayList<CallRecord> getCallingInProvinceRecord() {
468         return callingInProvinceRecords;
469     }
470 
471     public ArrayList<CallRecord> getCallingInLandRecord() {
472         return callingInLandRecords;
473     }
474 
475     public ArrayList<CallRecord> getAnswerInCityRecords() {
476         return answerInCityRecords;
477     }
478 
479     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
480         return answerInProvinceRecords;
481     }
482 
483     public ArrayList<CallRecord> getAnswerInLandRecords() {
484         return answerInLandRecords;
485     }
486 
487     public ArrayList<MessageRecord> getSendMessageRecord() {
488         return sendMessageRecords;
489     }
490 
491     public ArrayList<MessageRecord> getReceiveMessageRecord() {
492         return receiveMessageRecords;
493     }
494 }

分析:

while(true)
        {
            s = in.nextLine();
//            if(s.matches("u-\\d{12} 0||t-\\d{12} \\d{12}( \\d{4}\\.[1-9]*[0-2]*\\.[1-3]*[0-9]* [0-2][0-3]:[0-5][0-9]:[0-5][0-9]){2}")) {
                if(s.charAt(0) == 'u') {
            //注册
                String [] ss = s.split(" ");//一个字符串进行分割成多个字符串数组
                String phoneNumber = ss[0].substring(2);
                User user = new User(phoneNumber);
                user.setChargeMode(new LandlinePhoneCharging());
                users.add(user);
                }
                else
                    break;
//            }
        }

对输入的U注册用户数据进行处理并存储

for(User user : users)
        {
            if(user.getNumber().equals(ss[0]))
            {
                String call = ss[0].substring(0, 4);
                String  receive = ss[1].substring(0, 4);
                startTime = ss[2] + " " + ss[3];
                endTime = ss[4] + " " + ss[5];
                try {
                    StartTime = dateFormat.parse(startTime);
                } catch (ParseException e) {
                    continue;
                }
                try {
                    EndTime = dateFormat.parse(endTime);
                } catch (ParseException e) {
                    continue;
                }
                if(check(receive)== 1)
                {
                    user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive));
                }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime,call,receive));
                else user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime,call,receive));
            }
        }

拨打电话的时间和号码进行记录并处理

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

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

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

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

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

源码:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int i = 0 ;
        String [] s = new String[100];//s数组
        ArrayList<User> users = new ArrayList<>();//user容器
        DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
       for(;;){
            s[i] = in.nextLine();//将每一行输入存入s数组
            if(s[i].equals("end"))
                break;
            i ++;//个数
        }
        for(int j = 0;j < i;j ++)//u注册用户
        {
            if(s[j].charAt(0) == 'u')
            {
                boolean t = false;
                if (s[j].equals("")) continue;//去掉空的
                if(cheakDate(s[j]) == false)continue;
                if (checkFirst(s[j]) == false) continue;//去掉不符合格式的
                String[] s2 = s[j].split(" ");
                String phoneNumber = s2[0].substring(2);//提取s[j]中的电话号码存入phoneNumber

                for (User user : users)
                    if (user.getNumber().equals(phoneNumber)) {
                        t = true;
                        break;
                    }
                if (t) continue;//除去相同号码

                User user = new User(phoneNumber);
                users.add(user);
                if (s[j].charAt(s[j].length() - 1) == '0')//座机计费
                    user.setChargeMode(new LandlinePhoneCharging());
                else if(s[j].charAt(s[j].length() - 1) == '1')//手机计费
                    user.setChargeMode(new MobilePhoneCharging());
            }
            else
                break;
        }
        for(int j = 0;j < i;j ++)//t
        {
            if(s[j].charAt(0) == 't')
            {
                if(s[j].equals(""))continue;
                if(s[j].charAt(0) == 't') {
                    phone(1, 2, 3, 4);
                    Date(3,4,3,2);
                }
                if(cheakDate(s[j]) == false)
                if (checkString(s[j]) == true) {//格式检查
                    s[j] = s[j].substring(2);
                    String[] s2 = s[j].split(" ");

                    String startTime;
                    String endTime;
                    Date StartTime = null, EndTime = null;
                    boolean Efficient = false;

                    for (User user : users) {
                        if (user.getNumber().equals(s2[0])) {
                            Efficient = true;
                            if (s2.length == 6) {//079186300001 079186300003 2022.1.3 10:00:25 2022.1.3 10:05:25
                                String call = s2[0].substring(0, 4);//0791
                                String receive = s2[1].substring(0, 4);//0791
                                startTime = s2[2] + " " + s2[3];
                                endTime = s2[4] + " " + s2[5];
                                phone(1, 2, 3, 4);
                                Date(3,4,3,2);
                                //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                                try {
                                    StartTime = dateFormat.parse(startTime);
                                } catch (ParseException e) {
                                    continue;
                                }
                                try {
                                    EndTime = dateFormat.parse(endTime);
                                } catch (ParseException e) {
                                    continue;
                                }
                                if (checkCode(receive) == 1) {//接收地区 市内部
                                    user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive));
                                } else if (checkCode(receive) == 2)//省
                                    user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime, call, receive));
                                else if (checkCode(receive) == 3)//国内
                                    user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime, call, receive));
                            }else if(s2.length == 8)//13811111111 0791 13811111110 020 2022.1.3 08:00:00 2022.1.3 08:09:20
                            {
                                String call = s2[1];//13811111111
                                String receive = s2[3];//13811111110
                                startTime = s2[4] + " " + s2[5];//2022.1.3 08:00:00
                                endTime = s2[6] + " " + s2[7];//2022.1.3 08:09:20
                                //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                                try {
                                    StartTime = dateFormat.parse(startTime);
                                } catch (ParseException e) {
                                    continue;
                                }
                                try {
                                    EndTime = dateFormat.parse(endTime);
                                } catch (ParseException e) {
                                    continue;
                                }
                                if(checkCode(call) == 1 && checkCode(receive) == 1)//市到市
                                {
                                    user.getUserRecords().getMobilePhoneCityCallCity().add(new CallRecord(StartTime, EndTime, call, receive));
                                }else if(checkCode(call) == 1 && checkCode(receive) == 2) {//市到省
                                    user.getUserRecords().getMobilePhoneCityCallProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                }else if(checkCode(call) == 1 && checkCode(receive) == 3){//市到国
                                    user.getUserRecords().getMobilePhoneCityCallLand().add(new CallRecord(StartTime, EndTime, call, receive));
                                    ///判断接听电话的有没有开户
//                                    for(User user1 : users)
//                                    {
//                                        if(user1.getNumber().equals(ss[2]) == true)
//                                        {
//                                            user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
//                                            break;
//                                        }
//                                    }
                                    phone(1, 2, 3, 4);
                                    Date(3,4,3,2);
                                }
                                else if(checkCode(call) == 2){//省主叫
                                    user.getUserRecords().getMobilePhoneProvincialRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive));
                                    if(checkCode(receive) == 3)
                                    {
                                        for(User user1 : users)
                                        {
                                            if(user1.getNumber().equals(s2[2]) == true)
                                            {
                                                user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                                break;
                                            }
                                        }
                                    }
                                }else if(checkCode(call) == 3){
                                    user.getUserRecords().getMobilePhoneDomesticRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive));
                                    if(checkCode(receive) == 3)
                                    {
                                        phone(1, 2, 3, 4);
                                        Date(3,4,3,2);
                                        for(User user1 : users)
                                        {
                                            if(user1.getNumber().equals(s2[2]) == true)
                                            {
                                                user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                                break;
                                            }
                                        }
                                    }
                                }
                            }else if(s2.length == 7)//079186300001 13986300001 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
                            {
                                if(s2[0].charAt(0) == '1')//手机打座机 13986300001 0791 079186300001 2022.12.31 23:50:25 2023.1.1 00:05:11
                                {
                                    String call = s2[1];
                                    String receive = s2[2].substring(0, 4);
                                    startTime = s2[3] + " " + s2[4];
                                    endTime = s2[5] + " " + s2[6];

                                    //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                                    try {
                                        StartTime = dateFormat.parse(startTime);
                                    } catch (ParseException e) {
                                        continue;
                                    }
                                    try {
                                        EndTime = dateFormat.parse(endTime);
                                    } catch (ParseException e) {
                                        continue;
                                    }

                                    if (checkCode(call) == 1 && checkCode(receive) == 1) {
                                        user.getUserRecords().getMobilePhoneCityCallCity().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                                    else if (checkCode(call) == 1 && checkCode(receive) == 2) {
                                        user.getUserRecords().getMobilePhoneCityCallProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                                    else if (checkCode(call) == 1 && checkCode(receive) == 3) {
                                        user.getUserRecords().getMobilePhoneCityCallLand().add(new CallRecord(StartTime, EndTime, call, receive));
                                        phone(1, 2, 3, 4);
                                        Date(3,4,3,2);
                                    }
                                    else if (checkCode(call) == 2) {
                                        user.getUserRecords().getMobilePhoneProvincialRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                                    else if (checkCode(call) == 3) {
                                        user.getUserRecords().getMobilePhoneDomesticRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                                }else//座机打手机079186300001 13986300001 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
                                {
                                    String call = s2[0].substring(0, 4);
                                    String receive = s2[2];
                                    startTime = s2[3] + " " + s2[4];
                                    endTime = s2[5] + " " + s2[6];
                                    //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                                    try {
                                        StartTime = dateFormat.parse(startTime);
                                    } catch (ParseException e) {
                                        continue;
                                    }
                                    try {
                                        EndTime = dateFormat.parse(endTime);
                                    } catch (ParseException e) {
                                        continue;
                                    }
                                    if(checkCode(receive) == 1)
                                    {
                                        user.getUserRecords().getCallingInCityRecords().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                                    else if(checkCode(receive) == 2)
                                    {
                                        user.getUserRecords().getCallingInProvinceRecord().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                                    else if (checkCode(receive) == 3) {
                                        user.getUserRecords().getCallingInLandRecord().add(new CallRecord(StartTime, EndTime, call, receive));
                                        for(User user1 : users)
                                            if(user1.getNumber().equals(s2[1]) == true) {
                                                user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                                break;
                                            }
                                        phone(1, 2, 3, 4);
                                        Date(3,4,3,2);
                                    }
                                }
                            }
                        }
                    }
                    if(Efficient == false)
                    {
                        if(s2.length == 8) {
                            String call = s2[1];
                            String receive = s2[3];
                            startTime = s2[4] + " " + s2[5];
                            endTime = s2[6] + " " + s2[7];
                            try {
                                StartTime = dateFormat.parse(startTime);
                            } catch (ParseException e) {
                                // continue;
                            }
                            try {
                                EndTime = dateFormat.parse(endTime);
                            } catch (ParseException e) {
                                // continue;
                            }
                            //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                            ///判断接听电话的有没有开户
                            for(User user : users)
                                if(user.getNumber().equals(s2[2]))
                                    if (checkCode(receive) == 3) {
                                        user.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                        phone(1, 2, 3, 4);
                                        Date(3,4,3,2);
                                    }
                        }
//                        else if(ss.length == 7 && ss[0].charAt(0) == '0')
//                        {
//                            String call = ss[0].substring(0,4);
//                            String receive = ss[2];
//                            startTime = ss[3] + " " + ss[4];
//                            endTime = ss[5] + " " + ss[6];
//                            try {
//                                StartTime = dateFormat.parse(startTime);
//                            } catch (ParseException e) {
//                                // continue;
//                            }
//                            try {
//                                EndTime = dateFormat.parse(endTime);
//                            } catch (ParseException e) {
//                                // continue;
//                            }
//                            //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
//                            ///判断接听电话的有没有开户
//                            for(User user : users)
//                                if(user.getNumber().equals(ss[1]))
//                                    if (checkCode(receive) == 3) {
//                                        user.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
//                                    }
//                        }
                    }
                }
            }
        }
        //座机打座机 座机打手机 手机打座机 手机打手机
        TreeMap<String, User> treeMap = new TreeMap<>();
        for (User user : users) {
            treeMap.put(user.getNumber(), user);
        }
        Iterator<User> t = treeMap.values().iterator();
        while (t.hasNext()) {
            User user = t.next();
            System.out.println(user.number + " " + user.calCost() + " " + user.calBalance());
        }
    }

    public static double phone(double x1, double y1, double x2, double y2){
        double dis = 0 ;

        dis = Math.abs((x1-x2)-(y1-y2));
        return  dis;
    }
    public static double Date(double x1, double y1, double x2, double y2){
        double dis = 0 ;

        dis = Math.abs((x1+x2)-(y1+y2));
        return  dis;
    }
    public static  boolean cheakDate(String s){
        if(s.matches("u-0[0-9]{10,11} [0-1]"))
            return true;
        if(s.matches("u-1[0-9]{10} [0-1]"))
            return true;
        return false;
    }
    static boolean checkString(String str) {
        //月份:((((20)\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\d|3[01]))|(((19|20)\d{2}).(0?[469]|11).(0?[1-9]|[12]\d|30))|(((19|20)\d{2}).0?2.(0?[1-9]|1\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]
        //座机打座机
        //座机打手机           t-0[0-9]{10,11} 1[0-9]{10} [0-9]{3,4}
        if(str.matches("t-0[0-9]{10,11} 0[0-9]{9,11} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]"))
            return true;
        else if(str.matches("t-0[0-9]{10,11} 1[0-9]{10} [0-9]{3,4} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]"))
            return true;
        else if(str.matches("t-1[0-9]{10} [0-9]{3,4} 0[0-9]{9,11} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]"))
            return true;
        else if(str.matches("t-1[0-9]{10} [0-9]{3,4} 1[0-9]{10} [0-9]{3,4} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]"))
            return  true;
            //手机打座机
            //手机打手机
            //if(str.matches())
        else
            return false;
    }


    static boolean checkFirst(String s) {
        if(s.matches("u-0[0-9]{10,11} [0-1]"))
            return true;
        if(s.matches("u-1[0-9]{10} [0-1]"))
            return true;
        return false;
    }

    public static int checkCode(String s) {
        if (s.equals("0791")) return 1;//市内
        else if (s.equals("0790") || s.equals("0792") || s.equals("0793") || s.equals("0794") ||
                s.equals("0795") || s.equals("0796") || s.equals("0797") || s.equals("0798") ||
                s.equals("0799") || s.equals("0701"))
            return 2;//省内
        else return 3;//国内
    }


    public abstract static class ChargeRule {
        abstract double calCost(ArrayList<CallRecord> callRecords);
    }

    public static class MobilePhoneCityCallCityRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            double cost = 0;
            for(CallRecord c : callRecords)
            {
                double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() -
                        c.getStartTime().getTime()) / 1000.0 / 60.0);
                cost += 0.1 * sumTimeMinutes;
            }
            return cost;
        }
    }

    public static class MobilePhoneCharging extends  ChargeMode{

        double monthlyRent = 15;
        public MobilePhoneCharging ()
        {
            getChargeRules().add(new MobilePhoneCityCallCityRule());
            getChargeRules().add(new MobilePhoneCityCallProvinceRule());
            getChargeRules().add(new MobilePhoneCityCallLandRule());
            getChargeRules().add(new MobilePhoneDomesticRoamingCallRule());
            getChargeRules().add(new MobilePhoneProvincialRoamingCallRule());
            getChargeRules().add(new MobilePhoneRoamingAnsweringOutsideProvinceRule());
        }
        @Override
        double calCost(UserRecords userRecords) {
            double cost = 0;
            cost = getChargeRules().get(0).calCost(userRecords.getMobilePhoneCityCallCity()) +
                    getChargeRules().get(1).calCost(userRecords.getMobilePhoneCityCallProvince()) +
                    getChargeRules().get(2).calCost(userRecords.getMobilePhoneCityCallLand())
                    + getChargeRules().get(3).calCost(userRecords.getMobilePhoneDomesticRoamingCall()) +
                    getChargeRules().get(4).calCost(userRecords.getMobilePhoneProvincialRoamingCall())
                    + getChargeRules().get(5).calCost(userRecords.getMobilePhoneRoamingAnsweringOutsideProvince());
            return cost;
        }
        @Override
        public double getMonthlyRent() {
            return monthlyRent;
        }
    }

    public abstract static class CallChargeRule extends ChargeRule {
        abstract double calCost(ArrayList<CallRecord> callRecords);
    }

    public static class MobilePhoneProvincialRoamingCallRule extends CallChargeRule {//手机省级漫游呼叫规则

        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            double cost = 0;
            for(CallRecord c : callRecords)
            {
                double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() -
                        c.getStartTime().getTime()) / 1000.0 / 60.0);
                cost += 0.3 * sumTimeMinutes;
            }
            return cost;
        }
    }

    public static class MessageRecord extends CommunicationRecord {
        String message ;

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }
    }

    public static class LandlinePhoneCharging extends ChargeMode {
        double monthlyRent = 20;
        public LandlinePhoneCharging()
        {
            getChargeRules().add(new LandPhoneCityRule());
            getChargeRules().add(new LandPhoneLandRule());
            getChargeRules().add(new LandPhoneProvinceRule());
        }

        @Override
        double calCost(UserRecords userRecords) {
            double cost = 0;
            cost = getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) +
                    getChargeRules().get(1).calCost(userRecords.getCallingInLandRecord()) +
                    getChargeRules().get(2).calCost(userRecords.getCallingInProvinceRecord());
            return cost;
        }

        @Override
        public double getMonthlyRent() {
            return monthlyRent;
        }
    }
    public static class MobilePhoneCityCallProvinceRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            double cost = 0;
            for(CallRecord c : callRecords)
            {
                double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() -
                        c.getStartTime().getTime()) / 1000.0 / 60.0);
                cost += 0.2 * sumTimeMinutes;
            }
            return cost;
        }
    }

    public static class CommunicationRecord {
        String callingNumber;
        String answerNumber;

        public String getCallingNumber() {
            return callingNumber;
        }

        public void setCallingNumber(String callingNumber) {
            this.callingNumber = callingNumber;
        }

        public String getAnswerNumber() {
            return answerNumber;
        }

        public void setAnswerNumber(String answerNumber) {
            this.answerNumber = answerNumber;
        }
    }

    public static class LandPhoneLandRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            double cost = 0;
            for(CallRecord land : callRecords)
            {
                double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() -
                        land.getStartTime().getTime()) / 1000.0 / 60.0);
                cost += 0.6 * sumTimeMinutes;
            }
            return cost;
        }
    }

    public static class User {
        UserRecords userRecords = new UserRecords();
        double balance = 100;
        ChargeMode chargeMode;
        String number;

        public User(String number) {
            this.number = number;
        }

        double calBalance()
        {
            return getBalance() - calCost() - chargeMode.getMonthlyRent();
        }
        double calCost(){
            return chargeMode.calCost(userRecords);
        }

        public UserRecords getUserRecords() {
            return userRecords;
        }

        public void setUserRecords(UserRecords userRecords) {
            this.userRecords = userRecords;
        }

        public double getBalance() {
            return balance;
        }

        public void setBalance(double balance) {
            this.balance = balance;
        }

        public ChargeMode getChargeMode() {
            return chargeMode;
        }

        public void setChargeMode(ChargeMode chargeMode) {
            this.chargeMode = chargeMode;
        }

        public String getNumber() {
            return number;
        }

        public void setNumber(String number) {
            this.number = number;
        }
    }

    public static class CallRecord extends CommunicationRecord {
        Date startTime;
        Date endTime;
        String callingAddressAreaCode;
        String answerAddressAreaCode;

        public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
            this.startTime = startTime;
            this.endTime = endTime;
            this.callingAddressAreaCode = callingAddressAreaCode;
            this.answerAddressAreaCode = answerAddressAreaCode;
        }

        public Date getStartTime() {
            return startTime;
        }

        public void setStartTime(Date startTime) {
            this.startTime = startTime;
        }

        public Date getEndTime() {
            return endTime;
        }

        public void setEndTime(Date endTime) {
            this.endTime = endTime;
        }

        public String getCallingAddressAreaCode() {
            return callingAddressAreaCode;
        }

        public void setCallingAddressAreaCode(String callingAddressAreaCode) {
            this.callingAddressAreaCode = callingAddressAreaCode;
        }

        public String getAnswerAddressAreaCode() {
            return answerAddressAreaCode;
        }

        public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
            this.answerAddressAreaCode = answerAddressAreaCode;
        }
    }

    public static class MobilePhoneCityCallLandRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            double cost = 0;
            for(CallRecord c : callRecords)
            {
                double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() -
                        c.getStartTime().getTime()) / 1000.0 / 60.0);
                cost += 0.3 *  sumTimeMinutes;
            }
            return cost;
        }
    }

    public static class UserRecords {
        ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord>callingInLandRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord>answerInCityRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord>answerInProvinceRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord>answerInLandRecords = new ArrayList<CallRecord>();
        ArrayList<MessageRecord>sendMessageRecords = new ArrayList<MessageRecord>();
        ArrayList<MessageRecord>receiveMessageRecords = new ArrayList<MessageRecord>();
        ArrayList<CallRecord> mobilePhoneCityCallCity = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneCityCallProvince = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneCityCallLand = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneDomesticRoamingCall = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneProvincialRoamingCall = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneRoamingAnsweringOutsideProvince = new ArrayList<CallRecord>();
        public void addMobilePhoneCityCallCity(CallRecord callRecord){mobilePhoneCityCallCity.add(callRecord);};
        public void addMobilePhoneCityCallProvince(CallRecord callRecord){mobilePhoneCityCallProvince.add(callRecord);};
        public void addMobilePhoneCityCallLand(CallRecord callRecord){mobilePhoneCityCallLand.add(callRecord);};
        public void addMobilePhoneDomesticRoamingCall(CallRecord callRecord){mobilePhoneDomesticRoamingCall.add(callRecord);};
        public void addMobilePhoneProvincialRoamingCall(CallRecord callRecord){mobilePhoneProvincialRoamingCall.add(callRecord);};
        public void addMobilePhoneRoamingAnsweringOutsideProvince(CallRecord callRecord){mobilePhoneRoamingAnsweringOutsideProvince.add(callRecord);};
        public void addCallingInCityRecord(CallRecord callRecord)
        {
            callingInCityRecords.add(callRecord);
        }
        public void addCallingInProvinceRecord(CallRecord callRecord)
        {
            callingInProvinceRecords.add(callRecord);
        }
        public void addCallingInLandRecord(CallRecord callRecord)
        {
            callingInLandRecords.add(callRecord);
        }
        public void answerInCityRecord(CallRecord callRecord)
        {
            answerInCityRecords.add(callRecord);
        }
        public void answerInProvinceRecord(CallRecord callRecord)
        {
            answerInProvinceRecords.add(callRecord);
        }
        public void answerInLandRecord(CallRecord callRecord)
        {
            answerInLandRecords.add(callRecord);
        }
        public void addSendMessageRecords(MessageRecord sendMessageRecord)
        {
            sendMessageRecords.add(sendMessageRecord);
        }
        public void addReceiveMessageRecords(MessageRecord receiveMessageRecord)
        {
            receiveMessageRecords.add(receiveMessageRecord);
        }

        public ArrayList<CallRecord> getMobilePhoneCityCallCity() {
            return mobilePhoneCityCallCity;
        }

        public ArrayList<CallRecord> getMobilePhoneCityCallProvince() {
            return mobilePhoneCityCallProvince;
        }

        public ArrayList<CallRecord> getMobilePhoneCityCallLand() {
            return mobilePhoneCityCallLand;
        }

        public ArrayList<CallRecord> getMobilePhoneDomesticRoamingCall() {
            return mobilePhoneDomesticRoamingCall;
        }

        public ArrayList<CallRecord> getMobilePhoneProvincialRoamingCall() {
            return mobilePhoneProvincialRoamingCall;
        }

        public ArrayList<CallRecord> getMobilePhoneRoamingAnsweringOutsideProvince() {
            return mobilePhoneRoamingAnsweringOutsideProvince;
        }

        public ArrayList<CallRecord> getCallingInCityRecords() {
            return callingInCityRecords;
        }

        public ArrayList<CallRecord> getCallingInProvinceRecord() {
            return callingInProvinceRecords;
        }

        public ArrayList<CallRecord> getCallingInLandRecord() {
            return callingInLandRecords;
        }

        public ArrayList<CallRecord> getAnswerInCityRecords() {
            return answerInCityRecords;
        }

        public ArrayList<CallRecord> getAnswerInProvinceRecords() {
            return answerInProvinceRecords;
        }

        public ArrayList<CallRecord> getAnswerInLandRecords() {
            return answerInLandRecords;
        }

        public ArrayList<MessageRecord> getSendMessageRecord() {
            return sendMessageRecords;
        }

        public ArrayList<MessageRecord> getReceiveMessageRecord() {
            return receiveMessageRecords;
        }
    }

    public abstract static class ChargeMode {
        ArrayList<ChargeRule> chargeRules = new ArrayList<>();

        public ArrayList<ChargeRule> getChargeRules() {
            return chargeRules;
        }

        public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
            this.chargeRules = chargeRules;
        }
        abstract double calCost(UserRecords userRecords);

        abstract double getMonthlyRent();
    }

    //移动电话省外漫游呼叫规则
    public static class MobilePhoneRoamingAnsweringOutsideProvinceRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            double cost = 0;
            for(CallRecord c : callRecords)
            {
                double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() -
                        c.getStartTime().getTime()) / 1000.0 / 60.0);
                cost += 0.3 * sumTimeMinutes;
            }
            return cost;
        }
    }

    public static class LandPhoneProvinceRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            double cost = 0;
            for(CallRecord land : callRecords)
            {
                double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() -
                        land.getStartTime().getTime()) / 1000.0 / 60.0);
                cost += 0.3 * sumTimeMinutes;
            }
            return cost;
        }
    }

    public static class LandPhoneCityRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            double cost = 0;
            for(CallRecord land : callRecords)
            {
                double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() -
                        land.getStartTime().getTime()) / 1000.0 / 60.0);
                cost += 0.1 * sumTimeMinutes;
            }
            return cost;
        }
    }

    public static class MobilePhoneDomesticRoamingCallRule extends CallChargeRule {//手机国内漫游呼叫规则
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            double cost = 0;
            for(CallRecord c : callRecords)
            {
                double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() -
                        c.getStartTime().getTime()) / 1000.0 / 60.0);
                cost += 0.6 * sumTimeMinutes;
            }
            return cost;
        }
    }
}

分析:

利用checkCode类判断地区从而分类计费

  if (checkCode(receive) == 1) {//接收地区 市内部
                                    user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive));
                                } else if (checkCode(receive) == 2)//省
                                    user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime, call, receive));
                                else if (checkCode(receive) == 3)//国内
                                    user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime, call, rec

方法和上一次相同就是多了很多判断。

if(checkCode(receive) == 1)
                                    {
                                        user.getUserRecords().getCallingInCityRecords().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                                    else if(checkCode(receive) == 2)
                                    {
                                        user.getUserRecords().getCallingInProvinceRecord().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                                    else if (checkCode(receive) == 3) {
                                        user.getUserRecords().getCallingInLandRecord().add(new CallRecord(StartTime, EndTime, call, receive));
                                        for(User user1 : users)
                                            if(user1.getNumber().equals(s2[1]) == true) {
                                                user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                                break;
                                            }
题3: 7-1 电信计费系列3-短信计费 分数 50 作者 蔡轲 单位 南昌航空大学

实现一个简单的电信计费程序,针对手机的短信采用如下计费方式
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。

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

源码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        HashSet<User> users = new HashSet<>();//存入用户
        ArrayList<String> messages = new ArrayList<>();//存入信息
        String Line;
        do{
            Line = input.nextLine();
            User a;
            if (Line.equals("")) continue;
            if (Line.charAt(0) == 'u' && Line.charAt(14) == '3') {//注册
                    a = new User(Line.substring(2, 13));
                    users.add(a);//注册用户电话号码
                }
            else if ( legal(Line.substring(2)) && Line.charAt(0) == 'm') {//拨打
                    messages.add(Line);
                }
        }while (!Line.equals("end"));
        ArrayList<User> userone = new ArrayList<>(users);
        Collections.sort(userone);
        InputData inputData = new InputData();
        inputData.getChoice();
        inputData.getPoints();
        inputData.getselect();
        for (User j : userone) {
            double cost;
            cost = callCost(j, messages);
            System.out.printf("%s %.1f %.1f\n", j.num, cost, 100 - cost);
        }
    }
    public static double callCost(User user, ArrayList<String> messages) {
        int num = 0;
        for (String m : messages) {
            if (Objects.equals(getNum(m), user.num))
                num = num + getMessageNum(m);
        }
        if (num > 5)
            return 0.7 + (num - 5) * 0.3;
        else if (num > 3)
            return 0.3 + (num - 3) * 0.2;
        else
            return num * 0.1;
    }
    static String getNum(String s) {
        for (int i = 2; i < 13; i++) {
            if (!(s.charAt(i) >= '0' && s.charAt(i) <= '9'))
                return null;
        }
        return s.substring(2, 13);
    }
    private static int getMessageNum(String string) {
        int a = 0;
        for (int i = 0; i < string.length(); i++) {
            if (string.charAt(i) == ' ') {
                if (a != 1) a++;
                else {
                    a = i;
                    break;
                }
            }
        }
        int b = string.length() - a;
        int c = b / 10;
        if (b % 10 != 0)
            c++;
        return c;
    }
    static boolean legal(String s) {
        for (int i = 0; i < s.length(); i++) {
            if (!(s.charAt(i) >= '0' && s.charAt(i) <= '9') && s.charAt(i) != ',' &&
                    s.charAt(i) != ' ' && s.charAt(i) != '.' && !(s.charAt(i) >= 'a' && s.charAt(i) <= 'z') &&
                    !(s.charAt(i) >= 'A' && s.charAt(i) <= 'Z')) {
                return false;
            }
        }
        return true;
    }
    
   
}
class InputData {
    private int choice;;//用户输入的选择项
    public int getChoice() {
        return choice;
    }
    public int getselect() {
        return choice;
    }
    public double getPoints() {
        return 0;
    }


}
class User implements Comparable<User> {
    String num;
    public User(String num) {
        this.num = num;
    }
    @Override
    public int compareTo(User o) {
        return num.compareTo(o.num);
    }
}

分析:

这次的功能比较简单利用如下容器存储信息

HashSet<User> users = new HashSet<>();//存入用户

ArrayList<String> messages = new ArrayList<>();//存入信息

用如下方法获得短信数量

 static String getNum(String s) {
        for (int i = 2; i < 13; i++) {
            if (!(s.charAt(i) >= '0' && s.charAt(i) <= '9'))
                return null;
        }
        return s.substring(2, 13);
    }
    private static int getMessageNum(String string) {
        int a = 0;
        for (int i = 0; i < string.length(); i++) {
            if (string.charAt(i) == ' ') {
                if (a != 1) a++;
                else {
                    a = i;
                    break;
                }
            }
        }
        int b = string.length() - a;
        int c = b / 10;
        if (b % 10 != 0)
            c++;
        return c;
    }

 

(3)采坑心得:

不知道怎么计算通话时间

public class FormatDateTime {
    
    public static String toLongDateString(Date dt){
        SimpleDateFormat myFmt=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E ");        
        return myFmt.format(dt);
    }
    
    public static String toShortDateString(Date dt){
        SimpleDateFormat myFmt=new SimpleDateFormat("yy年MM月dd日 HH时mm分");        
        return myFmt.format(dt);
    }    
    
    public static String toLongTimeString(Date dt){
        SimpleDateFormat myFmt=new SimpleDateFormat("HH mm ss SSSS");        
        return myFmt.format(dt);
    }
    public static String toShortTimeString(Date dt){
        SimpleDateFormat myFmt=new SimpleDateFormat("yy/MM/dd HH:mm");        
        return myFmt.format(dt);
    }
    
    public static void main(String[] args) {

        Date now=new Date();

        System.out.println(FormatDateTime.toLongDateString(now));
        System.out.println(FormatDateTime.toShortDateString(now));
        System.out.println(FormatDateTime.toLongTimeString(now));
        System.out.println(FormatDateTime.toShortTimeString(now));
    }    
    
}
调用的main 测试结果:
2004年12月16日 17时38分26秒 星期四 
04年12月16日 17时38分
17 38 26 0965
04/12/16 17:38

 

(4)改进建议:

类图中的类有些我没有用到,有些情况也没有考虑到,有待完善。

(5)总结:

(1)下次要提前开始写大作业,不能卡着时间点,这样才有更多的时间去修改代码,去思考难的问题,提升解决问题的能力。

 

(2)要提升自学能力和学习能力,提高学习的主动性,很多问题在网上都能找到解决方法,解决问题的过程就是学习的过程。

 

(3)我对于多类还有许多不懂的地方,今后要加强这方面的学习。

标签:总结性,return,String,double,ArrayList,Blog,new,public,第三次
来源: https://www.cnblogs.com/luokeliu/p/16363257.html