首页 > 其他分享 >BLOG-3

BLOG-3

时间:2022-12-03 09:44:41浏览次数:34  
标签:return String double ArrayList BLOG new public

一、前言

  1. 难度分析:近三次大作业难度相较与前面多边形难度有所下降,手机计费比座机计费大,而最后的短信计费难度则又降低。
  2. 题量:题量适中
  3. 知识点:继承多态容器,正则表达式等

二、设计与分析

  1.题目一:7-1 电信计费系列1-座机计费  

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

输入格式:

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

输出格式:

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

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

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

image.png

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

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

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

image.png

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

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

image.png

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

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

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

源码:

 

import java.util.Scanner;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;

 
public class Main{
    public static void main(String []args) throws ParseException {                 
        Scanner input = new Scanner(System.in);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ArrayList<User> array = new ArrayList<>();
        int flag = 0;
        String s = input.nextLine();
        String[] a ;
        while (!s.equals("end")){
            if(s.matches("[u][-](0791)[0-9]{7,8}[ ][0]")){
                a = s.substring(2,s.length()).split("\\s");
                for(int i = 0;i < array.size();i++){
                    if(Objects.equals(array.get(i).getNumber(), a[0])) {
                        flag = 1;
                    }
                }
                if(flag == 0) {
                    array.add(new User(a[0]));
                    flag = 0;
                }
            }
            if(s.matches("t-(\\d){11,12}\\s(\\d){10,12}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]"
                    + "|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])"
                    + "|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))"
                    + "|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))"
                    + "|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d")){
                a = s.substring(2,s.length()).split("\\s");
                for(int i=0;i< array.size();i++){
                    if(array.get(i).getNumber().equals(a[0])){
                        if(a[1].startsWith("0791")){
                            array.get(i).userRecord.addCallingInCityRecords(new CallRecord(a[2]+" "+a[3],a[4]+" "+a[5]));
                            array.get(i).setUserRecord(array.get(i).userRecord);
                        }
                        else if(a[1].substring(0,4).matches("(079\\d|0701)")){
                            array.get(i).userRecord.addCallingInProvinceRecords(new CallRecord(a[2]+" "+a[3],a[4]+" "+a[5]));
                            array.get(i).setUserRecord(array.get(i).userRecord);
                        }
                        else{
                            array.get(i).userRecord.addCallingInLandRecords(new CallRecord(a[2]+" "+a[3],a[4]+" "+a[5]));
                            array.get(i).setUserRecord(array.get(i).userRecord);
                        }
                    }
                }
 
            }
            s = input.nextLine();
        }       
        List<User> list = new ArrayList<>(array);
        Collections.sort(list);       
        for (User e : list){
            System.out.print(e.getNumber()+" ");
            System.out.print(new DecimalFormat("0.0#").format(e.calCost()));
            System.out.print(" ");
            System.out.print(new DecimalFormat("0.0#").format(e.calBalance()));
            System.out.println();
        }
    }
}
 
abstract class ChargeRule{
 
}
 
abstract class CallChargeRule extends ChargeRule{
   public double calCost(ArrayList<CallRecord>callRecords){
       return 0;
   }
}

class CallRecord extends ChargeRule{
   private Date startTime;
   private Date endTime;
   private String callingAddressAreaCode;
   private String AnswerAddressAreaCode;
 
   public CallRecord(String startTime,String endTime) throws ParseException {
       this.startTime =  new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").parse(startTime);
       this.endTime = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").parse(endTime);
   }
 
   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;
   }
    
}
 
abstract class ChargeMode{
       ArrayList<ChargeRule> chargeRule = new ArrayList<ChargeRule>();
        
       public ArrayList<ChargeRule> getChargeRule(){
           return chargeRule;
       }
        
       public void setChargeRule(ArrayList<ChargeRule> chargeRule){
           this.chargeRule = chargeRule;
       }
        
       public double getMonthlyRent(){
           return 20;
       }
        
       public double calCost(UserRecords userRecords){
           return 0;
       }
        
    }
 
class LandlinePhoneCharging extends ChargeMode{
   private double monthlyRent = 20;
 
   public double calCost(UserRecords userRecords){
       return monthlyRent * 1;
   }
    
   public double getMonthlyRent(){
       return monthlyRent;
   }
}
 
class CommunicationRecord{
   protected String callingNumber;
   protected 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;
   }
}

class MessageRecord extends ChargeRule{
   private String message;
 
   public String getMessage() {
       return message;
   }
 
   public void setMessage(String message) {
       this.message = message;
   }
}
 
class LandPhoneInCityRule extends CallChargeRule{
   public double calCost(ArrayList<CallRecord> callRecords){
       double cost = 0;
       double  minute;
       for (CallRecord e: callRecords){
           minute = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime()) / 60000);
           cost =  cost + 0.1 * minute;
       }
       return cost;
   }
}
 
class LandPhoneInProvinceRule extends CallChargeRule{
       public double calCost(ArrayList<CallRecord> callRecords){
           double cost = 0;
           double  minute;
           for (CallRecord e: callRecords){
               minute = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime()) / 60000);
               cost =  cost + 0.3 * minute;
           }
           return cost;
        }
}  
 
