Boke-Liu的BLOG-3

一、前言

  最近这段时间在PTA做了三次的电信计费系列题目,先做个总结:

  1、题目集八是座机计费,主要考查了抽象类,继承与多态等知识,由于给出了类图,题目变得更简单,不需要我们自己做类设计,可以参考给出的类图,根据要求进行补充。内容主要是先输入开户信息和计费类型,在输入通讯信息,根据通讯信息判断通话类型和根据通话时间计算通话费用,接电话不计费,最后输出已开户用户的号码、消费金额和余额。

  2、题目集九是手机+座机计费,相对于单纯的座机计费新增加了手机计费的功能,包括四种类型的计费,座机打座机,座机打手机,手机打座机,手机打手机,计费方式也新增加了漫游,类型更多种,需要在原来类的基础上增加内容,也需要增加新的类,难度也增加了不少

  3、题目集十是短信计费,相对于前面两次,难度没有这么大,计费类型也和前两次不一样,前两次是计算每次的通讯费用再相加,短信计费必须先算总的短信条数,再计算短信费用,类设计也给出了提示,在原来的基础上进行增加补充

二、设计与分析

  1、电信计费系列1-座机计费,题目要求如下:

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

  代码如下:

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

public class Main {

    public static void main(String[] args) throws ParseException {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        List<User> users = new ArrayList<>();
        String s = "";
        ArrayList<String> strList = new ArrayList<String>();
        while(!s.equals("end")){
            s = in.nextLine();
            strList.add(s);
        }
        in.close();
        for(int i = 0;i<strList.size();i++) {
            
            if(strList.get(i).length() <=11)
                continue;
            char []b=strList.get(i).toCharArray();
            String[] a = strList.get(i).split("\\s+");
            String c=a[0].substring(2);
            boolean judge = true;
            boolean judge1 = true;
            boolean judge2 = false;
            String regEx= "u-0791[0-9]{7,8}\\s[0-2]";
            String regEx1= "t-0791[0-9]{7,8}\\s[0-9]{10,12}\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d";
            judge=strList.get(i).matches(regEx);
            judge1=strList.get(i).matches(regEx1);
            for(int j = 0;j<i;j++) {
                if(strList.get(i).equals(strList.get(j)))
                    judge2=true;
            }
            if(judge==false&&judge1==false)
                continue;
            else if(judge2) {
                continue;
            }
            else {
                if(b[0]==117) {
                    User user = new User();
                    user.setNumber(c);
                    ChargeMode chargeMode = new LandlinePhoneCharging();
                    ArrayList<ChargeRule> chargeRules = new ArrayList<>(3);
                    chargeRules.add(new LandPhoneInCityRule());
                    chargeRules.add(new LandPhoneInProvinceRule());
                    chargeRules.add(new LandPhoneInLandRule());
                    chargeMode.setChargeRules(chargeRules);
                    user.setChargeMode(chargeMode);
                    users.add(user);
                }
                if(b[0]==116) {
                    String[] d = a[2].split("\\.");
                    String[] d1 = a[4].split("\\.");
                    int year = Integer.parseInt(d[0]);
                    int month = Integer.parseInt(d[1]);
                    int day = Integer.parseInt(d[2]);
                    int year1 = Integer.parseInt(d1[0]);
                    int month1 = Integer.parseInt(d1[1]);
                    int day1 = Integer.parseInt(d1[2]);
                    
                    Check check = new Check(year, month, day);
                    Check check1 = new Check(year1, month1, day1);
                    if(check.checkInputValidity()&&check1.checkInputValidity()&&check.compareDates(check1)) {
                        String callingNumber = c;
                        String answerNumber = a[1];
                        String callingAddressAreaCode = c.substring(0, 4);
                        String answerAddressAreaCode = a[1].substring(0, 4);
                        String startTimeStr = a[2] + " " + a[3];
                        String endTimeStr = a[4] + " " + a[5];
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
                        Date startTime = sdf.parse(startTimeStr);
                        Date endTime = sdf.parse(endTimeStr);
                        CallRecord callRecord = new CallRecord();
                        callRecord.setCallingNumber(callingNumber);
                        callRecord.setAnswerNumber(answerNumber);
                        callRecord.setCallingAddressAreaCode(callingAddressAreaCode);
                        callRecord.setAnswerAddressAreaCode(answerAddressAreaCode);
                        callRecord.setStartTime(startTime);
                        callRecord.setEndTIme(endTime);
                        for (User user : users) {
                            if (user.getNumber().equals(callingNumber)) {
                                UserRecords userRecords = user.getUserRecords();
                                if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                    userRecords.addCallingInCityRecords(callRecord);
                                } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                    userRecords.addCallingInProvinceRecords(callRecord);
                                } else {
                                    userRecords.addCallingInLandRecords(callRecord);
                                }
                            }
                            if (user.getNumber().equals(answerNumber)) {
                                UserRecords userRecords = user.getUserRecords();
                                if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                    userRecords.addAnswerInCityRecords(callRecord);
                                } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                    userRecords.addAnswerInProvinceRecords(callRecord);
                                } else {
                                    userRecords.addAnswerInLandRecords(callRecord);
                                }
                            }
                       }
                    }

                }
            }
            
        }
        for (int i = 0; i < users.size() - 1; i++) {
            for (int j = 0; j < users.size() - 1 - i; j++) {
                User temp;
                if (users.get(j).getNumber().compareTo(users.get(j + 1).getNumber()) > 0) {
                    temp = users.get(j);
                    users.set(j, users.get(j + 1));
                    users.set(j + 1, temp);
                }
            }
        }
        for (User user : users) {
            String number = user.getNumber();
            double calCost = user.calCost();
            double balance = user.calBalance();
            System.out.println(number + " " + calCost + " " + balance);
        }
    }

}
class Check{
    private int day;
    private int month;
    private int year;
    