class LandPhoneInIandRule extends CallChargeRule{
   public double calCost(ArrayList<CallRecord> callRecords){
       double cost = 0;
       double  minute;
       for (CallRecord e: callRecords){
           minute = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime()) /  60000);
           cost =  cost + 0.6 * minute;
       }
       return cost;
   }
}

class User implements Comparable<User> {
    UserRecords userRecord = new UserRecords();
    private double balance = 100;
    ChargeMode chargeMode;
    private String number;
     
   public User(){
 
   }
    
   public void setBalance(double balance) {
    this.balance = balance;
   }
 
   public User(String number) {
       this.number = number;
   }
 
   public double calBalance(){
        return balance - calCost() - 20;
    }
    
    public double calCost(){
        LandPhoneInCityRule landPhoneInCityRule = new LandPhoneInCityRule();
        LandPhoneInIandRule landPhoneInIandRule = new LandPhoneInIandRule();
        LandPhoneInProvinceRule landPhoneInProvinceRule = new LandPhoneInProvinceRule();
        return landPhoneInIandRule.calCost(userRecord.getCallingInLandRecords())
                +landPhoneInCityRule.calCost(userRecord.getCallingInCityRecords())
                +landPhoneInProvinceRule.calCost(userRecord.getCallingInProvinceRecords());
    }
     
    public UserRecords getUserRecord(){
        return userRecord;
    }
     
    public void setUserRecord(UserRecords userRecord){
        this.userRecord = userRecord;
    }
     
    public double getBalance(){
        return 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 int compareTo(User o) {
       return this.getNumber().compareTo(o.getNumber());
   }
 
}
 
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> sendMessageRecord = new ArrayList<MessageRecord>();
   ArrayList<MessageRecord> receiveMessageRecord = new ArrayList<MessageRecord>();
    
   public void addCallingInCityRecords(CallRecord callRecord){
       callingInCityRecords.add(callRecord);
   }
    
   public void addCallingInProvinceRecords(CallRecord callRecord){
       callingInProvinceRecords.add(callRecord);
   }
    
   public void addCallingInLandRecords(CallRecord callRecord){
       callingInLandRecords.add(callRecord);
   }
    
   public void addAnswerInCityRecords(CallRecord callRecord){
       answerInCityRecords.add(callRecord);
   }
    
   public void addAnswerInProvinceRecords(CallRecord callRecord){
       answerInProvinceRecords.add(callRecord);
   }
    
   public void addAnswerInLandRecords(CallRecord callRecord){
       answerInLandRecords.add(callRecord);
   }
    
   public void addSendMessageRecord(MessageRecord sendMessageRecord){
       this.sendMessageRecord.add(sendMessageRecord);
   }
    
   public void addReceiveMessageRecord(MessageRecord receiveMessageRecord){
       this.receiveMessageRecord.add(receiveMessageRecord);
   }
    
   public ArrayList<MessageRecord> getSendMessageRecord(){
       return sendMessageRecord;
   }
    
   public ArrayList<MessageRecord> getReceiveMessageRecord(){
       return receiveMessageRecord;
   }
    
   public ArrayList<CallRecord> getCallingInCityRecords(){
       return callingInCityRecords;
   }
    
   public ArrayList<CallRecord> getCallingInProvinceRecords(){
       return callingInProvinceRecords;
   }
    
   public ArrayList<CallRecord> getCallingInLandRecords(){
       return callingInLandRecords;
   }
    
   public ArrayList<CallRecord> getAnswerInCityRecords(){
       return answerInCityRecords;
   }
    
   public ArrayList<CallRecord> getAnswerInProvinceRecords(){
       return answerInProvinceRecords;
   }
    
   public ArrayList<CallRecord> getAnswerInLandRecords(){
       return answerInLandRecords;
   }
}

 

  

 

 

  代码类图:

 

 分析:

本题由于老师已经将类图给出,将所给类补全后,在Main中利用正则表达式判断输入字符串,并进行容器的添加计算,需要将类与类之间的关系理顺

踩坑心得:

这题正则表达式的书写非常有难度,一定要小心仔细

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

 

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

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

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

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

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

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

image.png
图1

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

image.png

图2

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

image.png
图3

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

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

源码:

import java.util.ArrayList;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Collections;
import java.util.Scanner;

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

    }
}


class CallRecord {
    private Date startTime;
    private Date endTime;
    private String callingAddressAreaCode;
    private String answerAddressAreaCode;

    public CallRecord(String starttime,String endtime, String callingAddressAreaCode, String answerAddressAreaCode) throws ParseException {
        super();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        String date1 = starttime;
        String date2 = endtime;
        Date time1 = sf.parse(date1);
        Date time2 = sf.parse(date2);
        this.startTime = time1;
        this.endTime = time2;
        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;
    }

}

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

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

    public void setChargeRules(ArrayList<ChargeRule> chargeRules) {

    }
    public double calCost(UserRecords userRecords) {
        return 0;

    }
    public double getMonthlyRent() {
        return 0;

    }

}

abstract class ChargeRule {
	
}

abstract class CommunicationRecord {
    private String callingNumber;
    private 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;
    }

}
class LandlinePhoneCharging extends ChargeMode{
    private double monthlyRent = 20;

    public double getMonthlyRent() {
        return monthlyRent;
    }

    public double calCost(UserRecords userRecords) {
        double calcost = 0;
        LandPhoneInCityRule incity = new LandPhoneInCityRule();
        LandPhoneInProvinceRule inprovince = new LandPhoneInProvinceRule();
        LandPhoneInlandRule inland = new LandPhoneInlandRule();
        calcost = incity.calCost(userRecords.getCallinglnCityRecords()) + inprovince.calCost(userRecords.getCallinglnProvinceRecords()) + inland.calCost(userRecords.getCallinglnLandRecords());
        return calcost;
    }

}

class LandPhoneInCityRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
         double sum = 0;
         for(CallRecord a:callRecords){
         sum += 0.1 * ((((a.getEndTime().getTime() - a.getStartTime().getTime())/1000)+59)/60);
    }
        return sum;
    }


}

class LandPhoneInlandRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
         double sum = 0;
         for(CallRecord a:callRecords){
         sum += 0.6 * ((((a.getEndTime().getTime() - a.getStartTime().getTime())/1000)+59)/60);
    }
        return sum;
    }
}
class LandPhoneInProvinceRule extends CallChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
         double sum = 0;
         for(CallRecord a:callRecords){
         sum += 0.3 * ((((a.getEndTime().getTime() - a.getStartTime().getTime())/1000)+59)/60);
    }
        return sum;
    }
}

public class Main {