    public Check(int year,int month,int day) {
        this.day = day;
        this.month = month;
        this.year = year;
    }
    
    public boolean checkInputValidity() {
        boolean a;
        int[] n = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
        {
            n[2] = 29;
        }
        if(month>0&&month<=12&&day<=n[month]&&day>0) {
            a = true;
        }
        else {
            a = false;
        }
        return a;
    }
    
    public static boolean isLeapYear(int year) //判断year是否为闰年,返回boolean类型;
    {
        
        if((year%4 == 0&&year%100 != 0)||(year%400 == 0))
            return true;
            else return false;
    }
    
    public boolean compareDates(Check date) {
        if(year>date.year) {
            return false;
        }
        else if(year<date.year){
            return true;
        }
        else {
            if(month>date.month) {
                return false;
            }
            else if(month<date.month) {
                return true;
            }
            else {
                if(day>date.day) {
                    return false;
                }
                else {
                    return true;
                }
            }
        }
    }

}


abstract class CallChargeRule extends ChargeRule{
    public abstract double calCost(ArrayList<CallRecord> callRecords);
}
class CallRecord extends CommunicationRecord {
    Date startTime;
    Date endTIme;
    String callingAddressAreaCode;
    String 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) {
        this.chargeRules = chargeRules;
    }
    
    public abstract double calCost(UserRecords userRecords);
    
    public abstract double getMonthlyRent();
    
}
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 {
    double monthlyRent = 20;

    @Override
    public double calCost(UserRecords userRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for (ChargeRule chargeRule : getChargeRules()) {
            if (chargeRule instanceof LandPhoneInCityRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInCityRecords());
            }
            if (chargeRule instanceof LandPhoneInProvinceRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInProvinceRecords());
            }
            if (chargeRule instanceof LandPhoneInLandRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInLandRecords());
            }
        }
        return sum;
    }

    @Override
    public double getMonthlyRent() {
        // TODO Auto-generated method stub
        return monthlyRent;
    }

    
}
class LandPhoneInCityRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.1*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class LandPhoneInLandRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.6*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class LandPhoneInProvinceRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.3*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class MessageRecord extends CommunicationRecord {
    String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
    
}
class User {
    UserRecords userRecords = new UserRecords();
    double balance = 100;
    ChargeMode chargeMode;
    String number;
    
    public double calBalance() {
        return balance-chargeMode.calCost(userRecords)-chargeMode.getMonthlyRent();
    }
    public double calCost() {
        return Double.valueOf(new DecimalFormat("#.00").format(chargeMode.calCost(userRecords)));
    }
    
    public UserRecords getUserRecords() {
        return userRecords;
    }
    