	public static void main(String[] args) throws ParseException {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		String s0 = "u-079[0-9][0-9]{7,8} 0" ;
        String s1 = "u-0701[0-9]{7,8} 0";
        String s2 = "t-[0-9]{10,12} [0-9]{10,12} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2}";
        String s3 = "0791";
        String s4 = "079[0-9]";
        String s5 = "0701";
        String s6 = "[0-9]{3,4}";
        String s7 = "[0-9]{11}";
        String s8 = "u-[0-9]{11} 1";
        String s9 = "t-[0-9]{10,12} [0-9]{11} [0-9]{3,4} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2}";
        String s10 = "t-[0-9]{11} [0-9]{3,4} [0-9]{11} [0-9]{3,4} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2}";
        String s11 = "t-[0-9]{11} [0-9]{3,4} [0-9]{10,12} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2}";
        String s12 = "[0-9]{10,12}";
        String s13 = "0791[0-9]{7,8}";
        String s14 = "079[0-9]{8,9}";
        String s15 = "0701[0-9]{7,8}";
        String s16 = "[0-9]{10,12}";       
		ArrayList<User>list = new ArrayList<>();
		String s = in.nextLine();
		while(!s.matches(s9)&&!s.matches(s10)&&!s.matches(s11)){
            User a = new User();
            if(s.matches(s0)||s.matches(s1)||s.matches(s8)){
                a.setNumber((String) s.subSequence(2, s.length()-2));
                int flag = 0;
                for(User b :list) {
                    if(b.getNumber().equals((String) s.subSequence(2, s.length()-2))) {
                        flag++;
                    }
                }
                if(flag==0)
                list.add(a);
            }
                s = in.nextLine();
            if(s.equals("end")){
                break;
            }
        }
        while(!s.equals("end")) {
            if(s.matches(s2)) {
                String str[] = s.split(" ");
                String num1 = str[0].substring(2);
                String num2 = str[1];
                String starttime = str[2]+" "+str[3];
                String endtime = str[4]+" "+str[5];
                if(check(starttime)&&check(endtime)) {
                    for(int i = 0;i<list.size();i++) {
                        if(list.get(i).getNumber().equals(num1)&&num2.matches(s13)) {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            list.get(i).getUserRecords().addCallinglnCityRecords(callRecords);
                        }
                        else if(list.get(i).getNumber().equals(num1)&&(num2.matches(s14)||num2.matches(s15))&&!num2.matches(s13)) {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            list.get(i).getUserRecords().addCallinglnProvinceRecords(callRecords);
                        }
                        else if(list.get(i).getNumber().equals(num1)&&!num2.matches(s13)&&!num2.matches(s14)&&!num2.matches(s15)&&num2.matches(s16)) {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            list.get(i).getUserRecords().addCallinglnLandRecords(callRecords);
                        }
                    }
                }

            }

            if(s.matches(s9)) {
                String str[] = s.split(" ");
                String num1 = str[0].substring(2);
                String num2 = str[1];
                String place = str[2];
                String starttime = str[3]+" "+str[4];
                String endtime = str[5]+" "+str[6];
                if(check(starttime)&&check(endtime)) {
                    for(int i = 0;i<list.size();i++) {
                        if(list.get(i).getNumber().equals(num1)&&place.matches(s3)) {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            list.get(i).getUserRecords().addCallinglnCityRecords(callRecords);
                        }
                        else if(list.get(i).getNumber().equals(num1)&&(place.matches(s4)||place.matches(s5))&&!place.matches(s3)) {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            list.get(i).getUserRecords().addCallinglnProvinceRecords(callRecords);
                        }
                        else if(list.get(i).getNumber().equals(num1)&&!place.matches(s3)&&!place.matches(s4)&&!place.matches(s5)&&place.matches(s6)) {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            list.get(i).getUserRecords().addCallinglnLandRecords(callRecords);
                            for(int j = 0;j<list.size();j++) {
                                if(list.get(j).getNumber().equals(num2)) {
                                    list.get(j).getUserRecords().addAnswerlnLandRoamRecords(callRecords);
                                }
                            }
                            break;
                        }
                        else
                        if(list.get(i).getNumber().equals(num2)&&!place.matches(s3)&&!place.matches(s4)&&!place.matches(s5)&&place.matches(s6))
                        {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            for(int j = 0;j<list.size();j++) {
                                if(list.get(j).getNumber().equals(num2)) {
                                    list.get(j).getUserRecords().addAnswerlnLandRoamRecords(callRecords);
                                }
                        }
                        }
                        break;
                    }
                }
            }
            if(s.matches(s10)) {
                String str[] = s.split(" ");
                String num1 = str[0].substring(2);
                String place1 = str[1];
                String num2 = str[2];
                String place2 = str[3];
                String starttime = str[4]+" "+str[5];
                String endtime = str[6]+" "+str[7];
                if(check(starttime)&&check(endtime)) {
                    for(int i = 0;i<list.size();i++) {
                        if(place1.matches(s3))
                        {
                            if(list.get(i).getNumber().equals(num1)&&place2.matches(s3)) {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addCallinglnCityRecords(callRecords);
                                break;
                            }
                            else if(list.get(i).getNumber().equals(num1)&&(place2.matches(s4)||place2.matches(s5))&&!place2.matches(s3)) {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addCallinglnProvinceRecords(callRecords);
                                break;
                            }
                            else if(list.get(i).getNumber().equals(num1)&&!place2.matches(s3)&&!place2.matches(s4)&&!place2.matches(s)&&place2.matches(s6)) {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addCallinglnLandRecords(callRecords);
                                for(int j = 0;j<list.size();j++) {
                                    if(list.get(j).getNumber().equals(num2)&&num1!=num2) {
                                        list.get(j).getUserRecords().addAnswerlnLandRoamRecords(callRecords);
                                    }
                                }
                                break;
                            }
                            else if(list.get(i).getNumber().equals(num2)&&!place2.matches(s3)&&!place2.matches(s4)&&!place2.matches(s5)&&place2.matches(s6))
                            {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addAnswerlnLandRoamRecords(callRecords);
                                break;
                            }
                        }
                        if((place1.matches(s4)||place1.matches(s5))&&!place1.matches(s3))
                        {
                            if(list.get(i).getNumber().equals(num1)&&place2.matches(s3)) {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addCallinglnProvinceRoamRecords(callRecords);
                                break;
                            }
                            else if(list.get(i).getNumber().equals(num1)&&(place2.matches(s4)||place2.matches(s5))&&!place2.matches(s3)) {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addCallinglnProvinceRoamRecords(callRecords);
                                break;
                            }
                            else if(list.get(i).getNumber().equals(num1)&&!place2.matches(s3)&&!place2.matches(s4)&&!place2.matches(s5)&&place2.matches(s6)) {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addCallinglnProvinceRoamRecords(callRecords);
                                for(int j = 0;j<list.size();j++) {
                                    if(list.get(j).getNumber().equals(num2)&&num1!=num2) {
                                        list.get(j).getUserRecords().addAnswerlnLandRoamRecords(callRecords);
                                    }
                                }
                                break;
                            }
                            else if(list.get(i).getNumber().equals(num2)&&!place2.matches(s3)&&!place2.matches(s4)&&!place2.matches(s5)&&place2.matches(s6))
                            {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addAnswerlnLandRoamRecords(callRecords);
                                break;
                            }

                        }
                        if(!place1.matches(s3)&&!place1.matches(s4)&&!place1.matches(s5)&&place1.matches(s6))
                        {
                            if(list.get(i).getNumber().equals(num1)&&place2.matches(s3)) {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addCallinglnLandRoamRecords(callRecords);
                                break;
                            }
                            else if(list.get(i).getNumber().equals(num1)&&(place2.matches(s4)||place2.matches(s5))&&!place2.matches(s3)) {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addCallinglnLandRoamRecords(callRecords);
                                break;
                            }
                            else if(list.get(i).getNumber().equals(num1)&&!place2.matches(s3)&&!place2.matches(s4)&&!place2.matches(s5)&&place2.matches(s6)) {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addCallinglnLandRoamRecords(callRecords);
                                for(int j = 0;j<list.size();j++) {
                                    if(list.get(j).getNumber().equals(num2)&&num1!=num2) {
                                        list.get(j).getUserRecords().addAnswerlnLandRoamRecords(callRecords);
                                    }
                                }
                                break;
                            }
                            else if(list.get(i).getNumber().equals(num2)&&!place2.matches(s3)&&!place2.matches(s4)&&!place2.matches(s5)&&place2.matches(s6))
                            {
                                CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                                list.get(i).getUserRecords().addAnswerlnLandRoamRecords(callRecords);
                                for(int j = 0;j<list.size();j++) {
                                    if(list.get(j).getNumber().equals(num1)&&num1!=num2) {
                                        list.get(j).getUserRecords().addCallinglnLandRoamRecords(callRecords);
                                    }
                                }
                                break;
                            }
                        }

                    }
                }
            }
            if(s.matches(s11)) {
                String str[] = s.split(" ");
                String num1 = str[0].substring(2);
                String place = str[1];
                String num2 = str[2];
                String starttime = str[3]+" "+str[4];
                String endtime = str[5]+" "+str[6];
                if(check(starttime)&&check(endtime)) {
                    for(int i = 0;i<list.size();i++) {
                        if(list.get(i).getNumber().equals(num1)&&place.matches(s3)) {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            list.get(i).getUserRecords().addCallinglnCityRecords(callRecords);

                        }
                        else
                        if(list.get(i).getNumber().equals(num1)&&(place.matches(s4)||place.matches(s5))&&!place.matches(s3)) {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            list.get(i).getUserRecords().addCallinglnProvinceRoamRecords(callRecords);
                        }
                        else
                        if(list.get(i).getNumber().equals(num1)&&!place.matches(s3)&&!place.matches(s4)&&!place.matches(s5)&&place.matches(s6)) {
                            CallRecord callRecords = new CallRecord(starttime, endtime, num1, num2);
                            list.get(i).getUserRecords().addCallinglnLandRoamRecords(callRecords);
                        }
                    }
                }
            }
            s = in.nextLine();
        }
        for(int i = 0;i<list.size();i++) {
            if(list.get(i).getNumber().matches(s6)) {
                list.get(i).calBalance();
                list.get(i).calCost();
            }
            if(list.get(i).getNumber().matches(s7)) {
                list.get(i).calBalance1();
                list.get(i).calCost1();
            }
            for(int j = 0;j<list.size()-1;j++) {
                if(list.get(j).getNumber().compareTo(list.get(j+1).getNumber())>0) {
                    Collections.swap(list, j, j+1);
                }
            }
        }
            for(User l : list) {
                if(l.getNumber().charAt(0)=='0') {
                    System.out.printf("%s %.1f %.1f\n",l.getNumber(),l.calCost(),l.calBalance());
                }
                if(l.getNumber().charAt(0)=='1') {
                    System.out.printf("%s %.1f %.1f\n",l.getNumber(),l.calCost1(),l.calBalance1());
                }

            }
	}
	
	public static boolean check(String s) {
		SimpleDateFormat a = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
		try {
			a.setLenient(false);
			a.parse(s);
		}catch(Exception e) {
			return false;
		}
		return true;
	}
}

class MessageRecord {
    private String message;

    public String getMessage() {
        return message;
    }

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

}

class SmartlinePhoneCharging extends ChargeMode{
    private double monthlyRent = 15;

    public double getMonthlyRent() {
        return monthlyRent;
    }
    public double calCost(UserRecords userRecords) {
        double calcost = 0;
        SmartPhoneInCityRule smartPhoneInCityRule = new SmartPhoneInCityRule();
        SmartPhoneInProvinceRule smartPhoneInProvinceRule = new SmartPhoneInProvinceRule();
        SmartPhoneInLandRule smartPhoneInLandRule = new SmartPhoneInLandRule();
        SmartPhoneInProvinceRoamRule smartPhoneInProvinceRoamRule = new SmartPhoneInProvinceRoamRule();
        SmartPhoneInLandCallingRoamRule smartPhoneInLandCallingRoamRule = new SmartPhoneInLandCallingRoamRule();
        SmartPhoneInLandAnswerRoamRule smartPhoneInLandAnswerRoamRule = new SmartPhoneInLandAnswerRoamRule();
        calcost = smartPhoneInCityRule.calCost(userRecords.getCallinglnCityRecords()) + smartPhoneInProvinceRule.calCost(userRecords.getCallinglnProvinceRecords()) + smartPhoneInLandRule.calCost(userRecords.getCallinglnLandRecords()) + smartPhoneInProvinceRoamRule.calCost(userRecords.getCallinglnProvinceRoamRecords()) + smartPhoneInLandCallingRoamRule.calCost(userRecords.getCallinglnLandRoamRecords()) + smartPhoneInLandAnswerRoamRule.calCost(userRecords.getAnswerlnLandRoamRecords());
        return calcost;
    }
}
class SmartPhoneInCityRule extends CallChargeRule{

	@Override
	public double calCost(ArrayList<CallRecord> callRecords) {

        double sum = 0;
		for(CallRecord a:callRecords) {
			 sum += 0.1 * ((((a.getEndTime().getTime() - a.getStartTime().getTime())/1000)+59)/60);
		}
		return sum;
	}
	
}

class SmartPhoneInLandAnswerRoamRule extends CallChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
         double sum = 0;
         for(CallRecord a:callRecords){
         sum += 0.3 * ((((a.getEndTime().getTime() - a.getStartTime().getTime())/1000)+59)/60);
    }
        return sum;
    }
}