    public void setUserRecords(UserRecords userRecords) {
        this.userRecords = userRecords;
    }
    
    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;
    }
    
}
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>();
    
    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 answerRecord) {
        answerInProvinceRecords.add(answerRecord);
    }
    
    public void addAnswerInLandRecords(CallRecord answerRecord) {
        answerInLandRecords.add(answerRecord);
    }
    
    public void addSendMessageRecords(MessageRecord sendMessageRecord) {
        sendMessageRecords.add(sendMessageRecord);
    }
    
    public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) {
        receiveMessageRecords.add(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;
    }


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


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

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

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

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

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

  CallRecord(通话记录类)包含属性: 通话的起始、结束时间以及 拨号地点的区号(callingAddressAreaCode)、接听地 点的区号(answerAddressAreaCode)。

  区号用于记录在哪个地点拨打和接听的电话。对于座机,就是本机区号。如果是手机 号,则接打地点的区号和本机的开户地区会有差异。

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

  LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别 是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。

  主方法里运用了List储存开户用户数据,也运用了冒泡排序对开户用户实现按顺序输出,对于通讯信息也运用了字符串的知识对字符串进行截取、转换为字符数组等。将截取出来的信息分别传给对于类的对象实现计算话费等功能。

类图如下:

 

  2、电信计费系列2-手机+座机计费,题目要求如下:

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

  针对手机用户采用实时计费方式: 月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电 话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话(无论打哪里)0.3元/分 钟,省外漫游接听0.3元/分钟,省外漫游拨打(无论打哪里)0.6元/分钟; 注:被叫电话属于市内、省内、国内由被叫电话的接听地点区号决定。

  代码如下:

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

public class Main {

    public static void main(String[] args) throws ParseException {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        List<User> users = new ArrayList<>();
        String s = "";
        ArrayList<String> strList = new ArrayList<String>();
        while(!s.equals("end")){
            s = in.nextLine();
            strList.add(s);
        }
        in.close();
        for(int i = 0;i<strList.size();i++) {
            
            if(strList.get(i).length() <=11)
                continue;
            char []b=strList.get(i).toCharArray();
            String[] a = strList.get(i).split("\\s+");
            String c=a[0].substring(2);
            boolean judge = true;
            boolean judge1 = true;
            boolean judge2 = true;
            boolean judge3 = true;
            boolean judge4 = true;
            boolean judge5 = true;
            boolean judge6 = false;
            String regEx= "u-0[0-9]{9,11}\\s0";
            String regEx1= "t-0[0-9]{9,11}\\s0[0-9]{9,11}\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d";
            String regEx2="u-1[0-9]{10}\\s1";
            String regEx3="t-0[0-9]{9,11}\\s1[0-9]{10}\\s0[0-9]{2,3}\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d";
            String regEx4="t-1[0-9]{10}\\s0[0-9]{2,3}\\s0[0-9]{9,11}\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d";
            String regEx5="t-1[0-9]{10}\\s0[0-9]{2,3}\\s1[0-9]{10}\\s0[0-9]{2,3}\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s[1-9]\\d{3}.([1-9]|1[0-2]).([1-9]|[1-2][0-9]|3[0-1])\\s(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d";
            judge=strList.get(i).matches(regEx);
            judge1=strList.get(i).matches(regEx1);
            judge2=strList.get(i).matches(regEx2);
            judge3=strList.get(i).matches(regEx3);
            judge4=strList.get(i).matches(regEx4);
            judge5=strList.get(i).matches(regEx5);
            for(int j = 0;j<i;j++) {
                if(strList.get(i).equals(strList.get(j)))
                    judge6=true;
            }
            if(judge==false&&judge1==false&&judge2==false&&judge3==false&&judge4==false&&judge5==false)
                continue;
            else if(judge6) {
                continue;
            }
            else {
                if(b[0]==117) {
                    User user = new User();
                    user.setNumber(c);
                    char []e=c.toCharArray();
                    if(e[0]==49) {
                        ChargeMode chargeMode = new MobilePhoneCharging();
                        ArrayList<ChargeRule> chargeRules = new ArrayList<>(6);
                        chargeRules.add(new MobilePhoneInCityRule());
                        chargeRules.add(new MobilePhoneInProvinceRule());
                        chargeRules.add(new MobilePhoneInLandRule());
                        chargeRules.add(new RoaminganswersInLandRule());
                        chargeRules.add(new RoamingCallsInProvinceRule());
                        chargeRules.add(new RoamingCallsInLandRule());
                        chargeMode.setChargeRules(chargeRules);
                        user.setChargeMode(chargeMode);
                        users.add(user);
                    }
                    if(e[0]==48) {
                        ChargeMode chargeMode = new LandlinePhoneCharging();
                        ArrayList<ChargeRule> chargeRules = new ArrayList<>(3);
                        chargeRules.add(new LandPhoneInCityRule());
                        chargeRules.add(new LandPhoneInProvinceRule());
                        chargeRules.add(new LandPhoneInLandRule());
                        chargeMode.setChargeRules(chargeRules);
                        user.setChargeMode(chargeMode);
                        users.add(user);
                    }
                }
                if(b[0]==116) {
                    if(judge1) {
                        String[] d = a[2].split("\\.");
                        String[] d1 = a[4].split("\\.");
                        int year = Integer.parseInt(d[0]);
                        int month = Integer.parseInt(d[1]);
                        int day = Integer.parseInt(d[2]);
                        int year1 = Integer.parseInt(d1[0]);
                        int month1 = Integer.parseInt(d1[1]);
                        int day1 = Integer.parseInt(d1[2]);
                        
                        Check check = new Check(year, month, day);
                        Check check1 = new Check(year1, month1, day1);
                        if(check.checkInputValidity()&&check1.checkInputValidity()&&check.compareDates(check1)) {
                            String callingNumber = c;
                            String answerNumber = a[1];
                            String callingAddressAreaCode = c.substring(0, 4);
                            String answerAddressAreaCode = a[1].substring(0, 4);
                            String startTimeStr = a[2] + " " + a[3];
                            String endTimeStr = a[4] + " " + a[5];
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
                            Date startTime = sdf.parse(startTimeStr);
                            Date endTime = sdf.parse(endTimeStr);
                            CallRecord callRecord = new CallRecord();
                            callRecord.setCallingNumber(callingNumber);
                            callRecord.setAnswerNumber(answerNumber);
                            callRecord.setCallingAddressAreaCode(callingAddressAreaCode);
                            callRecord.setAnswerAddressAreaCode(answerAddressAreaCode);
                            callRecord.setStartTime(startTime);
                            callRecord.setEndTIme(endTime);
                            for (User user : users) {
                                if (user.getNumber().equals(callingNumber)) {
                                    UserRecords userRecords = user.getUserRecords();
                                    if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                        userRecords.addCallingInCityRecords(callRecord);
                                    } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                        userRecords.addCallingInProvinceRecords(callRecord);
                                    } else {
                                        userRecords.addCallingInLandRecords(callRecord);
                                    }
                                }
                                if (user.getNumber().equals(answerNumber)) {
                                    UserRecords userRecords = user.getUserRecords();
                                    if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                        userRecords.addAnswerInCityRecords(callRecord);
                                    } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                        userRecords.addAnswerInProvinceRecords(callRecord);
                                    } else {
                                        userRecords.addAnswerInLandRecords(callRecord);
                                    }
                                }
                           }
                        }
                    }
                    if(judge3) {
                        String[] d = a[3].split("\\.");
                        String[] d1 = a[5].split("\\.");
                        int year = Integer.parseInt(d[0]);
                        int month = Integer.parseInt(d[1]);
                        int day = Integer.parseInt(d[2]);
                        int year1 = Integer.parseInt(d1[0]);
                        int month1 = Integer.parseInt(d1[1]);
                        int day1 = Integer.parseInt(d1[2]);
                        
                        Check check = new Check(year, month, day);
                        Check check1 = new Check(year1, month1, day1);
                        if(check.checkInputValidity()&&check1.checkInputValidity()&&check.compareDates(check1)) {
                            String callingNumber = c;
                            String answerNumber = a[1];
                            String callingAddressAreaCode = c.substring(0, 4);
                            String answerAddressAreaCode = a[2];
                            String startTimeStr = a[3] + " " + a[4];
                            String endTimeStr = a[5] + " " + a[6];
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
                            Date startTime = sdf.parse(startTimeStr);
                            Date endTime = sdf.parse(endTimeStr);
                            CallRecord callRecord = new CallRecord();
                            callRecord.setCallingNumber(callingNumber);
                            callRecord.setAnswerNumber(answerNumber);
                            callRecord.setCallingAddressAreaCode(callingAddressAreaCode);
                            callRecord.setAnswerAddressAreaCode(answerAddressAreaCode);
                            callRecord.setStartTime(startTime);
                            callRecord.setEndTIme(endTime);
                            for (User user : users) {
                                if (user.getNumber().equals(callingNumber)) {
                                    UserRecords userRecords = user.getUserRecords();
                                    if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                        userRecords.addCallingInCityRecords(callRecord);
                                    } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                        userRecords.addCallingInProvinceRecords(callRecord);
                                    } else {
                                        userRecords.addCallingInLandRecords(callRecord);
                                    }
                                }
                                if (user.getNumber().equals(answerNumber)) {
                                    UserRecords userRecords = user.getUserRecords();
                                    if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                        userRecords.addAnswerInCityRecords(callRecord);
                                    } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                        userRecords.addAnswerInProvinceRecords(callRecord);
                                    } else {
                                        userRecords.addRoaminganswersInCityRecords(callRecord);;
                                    }
                                }
                           }
                        }
                    }
                    if(judge4) {
                        String[] d = a[3].split("\\.");
                        String[] d1 = a[5].split("\\.");
                        int year = Integer.parseInt(d[0]);
                        int month = Integer.parseInt(d[1]);
                        int day = Integer.parseInt(d[2]);
                        int year1 = Integer.parseInt(d1[0]);
                        int month1 = Integer.parseInt(d1[1]);
                        int day1 = Integer.parseInt(d1[2]);
                        
                        Check check = new Check(year, month, day);
                        Check check1 = new Check(year1, month1, day1);
                        if(check.checkInputValidity()&&check1.checkInputValidity()&&check.compareDates(check1)) {
                            String callingNumber = c;
                            String answerNumber = a[2];
                            String callingAddressAreaCode = a[1];
                            String answerAddressAreaCode = a[2].substring(0, 4);
                            String startTimeStr = a[3] + " " + a[4];
                            String endTimeStr = a[5] + " " + a[6];
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
                            Date startTime = sdf.parse(startTimeStr);
                            Date endTime = sdf.parse(endTimeStr);
                            CallRecord callRecord = new CallRecord();
                            callRecord.setCallingNumber(callingNumber);
                            callRecord.setAnswerNumber(answerNumber);
                            callRecord.setCallingAddressAreaCode(callingAddressAreaCode);
                            callRecord.setAnswerAddressAreaCode(answerAddressAreaCode);
                            callRecord.setStartTime(startTime);
                            callRecord.setEndTIme(endTime);
                            for (User user : users) {
                                if (user.getNumber().equals(callingNumber)) {
                                    UserRecords userRecords = user.getUserRecords();
                                    if("0791".equals(a[1])) {
                                        if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                            userRecords.addCallingInCityRecords(callRecord);
                                        } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                            userRecords.addCallingInProvinceRecords(callRecord);
                                        } else {
                                            userRecords.addCallingInLandRecords(callRecord);
                                        }
                                    }
                                    else if(a[1].matches("^(079[0-9])|(0701)$")) {
                                         userRecords.addRoamingCallsInProvinceRecords(callRecord);
                                    }
                                    else {
                                         userRecords.addRoamingCallsInLandRecords(callRecord);
                                    }
                                }
                                if (user.getNumber().equals(answerNumber)) {
                                    UserRecords userRecords = user.getUserRecords();
                                    if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                        userRecords.addAnswerInCityRecords(callRecord);
                                    } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                        userRecords.addAnswerInProvinceRecords(callRecord);
                                    } else {
                                        userRecords.addAnswerInLandRecords(callRecord);
                                    }
                                }
                           }
                        }
                    }
                    if(judge5) {
                        String[] d = a[4].split("\\.");
                        String[] d1 = a[6].split("\\.");
                        int year = Integer.parseInt(d[0]);
                        int month = Integer.parseInt(d[1]);
                        int day = Integer.parseInt(d[2]);
                        int year1 = Integer.parseInt(d1[0]);
                        int month1 = Integer.parseInt(d1[1]);
                        int day1 = Integer.parseInt(d1[2]);
                        
                        Check check = new Check(year, month, day);
                        Check check1 = new Check(year1, month1, day1);
                        if(check.checkInputValidity()&&check1.checkInputValidity()&&check.compareDates(check1)) {
                            String callingNumber = c;
                            String answerNumber = a[2];
                            String callingAddressAreaCode = a[1];
                            String answerAddressAreaCode = a[3];
                            String startTimeStr = a[4] + " " + a[5];
                            String endTimeStr = a[6] + " " + a[7];
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
                            Date startTime = sdf.parse(startTimeStr);
                            Date endTime = sdf.parse(endTimeStr);
                            CallRecord callRecord = new CallRecord();
                            callRecord.setCallingNumber(callingNumber);
                            callRecord.setAnswerNumber(answerNumber);
                            callRecord.setCallingAddressAreaCode(callingAddressAreaCode);
                            callRecord.setAnswerAddressAreaCode(answerAddressAreaCode);
                            callRecord.setStartTime(startTime);
                            callRecord.setEndTIme(endTime);
                            for (User user : users) {
                                if (user.getNumber().equals(callingNumber)) {
                                    UserRecords userRecords = user.getUserRecords();
                                    if("0791".equals(a[1])) {
                                        if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                            userRecords.addCallingInCityRecords(callRecord);
                                        } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                            userRecords.addCallingInProvinceRecords(callRecord);
                                        } else {
                                            userRecords.addCallingInLandRecords(callRecord);
                                        }
                                    }
                                    else if(a[1].matches("^(079[0-9])|(0701)$")) {
                                         userRecords.addRoamingCallsInProvinceRecords(callRecord);
                                    }
                                    else {
                                         userRecords.addRoamingCallsInLandRecords(callRecord);
                                    }
                                    
                                }
                                if (user.getNumber().equals(answerNumber)) {
                                    UserRecords userRecords = user.getUserRecords();
                                    if ("0791".equals(callRecord.getAnswerAddressAreaCode())) {
                                        userRecords.addAnswerInCityRecords(callRecord);
                                    } else if (callRecord.getAnswerAddressAreaCode().matches("^(079[0-9])|(0701)$")) {
                                        userRecords.addAnswerInProvinceRecords(callRecord);
                                    } else {
                                        userRecords.addRoaminganswersInCityRecords(callRecord);;
                                    }
                                }
                           }
                        }
                    }

                }
            }
            
        }
        for (int i = 0; i < users.size() - 1; i++) {
            for (int j = 0; j < users.size() - 1 - i; j++) {
                User temp;
                if (users.get(j).getNumber().compareTo(users.get(j + 1).getNumber()) > 0) {
                    temp = users.get(j);
                    users.set(j, users.get(j + 1));
                    users.set(j + 1, temp);
                }
            }
        }
        for (User user : users) {
            String number = user.getNumber();
            double calCost = user.calCost();
            double balance = user.calBalance();
            System.out.println(number + " " + calCost + " " + balance);
        }
    }

}
class Check{
    private int day;
    private int month;
    private int year;
    
    public Check(int year,int month,int day) {
        this.day = day;
        this.month = month;
        this.year = year;
    }
    
    public boolean checkInputValidity() {
        boolean a;
        int[] n = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
        {
            n[2] = 29;
        }
        if(month>0&&month<=12&&day<=n[month]&&day>0) {
            a = true;
        }
        else {
            a = false;
        }
        return a;
    }
    
    public static boolean isLeapYear(int year) //判断year是否为闰年,返回boolean类型;
    {
        
        if((year%4 == 0&&year%100 != 0)||(year%400 == 0))
            return true;
            else return false;
    }
    
    public boolean compareDates(Check date) {
        if(year>date.year) {
            return false;
        }
        else if(year<date.year){
            return true;
        }
        else {
            if(month>date.month) {
                return false;
            }
            else if(month<date.month) {
                return true;
            }
            else {
                if(day>date.day) {
                    return false;
                }
                else {
                    return true;
                }
            }
        }
    }

}

abstract class CallChargeRule extends ChargeRule{
    public abstract double calCost(ArrayList<CallRecord> callRecords);
}
class CallRecord extends CommunicationRecord {
    Date startTime;
    Date endTIme;
    String callingAddressAreaCode;
    String 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) {
        this.chargeRules = chargeRules;
    }
    
    public abstract double calCost(UserRecords userRecords);
    
    public abstract double getMonthlyRent();
    
}
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 {
    double monthlyRent = 20;

    @Override
    public double calCost(UserRecords userRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for (ChargeRule chargeRule : getChargeRules()) {
            if (chargeRule instanceof LandPhoneInCityRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInCityRecords());
            }
            if (chargeRule instanceof LandPhoneInProvinceRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInProvinceRecords());
            }
            if (chargeRule instanceof LandPhoneInLandRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInLandRecords());
            }
        }
        return sum;
    }

    @Override
    public double getMonthlyRent() {
        // TODO Auto-generated method stub
        return monthlyRent;
    }

    
}
class LandPhoneInCityRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.1*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class LandPhoneInLandRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.6*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class LandPhoneInProvinceRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.3*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class MessageRecord extends CommunicationRecord {
    String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
    
}
class User {
    UserRecords userRecords = new UserRecords();
    double balance = 100;
    ChargeMode chargeMode;
    String number;
    