class SmartPhoneInLandCallingRoamRule extends CallChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
         double sum = 0;
         for(CallRecord a:callRecords){
         sum += 0.6 * ((((a.getEndTime().getTime() - a.getStartTime().getTime())/1000)+59)/60);
    }
        return sum;
    }
}

class SmartPhoneInLandRule extends CallChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
         double sum = 0;
         for(CallRecord a:callRecords){
         sum += 0.3 * ((((a.getEndTime().getTime() - a.getStartTime().getTime())/1000)+59)/60);
    }
        return sum;
    }
}

class SmartPhoneInProvinceRoamRule extends CallChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
         double sum = 0;
         for(CallRecord a:callRecords){
         sum += 0.3 * ((((a.getEndTime().getTime() - a.getStartTime().getTime())/1000)+59)/60);
    }
        return sum;
    }
}

class SmartPhoneInProvinceRule extends CallChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
         double sum = 0;
         for(CallRecord a:callRecords){
         sum += 0.2 * ((((a.getEndTime().getTime() - a.getStartTime().getTime())/1000)+59)/60);
    }
        return sum;
    }
}
class User {
    private UserRecords userRecords = new UserRecords();
    private double balance = 100 ;
    private ChargeMode chargeMode0;
    private ChargeMode chargeMode1;
    private String number;
    public User() {
        super();
        this.chargeMode0 = new LandlinePhoneCharging();
        this.chargeMode1 = new SmartlinePhoneCharging();
    }

    public double calBalance() {
        double Balance = 0;
        Balance = getBalance() - calCost() - getChargeMode().getMonthlyRent();
        return Balance;
    }
    public double calCost() {
        double sum = 0;
        sum = getChargeMode().calCost(getUserRecords());
        return sum;
    }
    public double calBalance1() {
        double Balance = 0;
        Balance = getBalance() - calCost1() - getChargeMode1().getMonthlyRent();
        return Balance;
    }
    public double calCost1() {
        double sum = 0;
        sum = getChargeMode1().calCost(getUserRecords());
        return sum;
    }
    public UserRecords getUserRecords() {
        return userRecords;
    }
    public void setUserRecords(UserRecords userRecords) {
        this.userRecords = userRecords;
    }
    public double getBalance() {
        return balance;
    }
    public ChargeMode getChargeMode() {
        return chargeMode0;
    }
    public void setChargeMode(ChargeMode chargeMode) {
        this.chargeMode0 = chargeMode;
    }
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }

    public ChargeMode getChargeMode1() {
        return chargeMode1;
    }

    public void setChargeMode1(ChargeMode chargeMode1) {
        this.chargeMode1 = chargeMode1;
    }

}

class UserRecords {

    private ArrayList<CallRecord> callinglnCityRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> callinglnProvinceRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> callinglnLandRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> answerlnCityRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> answerlnProvinceRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> answerlnLandRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> callinglnProvinceRoamRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> callinglnLandRoamRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> answerlnLandRoamRecords = new ArrayList<CallRecord>();
    private ArrayList<MessageRecord> sendMessageReconds = new ArrayList<MessageRecord>();
    private ArrayList<MessageRecord> receiveMessageReconds = new ArrayList<MessageRecord>();

    public ArrayList<CallRecord> getCallinglnCityRecords() {
        return callinglnCityRecords;
    }
    public void addCallinglnCityRecords(CallRecord callRecord) {
        callinglnCityRecords.add(callRecord);
    }
    public ArrayList<CallRecord> getCallinglnProvinceRecords() {
        return callinglnProvinceRecords;
    }
    public void addCallinglnProvinceRecords(CallRecord callRecord) {
        callinglnProvinceRecords.add(callRecord);
    }
    public ArrayList<CallRecord> getCallinglnLandRecords() {
        return callinglnLandRecords;
    }
    public void addCallinglnLandRecords(CallRecord callRecord) {
        callinglnLandRecords.add(callRecord);
    }
    public ArrayList<CallRecord> getAnswerlnCityRecords() {
        return answerlnCityRecords;
    }
    public void addAnswerlnCityRecords(CallRecord callRecord) {
        answerlnCityRecords.add(callRecord);
    }
    public ArrayList<CallRecord> getAnswerlnProvinceRecords() {
        return answerlnProvinceRecords;
    }
    public void addAnswerlnProvinceRecords(CallRecord callRecord) {
        answerlnProvinceRecords.add(callRecord);
    }
    public ArrayList<CallRecord> getAnswerlnLandRecords() {
        return answerlnLandRecords;
    }
    public void addAnswerlnLandRecords(CallRecord callRecord) {
        answerlnLandRecords.add(callRecord);
    }
    public ArrayList<MessageRecord> getSendMessageReconds() {
        return sendMessageReconds;
    }
    public void addSendMessageReconds(MessageRecord messageRecord) {
        sendMessageReconds.add(messageRecord);
    }
    public ArrayList<MessageRecord> getReceiveMessageReconds() {
        return receiveMessageReconds;
    }
    public void addReceiveMessageReconds(MessageRecord messageRecord) {
        receiveMessageReconds.add(messageRecord);
    }
    public ArrayList<CallRecord> getCallinglnProvinceRoamRecords() {
        return callinglnProvinceRoamRecords;
    }
    public void addCallinglnProvinceRoamRecords(CallRecord callRecord) {
        callinglnProvinceRoamRecords.add(callRecord);
    }
    public ArrayList<CallRecord> getCallinglnLandRoamRecords() {
        return callinglnLandRoamRecords;
    }
    public void addCallinglnLandRoamRecords(CallRecord callRecord) {
        callinglnLandRoamRecords.add(callRecord);
    }
    public ArrayList<CallRecord> getAnswerlnLandRoamRecords() {
        return answerlnLandRoamRecords;
    }
    public void addAnswerlnLandRoamRecords(CallRecord callRecord) {
        answerlnLandRoamRecords.add(callRecord);
    }


	
	