    public double calBalance() {
        return balance-chargeMode.calCost(userRecords)-chargeMode.getMonthlyRent();
    }
    public double calCost() {
        return Double.valueOf(new DecimalFormat("#.00").format(chargeMode.calCost(userRecords)));
    }
    
    public UserRecords getUserRecords() {
        return userRecords;
    }
    
    public void setUserRecords(UserRecords userRecords) {
        this.userRecords = userRecords;
    }
    
    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;
    }
    
}
class UserRecords {
    ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> roamingCallsInProvinceRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> roamingCallsInLandRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> roaminganswersInCityRecords = 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>();
    
    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 addRoaminganswersInCityRecords(CallRecord answerRecord) {
        roaminganswersInCityRecords.add(answerRecord);
    }

    public void addRoamingCallsInProvinceRecords(CallRecord callRecord) {
        roamingCallsInProvinceRecords.add(callRecord);
    }
    
    public void addRoamingCallsInLandRecords(CallRecord callRecord) {
        roamingCallsInLandRecords.add(callRecord);
    }
    
    public void addAnswerInCityRecords(CallRecord callRecord) {
        answerInCityRecords.add(callRecord);
    }
    
    public void addAnswerInProvinceRecords(CallRecord answerRecord) {
        answerInProvinceRecords.add(answerRecord);
    }
    