  sourceMonitor图:

 

 

 

 分析:

本题在之前的基础上增加算钱的类,依旧利用正则表达式判别输入字符串后进行操作

    3.题目三:7-1 电信计费系列3-短信计费

 

 

 

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

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

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

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

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

image.png

图1

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

image.png

图2

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

image.png

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

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

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

源码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
import java.text.ParseException;

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

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

    public void setChargeRules(ArrayList<ChargeRule> chargeRules) {

    }
    public double calCost(UserRecords userRecords) {
        return 0;

    }
    public double getMonthlyRent() {
        return 0;

    }
}

abstract class ChargeRule {

}

public class Main {

	public static void main(String[] args) throws ParseException{
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
        String s1 = "[0-9]{11}";
        String s2 = "u-[0-9]{11} 3";
        String s3 = "m-[0-9]{11} [0-9]{11} ";
        String s4 = "m-[0-9]{11}";
        String s5 = "m-[0-9]{11} [0-9]{11} [0-9|a-z|A-Z|\\s|\\.|\\,]+";
        ArrayList<User> list = new ArrayList<User>();
        String s = in.nextLine();
        while(!s.matches(s5)){
            User a = new User();
            if(s.matches(s2)){
                a.setNumber((String) s.subSequence(2, s.length()-2));
                int flag = 0;
                for(User b :list) {
                    if(b.getNumber().equals((String) s.subSequence(2, s.length()-2))) {
                        flag++;
                    }
                }
                if(flag==0)
                list.add(a);
            }
                s = in.nextLine();
            if(s.equals("end")){
                break;
            }
        }
        while(!s.equals("end")) {

            if(s.matches(s5)) {
                String str[] = ((String) s.subSequence(0, 25)).split(" ");
                String num1 = str[0].substring(2);
                String num2 = str[1];
                String message = s.substring(26,s.length());

                    for(int i = 0;i<list.size();i++) {
                        if(list.get(i).getNumber().equals(num1)) {
                            MessageRecord messageRecord = new MessageRecord(message,num1,num2);
                            list.get(i).getUserRecords().addSendMessageReconds(messageRecord);
                        }

                    }

            }
            s = in.nextLine();
        }
        for(int i = 0;i<list.size();i++) {
            if(list.get(i).getNumber().matches(s1)) {
                list.get(i).calBalance();
                list.get(i).calCost();
            for(int j = 0;j<list.size()-1;j++) {
                if(list.get(j).getNumber().compareTo(list.get(j+1).getNumber())>0) {
                    Collections.swap(list, j, j+1);
                }
            }
        }
        }
            for(User l : list) {
                    System.out.printf("%s %.1f %.1f\n",l.getNumber(),l.calCost(),l.calBalance());
            }



}

}

abstract class MessageChargeRule extends ChargeRule{
        public double calCost(ArrayList<MessageRecord>messageRecord) {
            return 0;

        }
}

class MessageCharging extends ChargeMode{
        public double calCost(UserRecords userRecords) {
            double calcost = 0;
            SendMessageRule sendMessageRule = new SendMessageRule ();
            calcost = sendMessageRule.calCost(userRecords.getSendMessageReconds());
            return calcost;
        }

}

class MessageRecord {

    private String message;
    private String callingAddressAreaCode;
    private String answerAddressAreaCode;

    public MessageRecord(String message, String callingAddressAreaCode, String answerAddressAreaCode) {
        super();
        this.message = message;
        this.callingAddressAreaCode = callingAddressAreaCode;
        this.answerAddressAreaCode = answerAddressAreaCode;
    }


    public String getMessage() {
        return message;
    }

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


}

class SendMessageRule extends MessageChargeRule{

    @Override
    public double calCost(ArrayList<MessageRecord> messageRecord) {
        // TODO Auto-generated method stub
        double calcost = 0;
        int sum0 = 0;
        for(MessageRecord messagerecord : messageRecord) {
            int sum = 0;
            if(messagerecord.getMessage().length()%10==0)
            sum = messagerecord.getMessage().length()/10;
            else {
                sum = messagerecord.getMessage().length()/10 + 1;
            }
            sum0 += sum;
        }
        if(sum0<=3) {
            calcost = 0.1*sum0;
        }
        if(sum0>3&&sum0<=5) {
            calcost = 0.1*3 + (sum0-3)*0.2;
        }
        if(sum0>5) {
            calcost = 0.1*3 + 0.2*2 + 0.3*(sum0-5);
        }
        return calcost;
    }

}


class User {
    private UserRecords userRecords = new UserRecords();
    private double balance = 100 ;
    private ChargeMode chargeMode;
    private String number;
    public User() {
        super();
        this.chargeMode = new MessageCharging();
    }

    public double calBalance() {
        double Balance = 0;
        Balance = getBalance() - calCost();
        return Balance;
    }
    public double calCost() {
        double sum = 0;
        sum = getChargeMode().calCost(getUserRecords());
        return sum;
    }
    public UserRecords getUserRecords() {
        return userRecords;
    }
    public void setUserRecords(UserRecords userRecords) {
        this.userRecords = userRecords;
    }
    public double getBalance() {
        return balance;
    }
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }

    public ChargeMode getChargeMode() {
        return chargeMode;
    }

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

}

class UserRecords {

    private ArrayList<MessageRecord> sendMessageReconds = new ArrayList<MessageRecord>();
    private ArrayList<MessageRecord> receiveMessageReconds = new ArrayList<MessageRecord>();


    public ArrayList<MessageRecord> getSendMessageReconds() {
        return sendMessageReconds;
    }
    public void addSendMessageReconds(MessageRecord messageRecord) {
        sendMessageReconds.add(messageRecord);
    }
    public ArrayList<MessageRecord> getReceiveMessageReconds() {
        return receiveMessageReconds;
    }
    public void addReceiveMessageReconds(MessageRecord messageRecord) {
        receiveMessageReconds.add(messageRecord);
    }



}

  类图:

 

 

三、踩坑心得

   这三次计费的训练,和多边形一样,一层一层迭代,只要前面类图编写合理,后面的运用就会非常轻松。要理解给定类图,并编写代码。要保持高质量的正则表达式,对方法的书写也要合理,保证代码可扩展性

 

四、改进建议

  由于已经给定了类图,对于类图的设计并无需要改进的地方,但是题目中的一些测试点还是不太理解,有些情况并未完善,有待完善

五、总结

   通过这三次电话计费类程序的编写,我发现了自己还存在很多不足的地方,编写代码的能力还需要提升。这几次题目对于正则表达式的训练需要加强,对类与类之间的关系要有一个清晰的认识。要去提高自己自学能力,提高学习的主动性,在今后的学习中还需更加努力  

标签:return,String,double,ArrayList,BLOG,new,public
From: https://www.cnblogs.com/dream-1/p/16946328.html

相关文章

  • 基于yolo进行目标检测的实验和研究【BLOG】
          根据我接触到的项目经验来看,需要我们进行检测的不是自然场景下的任意物体,而是特定场景下一类物体。典型的就是钢管识别,这些照片一般都是在厂区里面拍的、......
  • 介绍一个JAVA的开源blog--APACHE ROLLER
    开源的BLOG系统,最推荐的依然是PHP的,非常多选择,JAVA的可选择的不多,但今天居然发现一个APACHE的顶级项目roller,项目地址是​​​http://rolller.......
  • weblogic12版本节点启动报错问题处理
    问题:<Sep12,202211:00:13AMCST><Warning><DeploymentService><BEA-290074><Deploymentserviceservletreceivedfiledownloadrequestforfile"security/Se......
  • 使用cnblog上传markdown文件到博客园
    下载并且安装python3地址:https://www.python.org/安装完以后:下载pycnblog地址:https://github.com/dongfanger/pycnblo将下载的pycnblog工具解压,打开config.yaml......
  • weblogic优化
    一、登录web界面卡顿[root@localhostsecurity]#find/-namejava.security/apppackage/jdk1.8.0_311/jre/lib/security/java.security[root@localhostsecurity]#cat......
  • dblogin登陆数据库时报错ORA-04060
    问题描述:dblogin登陆数据库时报错ORA-04060,如下所示:oracle:11.2.0.4GGSCI(leo-11g-ogg)5>dbloginuseridogg,passwordogg2022-12-0112:19:49WARNINGOGG-25108Fail......
  • Blog模板设计-Markdown
    其他工具推荐:​​文章模板生成​​​​微信二维码设计​​​​部分图片来源​​Blog-封面SloganBlog-开篇SloganHere’sthetableofcontents:Markdown使用教程Markdown......
  • Weblogic Cluster BEA-000116故障处理
    部署环境:Weblogic10MP2forUNIX实验:WeblogicCluster:(MServer1,MServer2)7222MulticastIP:239.192.0.0AdminServer:192.168.1.33:7001MServer1:192.168.1.33......
  • WebLogic ClassLoader
    WebLogicClassLoaderWeblogic中发布的一个应用一般目录结构如下对应的各层级结构如下ApplicationClassLoader用来加载EJBJARS、APP-INF/lib、APP-INF/classes、EJBJARS......
  • https://www.cnblogs.com/liyue3/p/16924616.html
    Android12源码网盘下载路径:“iTOP-3588开发板\01_【1TOP-RK3588开发板】基础资料\03_iTOP-RK3588开发板Android12源码”源码是分卷压缩包,需要全部下载下来放在同......