    public void addAnswerInLandRecords(CallRecord answerRecord) {
        answerInLandRecords.add(answerRecord);
    }
    
    public void addSendMessageRecords(MessageRecord sendMessageRecord) {
        sendMessageRecords.add(sendMessageRecord);
    }
    
    public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) {
        receiveMessageRecords.add(receiveMessageRecord);
    }

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


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


    public ArrayList<CallRecord> getCallingInLandRecords() {
        return callingInLandRecords;
    }
    
    public ArrayList<CallRecord> getRoamingCallsInProvinceRecords() {
        return roamingCallsInProvinceRecords;
    }

    public ArrayList<CallRecord> getRoamingCallsInLandRecords() {
        return roamingCallsInLandRecords;
    }

    public ArrayList<CallRecord> getRoaminganswersInCityRecords() {
        return roaminganswersInCityRecords;
    }

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


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


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


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


    public ArrayList<MessageRecord> getReceiveMessageRecords() {
        return receiveMessageRecords;
    }
    
}
class MobilePhoneCharging extends ChargeMode {
    double monthlyRent = 15;
    
    @Override
    public double calCost(UserRecords userRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for (ChargeRule chargeRule : getChargeRules()) {
            if (chargeRule instanceof MobilePhoneInCityRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInCityRecords());
            }
            if (chargeRule instanceof MobilePhoneInProvinceRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInProvinceRecords());
            }
            if (chargeRule instanceof MobilePhoneInLandRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInLandRecords());
            }
            if (chargeRule instanceof RoaminganswersInLandRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getRoaminganswersInCityRecords());
            }
            if (chargeRule instanceof RoamingCallsInProvinceRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getRoamingCallsInProvinceRecords());
            }
            if (chargeRule instanceof RoamingCallsInLandRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getRoamingCallsInLandRecords());
            }
        }
        return sum;
    }

    @Override
    public double getMonthlyRent() {
        // TODO Auto-generated method stub
        return monthlyRent;
    }
    
}
class MobilePhoneInCityRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.1*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class MobilePhoneInProvinceRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.2*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class MobilePhoneInLandRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.3*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class RoaminganswersInLandRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.3*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class RoamingCallsInLandRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.6*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class RoamingCallsInProvinceRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.3*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}

  在上一题的基础上增加了MobilePhoneInCityRule类、MobilePhoneInProvinceRule类、MobilePhoneInLandRule类用于用户在开户城市的通讯计费,还增加了RoaminganswersInLandRule、RoamingCallsInLandRule、RoamingCallsInProvinceRule 三个类用于手机漫游计费。

  输入输出格式也有不同,输入信息包括两种类型 1、逐行输入南昌市用户开户的信息,每行一个用户,含手机和座机用户 格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐) 例如:u-079186300001 0 座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。 手机号码由11位数字构成,最高位是1。 本题在电信计费系列1基础上增加类型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

 

 

  3、电信计费系列3-短信计费,题目要求如下:

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

  代码如下:

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

public class Main {

    public static void main(String[] args) throws ParseException {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        List<User> users = new ArrayList<>();
        String s = "";
        ArrayList<String> strList = new ArrayList<String>();
        while(!s.equals("end")){
            s = in.nextLine();
            strList.add(s);
        }
        in.close();
        for(int i = 0;i<strList.size();i++) {
            
            if(strList.get(i).length() <=11)
                continue;
            char []b=strList.get(i).toCharArray();
            String[] a = strList.get(i).split("\\s+");
            String c=a[0].substring(2);
            boolean judge2 = true;
            boolean judge6 = true;
            boolean judge7 = false;
            String regEx2="u-1[0-9]{10}\\s3";
            String regEx6="m-1[0-9]{10}\\s1[0-9]{10}\\s[A-Za-z0-9 ,.]+";
            judge2=strList.get(i).matches(regEx2);
            judge6=strList.get(i).matches(regEx6);
            if(judge2==false&&judge6==false)
                continue;
            else {
                if(b[0]==117) {
                    for(int j = 0;j<i;j++) {
                        if(strList.get(i).equals(strList.get(j)))
                        judge7=true;
                    }
                    if(judge7) {
                        continue;
                    }
                    User user = new User();
                    user.setNumber(c);
                    
                    ChargeMode chargeMode = new MessageCharging();
                    ArrayList<ChargeRule> chargeRules = new ArrayList<>(3);
                    chargeRules.add(new SendMessageRule());
                    chargeMode.setChargeRules(chargeRules);
                    user.setChargeMode(chargeMode);
                    users.add(user);
                }
                if(b[0]==109) {
                    String callingNumber = c;
                    String answerNumber = a[1];
                    String messsage = strList.get(i).substring(26);
                    MessageRecord messageRecord = new MessageRecord();
                    messageRecord.setMessage(messsage);
                    messageRecord.setCallingNumber(callingNumber);
                    messageRecord.setAnswerNumber(answerNumber);
                    for (User user : users) {
                        if (user.getNumber().equals(callingNumber)) {
                            UserRecords userRecords = user.getUserRecords();
                            userRecords.addSendMessageRecords(messageRecord);
                        }
                        if (user.getNumber().equals(answerNumber)) {
                            UserRecords userRecords = user.getUserRecords();
                            userRecords.addReceiveMessageRecords(messageRecord);;
                        }
                   }

                }
            }
            
        }
        for (int i = 0; i < users.size() - 1; i++) {
            for (int j = 0; j < users.size() - 1 - i; j++) {
                User temp;
                if (users.get(j).getNumber().compareTo(users.get(j + 1).getNumber()) > 0) {
                    temp = users.get(j);
                    users.set(j, users.get(j + 1));
                    users.set(j + 1, temp);
                }
            }
        }
        for (User user : users) {
            String number = user.getNumber();
            double calCost = user.calCost();
            double balance = user.calBalance();
            System.out.println(number + " " + calCost + " " + balance);
        }
    }

}
abstract class CallChargeRule extends ChargeRule{
    public abstract double calCost(ArrayList<CallRecord> callRecords);
}
class CallRecord extends CommunicationRecord {
    Date startTime;
    Date endTIme;
    String callingAddressAreaCode;
    String 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) {
        this.chargeRules = chargeRules;
    }
    
    public abstract double calCost(UserRecords userRecords);
    
    public abstract double getMonthlyRent();
    
}
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 {
    double monthlyRent = 20;

    @Override
    public double calCost(UserRecords userRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for (ChargeRule chargeRule : getChargeRules()) {
            if (chargeRule instanceof LandPhoneInCityRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInCityRecords());
            }
            if (chargeRule instanceof LandPhoneInProvinceRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInProvinceRecords());
            }
            if (chargeRule instanceof LandPhoneInLandRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInLandRecords());
            }
        }
        return sum;
    }

    @Override
    public double getMonthlyRent() {
        // TODO Auto-generated method stub
        return monthlyRent;
    }

    
}
class LandPhoneInCityRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.1*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class LandPhoneInLandRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.6*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class LandPhoneInProvinceRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.3*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
abstract class MessageChargeRule extends ChargeRule{
    public abstract double calCost(ArrayList<MessageRecord> messageRecords);
}
class MessageCharging extends ChargeMode {

    @Override
    public double calCost(UserRecords userRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for (ChargeRule chargeRule : getChargeRules()) {
            if (chargeRule instanceof SendMessageRule) {
                sum = sum + ((MessageChargeRule) chargeRule).calCost(userRecords.getSendMessageRecords());
            }
            
        }
        double c = 0;
        if(sum<4) {
            c = c + 0.1*sum;
        }
        if(sum<6&&sum>3) {
            c = c + 0.3+0.2*(sum-3);
        }
        if(sum>5) {
            c = c + 0.7+0.3*(sum-5);
        }
        return c;
    }

    @Override
    public double getMonthlyRent() {
        // TODO Auto-generated method stub
        return 0;
    }

}
class MessageRecord extends CommunicationRecord {
    String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
    
}
class MobilePhoneCharging extends ChargeMode {
    double monthlyRent = 15;
    
    @Override
    public double calCost(UserRecords userRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for (ChargeRule chargeRule : getChargeRules()) {
            if (chargeRule instanceof MobilePhoneInCityRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInCityRecords());
            }
            if (chargeRule instanceof MobilePhoneInProvinceRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInProvinceRecords());
            }
            if (chargeRule instanceof MobilePhoneInLandRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getCallingInLandRecords());
            }
            if (chargeRule instanceof RoaminganswersInLandRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getRoaminganswersInCityRecords());
            }
            if (chargeRule instanceof RoamingCallsInProvinceRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getRoamingCallsInProvinceRecords());
            }
            if (chargeRule instanceof RoamingCallsInLandRule) {
                sum = sum + ((CallChargeRule) chargeRule).calCost(userRecords.getRoamingCallsInLandRecords());
            }
        }
        return sum;
    }

    @Override
    public double getMonthlyRent() {
        // TODO Auto-generated method stub
        return monthlyRent;
    }
    
}
class MobilePhoneInCityRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.1*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class MobilePhoneInLandRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.3*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class MobilePhoneInProvinceRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.2*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class RoaminganswersInLandRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.3*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class RoamingCallsInLandRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.6*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class RoamingCallsInProvinceRule extends CallChargeRule {

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<callRecords.size();i++) {
            sum = sum + 0.3*Math.ceil((callRecords.get(i).getEndTIme().getTime()-callRecords.get(i).getStartTime().getTime())*1.0/(1000*60));
        }
        return sum;
    }

}
class SendMessageRule extends MessageChargeRule{

    @Override
    public double calCost(ArrayList<MessageRecord> messageRecords) {
        // TODO Auto-generated method stub
        double sum = 0;
        for(int i = 0;i<messageRecords.size();i++) {
            sum = sum + Math.ceil(messageRecords.get(i).getMessage().length()/10.0);
        }
        return sum;
    }

}
class User {
    UserRecords userRecords = new UserRecords();
    double balance = 100;
    ChargeMode chargeMode;
    String number;
    
    public double calBalance() {
        return balance-chargeMode.calCost(userRecords)-chargeMode.getMonthlyRent();
    }
    public double calCost() {
        return Double.valueOf(new DecimalFormat("#.00").format(chargeMode.calCost(userRecords)));
    }
    
    public UserRecords getUserRecords() {
        return userRecords;
    }
    
    public void setUserRecords(UserRecords userRecords) {
        this.userRecords = userRecords;
    }
    
    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;
    }
    
}
class UserRecords {
    ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> roamingCallsInProvinceRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> roamingCallsInLandRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> roaminganswersInCityRecords = 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>();
    
    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 addRoaminganswersInCityRecords(CallRecord answerRecord) {
        roaminganswersInCityRecords.add(answerRecord);
    }

    public void addRoamingCallsInProvinceRecords(CallRecord callRecord) {
        roamingCallsInProvinceRecords.add(callRecord);
    }
    
    public void addRoamingCallsInLandRecords(CallRecord callRecord) {
        roamingCallsInLandRecords.add(callRecord);
    }
    
    public void addAnswerInCityRecords(CallRecord callRecord) {
        answerInCityRecords.add(callRecord);
    }
    
    public void addAnswerInProvinceRecords(CallRecord answerRecord) {
        answerInProvinceRecords.add(answerRecord);
    }
    
    public void addAnswerInLandRecords(CallRecord answerRecord) {
        answerInLandRecords.add(answerRecord);
    }
    
    public void addSendMessageRecords(MessageRecord sendMessageRecord) {
        sendMessageRecords.add(sendMessageRecord);
    }
    
    public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) {
        receiveMessageRecords.add(receiveMessageRecord);
    }

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


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


    public ArrayList<CallRecord> getCallingInLandRecords() {
        return callingInLandRecords;
    }
    
    public ArrayList<CallRecord> getRoamingCallsInProvinceRecords() {
        return roamingCallsInProvinceRecords;
    }

    public ArrayList<CallRecord> getRoamingCallsInLandRecords() {
        return roamingCallsInLandRecords;
    }

    public ArrayList<CallRecord> getRoaminganswersInCityRecords() {
        return roaminganswersInCityRecords;
    }

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


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


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


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


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

  

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

  ChargeMode是计费方式的抽象类:chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。  

  getMonthlyRent()方法用于返回月租(monthlyRent)。   

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

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

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

 输入信息包括两种类型

1、逐行输入南昌市手机用户开户的信息,每行一个用户。
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐 3-手机短信计费)
2、逐行输入本月某些用户的短信信息,短信的格式:
m-主叫号码,接收号码,短信内容 (短信内容只能由数字、字母、空格、英文逗号、英文句号组成)

  输出,根据输入的详细短信信息,计算所有已开户的用户的当月短信费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。

每条短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。

  类图如下:

三、踩坑心得

  ①需要清楚地知道类间关系,知道每个类中方法的作用。


  ②做题时需要先理清思路再写程序,避免逻辑上的错误。

  ③当发现自己当前的逻辑方法完成不了题目时,可以尝试重新换个思路,以免执行不下去。

  ④做题时查缺补漏。


四、改进建议
  ①对于主函数中List的选择不是很好,可以运用TreeMap更容易处理。

  ②对于题目要求的排序输出,可以运用集合本身具有的排序方法,不必运用冒泡排序进行排序。

  ③对于一个问题可以思考灵活的方法,设计类做到可扩展性,增加功能或减少功能时不必修改太多的代码,灵活的方法也不需要太多的代码解决一个问题。

 

五、总结
  通过这三次题目集的练习,我掌握了类的相关设计,对象的创建,方法的调用,继承与多态,但还需要更加深入地研究类与对象之间的联系,类与类之间的联系,对象与对象之间的联系。还要学习如何设计类,增加类的可扩展性。其他方面我觉得课上及课下组织方式已经非常好了,教师的教学也非常好,对于作业以及实验我也没有可以挑剔的地方。

 

 

posted @ 2022-06-15 23:25  Boke-Liu  阅读(140)  评论(0)    收藏  举报