首页 > 其他分享 >BLOG-3

BLOG-3

时间:2022-12-10 22:45:06浏览次数:55  
标签:inputs return String double ArrayList BLOG public

(1)前言:

 10-16周很快就要结束了,这三次电信计费大作业总体比之前的四边形、五边形不要简单太多。主要是考察继承、多态、抽象类等的使用。

而且电信计费的类图都给定的,即总体框架直接给你了,所以才显得没有之前复杂。其中正则表达式这几道题的

重点,格式判断还是主要的。当然对于ArrayList、toString等方法也着重进行了考察。

(2)设计与分析:

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

实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租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

输入样例:

在这里给出一组输入。例如:

u-079186300001 0
t-079186300001 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:25
end
 

输出样例:

在这里给出相应的输出。例如:

079186300001 3.0 77.0
 

其余参考样例详见附件,未尽事宜以附件样例为准:

电信计费简化版-座机计费说明.pdf

 

源码:

(点加号)

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Main{
    //控制小数点
    public static void main(String[] args){
        //Point p1=new Point();

        Scanner input=new Scanner(System.in);
        String s=input.nextLine();//输入
        Show outputtool = new Show();

        Input inputdeal = new Input();

        ArrayList<User> users = new ArrayList<>();
        while (!s.equals("end")) {
            if (1 == inputdeal.check(s)) {
                inputdeal.writeUser(users, s);
            } else if (2 == inputdeal.check(s)) {
                inputdeal.writeRecord(users, s);
            }
            s= input.nextLine();
        }

        users.sort(new Comparator<User>() {

           
            public int compare(User u1, User u2) {
                if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });

        for (User u : users) {
            System.out.print(u.getNumber() + " ");
            outputtool.output(u.calCost());
            System.out.print(" ");
            outputtool.output(u.calBalance());
            System.out.println();

        }


    }
}
class Input{
    public int check(String s){
        String[] ss=s.split(" ");
        if(ss.length==2){
            if(ss[0].matches("^u-[0-9]{11,13}$")){
                if(Integer.parseInt(ss[1])>=0){
                    if(Integer.parseInt(ss[1])<=2)
                        return 1;
                }
            }
        }else if(ss.length==6){
            if (validate(ss[2]))
                if (validate(ss[4]))
                    if (validatet(ss[3]))
                        if (validatet(ss[5]))
                            if (ss[0].matches("[t]-0791\\d{7,8}")) {
                                if (ss[1].matches(".\\d{9,11}"))
                                    return 2;
                            }
        }
        return 0;
    }
    private boolean validate(String s) {
        Pattern p=Pattern.compile("\\d{4}+\\.\\d{1,2}+\\.\\d{1,2}+");
        Matcher m = p.matcher(s);
        if (!m.matches())
            return  false;
        // 得到年月日
        String[] array = s.split("\\.");
        int year = Integer.valueOf(array[0]);
        int month = Integer.valueOf(array[1]);
        int day = Integer.valueOf(array[2]);

        if (month < 1 || month > 12) {
            return false;
        }
        int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (isLeapYear(year)) {
            monthLengths[2] = 29;
        } else {
            monthLengths[2] = 28;
        }
        int monthLength = monthLengths[month];
        if (day < 1 || day > monthLength) {
            return false;
        }
        return true;
    }
    /** 是否是闰年 */
    private static boolean isLeapYear(int year) {
        return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
    }

    public boolean judge(String input) {

        return false;
    }

    public void writeUser(ArrayList<User> users, String input) {
       User usernew = new User();
        String[] inputs = input.split(" ");
        String num = inputs[0].substring(2);
        for (User i : users) {
            if (i.getNumber().equals(num)) {
                return;
            }
        }
        usernew.setNumber(num);
        int mode = Integer.parseInt(inputs[1]);
        if (mode == 0) {
            usernew.setChargeMode(new LandlinePhoneCharging());
        }
        users.add(usernew);
    }

    public void writeRecord(ArrayList<User> users, String input) {
        String[] inputs = input.split(" ");
        inputs[0] = inputs[0].replace("t-", "");

       User callu = null, answeru = null;
       CallRecord callrecord = new CallRecord(inputs);

        for (User i : users) {
            if (i.getNumber().equals(inputs[0])) {
                callu = i;
            }
            if (i.getNumber().equals(inputs[1])) {
                answeru = i;
            }
            if (callu != null && answeru != null) {
                break;
            }
        }

        if (callu != null) {
            if (callrecord.getCallType() == 1) {
                callu.getUserRecords().addCallingInCityRecords(callrecord);
            } else if (callrecord.getCallType() == 2) {
                callu.getUserRecords().addCallingInProvinceRecords(callrecord);
            } else {
                callu.getUserRecords().addCallingInLandRecords(callrecord);
            }
        }

        if (answeru != null) {
            if (callrecord.getCallType() == 1) {
                answeru.getUserRecords().addAnswerInCityRecords(callrecord);
            } else if (callrecord.getCallType() == 2) {

                answeru.getUserRecords().aadAnswerInProvinceRecords(callrecord);
            } else {
                answeru.getUserRecords().addAnswerInLandRecords(callrecord);
            }
        }

    }

    private boolean validatet(String s) {
        Pattern p=Pattern.compile("^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$");
        Matcher m = p.matcher(s);
        if (!m.matches())
            return  false;
        return  true;
    }


}
class Show {

    public void output(double out) {
//        java.text.DecimalFormat df=new java.text.DecimalFormat("#.#");
//        String a=df.format(out);
//        System.out.print(a);
        BigDecimal numb = new BigDecimal(out);
        out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        System.out.print(out);
    }
}

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

    public abstract double calCost(UserRecords userRecords);

    public abstract double getMonthlyRent();

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

    public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
        this.chargeRules = chargeRules;
    }
}

class User{
    private UserRecords userRecords = new UserRecords();
    private double balance = 100;
    private ChargeMode chargeMode;
    private String number;
    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }
    public double calCost(){
        return chargeMode.calCost(userRecords);
    }
    public double calBalance(){
        return balance-chargeMode.getMonthlyRent()-chargeMode.calCost(userRecords);
    }
    public UserRecords getUserRecords(){
        return userRecords;
    }
    public void setUserRecords(UserRecords userRecords) {
        this.userRecords = userRecords;
    }

    public ChargeMode getChargeMode() {
        return chargeMode;
    }

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



}


abstract class CommunicationRecord {
    protected String callingNumber;
    protected String answerNumber;

    public String getCallingNumber() {
        return callingNumber;
    }

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

    public String getAnswerNumbe() {
        return answerNumber;
    }

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

}
class MessageRecord extends CommunicationRecord {

    private String message;

    public String getMessage() {
        return message;
    }

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

    abstract public double calCost(UserRecords userRecords);

}
abstract class CallChargeRule extends ChargeRule {

}

class LandPhoneInCityRule extends CallChargeRule {


    public double calCost(UserRecords userRecords) {
        double sumCost = 0;
        for (CallRecord call : userRecords.getCallingInCityRecords()) {
            double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
            if (distanceS < 0) {
                continue;
            }
            double distanceM = (int) distanceS / 60;
            if (distanceS % 60 != 0) {
                distanceM += 1;
            }
            sumCost += distanceM * 0.1;
        }
        return sumCost;
    }

}

class LandPhoneInlandRule extends CallChargeRule {


    public double calCost(UserRecords userRecords) {
        double sumCost = 0;
        for (CallRecord call : userRecords.getCallingInLandRecords()) {
            double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
            if (distanceS < 0) {
                continue;
            }
            double distanceM = (int) distanceS / 60;
            if (distanceS % 60 != 0) {
                distanceM += 1;
            }
            sumCost += distanceM * 0.6;
        }
        return sumCost;
    }

}

class LandPhoneInProvinceRule extends CallChargeRule {


    public double calCost(UserRecords userRecords) {
        double sumCost = 0;
        for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
            double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
            if (distanceS < 0) {
                continue;
            }
            double distanceM = (int) distanceS / 60;
            if (distanceS % 60 != 0) {
                distanceM += 1;
            }
            sumCost += distanceM * 0.3;
        }
        return sumCost;
    }

}
class LandlinePhoneCharging extends ChargeMode {

    private double monthlyRent = 20;

    public LandlinePhoneCharging() {
        super();
        chargeRules.add(new LandPhoneInCityRule());
        chargeRules.add(new LandPhoneInProvinceRule());
        chargeRules.add(new LandPhoneInlandRule());
    }


    public double calCost(UserRecords userRecords) {
        double sumCost = 0;
        for (ChargeRule rule : chargeRules) {
            sumCost += rule.calCost(userRecords);
        }
        return sumCost;
    }


    public double getMonthlyRent() {
        return monthlyRent;
    }

}

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

    public int getCallType() {
        if (callingAddressAreaCode.equals(answerAddressAreaCode)) {
            return 1;
        }
        if (callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701")) {
            if (answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701")) {
                return 2;
            }
        }
        return 3;
    }



    public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
        super();
        this.startTime = startTime;
        this.endTime = endTime;
        this.callingAddressAreaCode = callingAddressAreaCode;
        this.answerAddressAreaCode = answerAddressAreaCode;
    }
    public CallRecord(String[] inputs) {
        super();
        if (inputs[0].length() == 10) {
            callingAddressAreaCode = inputs[0].substring(0, 3);
        } else {
            callingAddressAreaCode = inputs[0].substring(0, 4);
        }
        if (inputs[1].length() == 10) {
            answerAddressAreaCode = inputs[1].substring(0, 3);
        } else {
            answerAddressAreaCode = inputs[1].substring(0, 4);
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
        try {
            startTime = simpleDateFormat.parse(inputs[2] + " " + inputs[3]);
            endTime = simpleDateFormat.parse(inputs[4] + " " + inputs[5]);
        } catch (ParseException e) {
        }

    }
    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;
    }
}
class Point{
    public double x, y;

    public Point(){
        this.x = 0;
        this.y = 0;
    }
    public Point(double a,double b){
        this.x = a;
        this.y = b;
    }

    public void print(){
        String x = String.format("%.6f",this.x);
        String y = String.format("%.6f",this.y);
        x = x.replaceAll("0+?$", "");
        y = y.replaceAll("0+?$", "");
        System.out.printf("(%s , %s)\n",this.x,this.y);
    }

    //两点坐标相同
    public boolean isSameTo(Point a){
        return (this.x == a.x)&&(this.y == a.y);
    }
    //两点距离
    public double disToPoint(Point another){
        return Math.sqrt(Math.pow(this.x-another.x,2) + Math.pow(this.y-another.y,2));
    }
}
class UserRecords{
    private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
    private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
    private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
    private 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 aadAnswerInProvinceRecords(CallRecord callRecord) {
        answerInProvinceRecords.add(callRecord);
    }

    public void addAnswerInLandRecords(CallRecord callRecord) {
        answerInLandRecords.add(callRecord);
    }

    public void addSendMessageRecords(MessageRecord callRecord) {
        sendMessageRecords.add(callRecord);
    }

    public void addReceiveMessageRecords(MessageRecord callRecord) {
        receiveMessageRecords.add(callRecord);
    }

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

    public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
        this.callingInCityRecords = callingInCityRecords;
    }

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

    public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
        this.callingInProvinceRecords = callingInProvinceRecords;
    }

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

    public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
        this.callingInLandRecords = callingInLandRecords;
    }

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

    public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
        this.answerInCityRecords = answerInCityRecords;
    }

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

    public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
        this.answerInProvinceRecords = answerInProvinceRecords;
    }

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

    public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
        this.answerInLandRecords = answerInLandRecords;
    }

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

    public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
        this.sendMessageRecords = sendMessageRecords;
    }

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

    public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
        this.receiveMessageRecords = receiveMessageRecords;
    }

}
View Code

 

 

分析:

PTA头一次做这种题,相对于前两次的四边形和五边形大作业要简单的多。因为题目要求中给出了相应的类图,设计的总体框架已经给出,

根据类图就可以敲出相应代码,可谓完成了大部分。本题主要围绕如何判断输入信息的格式,以及判断后是如何将信息存储进记录。

然后由上图可知本题Max complexity(最大复杂度)过大,原因是设计中if-else语句用的太多。

 

7-1 电信计费系列2-手机+座机计费 分数 80 作者 蔡轲 单位 南昌航空大学

实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
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)。
注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。

输入样例:

在这里给出一组输入。例如:

u-13811111111 1
t-13811111111 0791 13811111110 020 2022.1.3 08:00:00 2022.1.3 08:09:20
end
 

输出样例:

在这里给出相应的输出。例如:

13811111111 3.0 82.0
 

更多内容详见附件:

电信计费简化版-座机计费说明.pdf

源码:

(点加号)

  1 import java.math.BigDecimal;
  2 import java.text.ParseException;
  3 import java.text.SimpleDateFormat;
  4 import java.util.*;
  5 import java.util.regex.Matcher;
  6 import java.util.regex.Pattern;
  7 
  8 
  9 abstract class ChargeMode {
 10     protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
 11 
 12     public abstract double calCost(UserRecords userRecords);
 13 
 14     public abstract double getMonthlyRent();
 15 
 16     public ArrayList<ChargeRule> getChargeRules() {
 17         return chargeRules;
 18     }
 19 
 20     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
 21         this.chargeRules = chargeRules;
 22     }
 23 }
 24 
 25 class UserRecords {
 26 
 27     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
 28     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
 29     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
 30     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
 31     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
 32     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
 33     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
 34     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
 35 
 36     public void addCallingInCityRecords(CallRecord callRecord) {
 37         callingInCityRecords.add(callRecord);
 38     }
 39 
 40     public void addCallingInProvinceRecords(CallRecord callRecord) {
 41         callingInProvinceRecords.add(callRecord);
 42     }
 43 
 44     public void addCallingInLandRecords(CallRecord callRecord) {
 45         callingInLandRecords.add(callRecord);
 46     }
 47 
 48     public void addAnswerInCityRecords(CallRecord callRecord) {
 49         answerInCityRecords.add(callRecord);
 50     }
 51 
 52     public void aaddAnswerInProvinceRecords(CallRecord callRecord) {
 53         answerInProvinceRecords.add(callRecord);
 54     }
 55 
 56     public void addAnswerInLandRecords(CallRecord callRecord) {
 57         answerInLandRecords.add(callRecord);
 58     }
 59 
 60     public void addSendMessageRecords(MessageRecord callRecord) {
 61         sendMessageRecords.add(callRecord);
 62     }
 63 
 64     public void addReceiveMessageRecords(MessageRecord callRecord) {
 65         receiveMessageRecords.add(callRecord);
 66     }
 67 
 68     public ArrayList<CallRecord> getCallingInCityRecords() {
 69         return callingInCityRecords;
 70     }
 71 
 72     public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
 73         this.callingInCityRecords = callingInCityRecords;
 74     }
 75 
 76     public ArrayList<CallRecord> getCallingInProvinceRecords() {
 77         return callingInProvinceRecords;
 78     }
 79 
 80     public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
 81         this.callingInProvinceRecords = callingInProvinceRecords;
 82     }
 83 
 84     public ArrayList<CallRecord> getCallingInLandRecords() {
 85         return callingInLandRecords;
 86     }
 87 
 88     public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
 89         this.callingInLandRecords = callingInLandRecords;
 90     }
 91 
 92     public ArrayList<CallRecord> getAnswerInCityRecords() {
 93         return answerInCityRecords;
 94     }
 95 
 96     public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
 97         this.answerInCityRecords = answerInCityRecords;
 98     }
 99 
100     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
101         return answerInProvinceRecords;
102     }
103 
104     public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
105         this.answerInProvinceRecords = answerInProvinceRecords;
106     }
107 
108     public ArrayList<CallRecord> getAnswerInLandRecords() {
109         return answerInLandRecords;
110     }
111 
112     public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
113         this.answerInLandRecords = answerInLandRecords;
114     }
115 
116     public ArrayList<MessageRecord> getSendMessageRecords() {
117         return sendMessageRecords;
118     }
119 
120     public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
121         this.sendMessageRecords = sendMessageRecords;
122     }
123 
124     public ArrayList<MessageRecord> getReceiveMessageRecords() {
125         return receiveMessageRecords;
126     }
127 
128     public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
129         this.receiveMessageRecords = receiveMessageRecords;
130     }
131 
132 }
133 class User {
134 
135     private UserRecords userRecords = new UserRecords();
136     private double balance = 100;
137     private ChargeMode chargeMode;
138     private String number;
139 
140     public double calCost() {
141         return chargeMode.calCost(userRecords);
142     }
143 
144     public double calBalance() {
145         return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
146     }
147 
148     public UserRecords getUserRecords() {
149         return userRecords;
150     }
151 
152     public void setUserRecords(UserRecords userRecords) {
153         this.userRecords = userRecords;
154     }
155 
156     public ChargeMode getChargeMode() {
157         return chargeMode;
158     }
159 
160     public void setChargeMode(ChargeMode chargeMode) {
161         this.chargeMode = chargeMode;
162     }
163 
164     public String getNumber() {
165         return number;
166     }
167 
168     public void setNumber(String number) {
169         this.number = number;
170     }
171 
172 }
173 
174 
175 
176 abstract class CommunicationRecord {
177     protected String callingNumber;
178     protected String answerNumbe;
179 
180     public String getCallingNumber() {
181         return callingNumber;
182     }
183 
184     public void setCallingNumber(String callingNumber) {
185         this.callingNumber = callingNumber;
186     }
187 
188     public String getAnswerNumbe() {
189         return answerNumbe;
190     }
191 
192     public void setAnswerNumbe(String answerNumbe) {
193         this.answerNumbe = answerNumbe;
194     }
195 
196 }
197 
198 abstract class ChargeRule {
199 
200     abstract public double calCost(UserRecords userRecords);
201 
202 }
203 
204 class CallRecord extends CommunicationRecord {
205     private Date startTime;
206     private Date endTime;
207     private String callingAddressAreaCode;
208     private String answerAddressAreaCode;
209 
210     public String getCallType() {
211         String type = "";
212         if (callingAddressAreaCode.equals("0791")) {
213             type = type.concat("1");
214         } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) {
215             type = type.concat("2");
216         } else {
217             type = type.concat("3");
218         }
219 
220         if (answerAddressAreaCode.equals("0791")) {
221             type = type.concat("1");
222         } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) {
223             type = type.concat("2");
224         } else {
225             type = type.concat("3");
226         }
227 
228         return type;
229     }
230 
231     public CallRecord(String[] inputs) {
232         super();
233 
234         char type = inputs[0].charAt(0);
235         inputs[0] = inputs[0].substring(2);
236 
237         String sd = null, st = null, ed = null, et = null;
238 
239         if (type == 't') {
240             if (inputs.length == 6) {
241                 sd = inputs[2];
242                 st = inputs[3];
243                 ed = inputs[4];
244                 et = inputs[5];
245                 callingAddressAreaCode = inputs[0].substring(0, 4);
246                 answerAddressAreaCode = inputs[1].substring(0, 4);
247             } else if (inputs.length == 7) {
248                 sd = inputs[3];
249                 st = inputs[4];
250                 ed = inputs[5];
251                 et = inputs[6];
252                 if (inputs[0].charAt(0) != '0') {
253                     if (inputs[2].length() == 10) {
254                         answerAddressAreaCode = inputs[2].substring(0, 3);
255                     } else {
256                         answerAddressAreaCode = inputs[2].substring(0, 4);
257                     }
258                     callingAddressAreaCode = inputs[1];
259                 } else {
260                     if (inputs[0].length() == 10) {
261                         callingAddressAreaCode = inputs[0].substring(0, 3);
262                     } else {
263                         callingAddressAreaCode = inputs[0].substring(0, 4);
264                     }
265                     answerAddressAreaCode = inputs[2];
266                 }
267             } else if (inputs.length == 8) {
268                 sd = inputs[4];
269                 st = inputs[5];
270                 ed = inputs[6];
271                 et = inputs[7];
272                 callingAddressAreaCode = inputs[1];
273                 answerAddressAreaCode = inputs[3];
274             }
275         } else if (type == 'm') {
276 
277         }
278         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
279         try {
280             startTime = simpleDateFormat.parse(sd + " " + st);
281             endTime = simpleDateFormat.parse(ed + " " + et);
282         } catch (ParseException e) {
283         }
284 
285     }
286 
287     public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
288         super();
289         this.startTime = startTime;
290         this.endTime = endTime;
291         this.callingAddressAreaCode = callingAddressAreaCode;
292         this.answerAddressAreaCode = answerAddressAreaCode;
293     }
294 
295     public Date getStartTime() {
296         return startTime;
297     }
298 
299     public void setStartTime(Date startTime) {
300         this.startTime = startTime;
301     }
302 
303     public Date getEndTime() {
304         return endTime;
305     }
306 
307     public void setEndTime(Date endTime) {
308         this.endTime = endTime;
309     }
310 
311     public String getCallingAddressAreaCode() {
312         return callingAddressAreaCode;
313     }
314 
315     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
316         this.callingAddressAreaCode = callingAddressAreaCode;
317     }
318 
319     public String getAnswerAddressAreaCode() {
320         return answerAddressAreaCode;
321     }
322 
323     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
324         this.answerAddressAreaCode = answerAddressAreaCode;
325     }
326 }
327 
328 abstract class CallChargeRule extends ChargeRule {
329 
330 }
331 class Point{
332     public double x, y;
333 
334     public Point(){
335         this.x = 0;
336         this.y = 0;
337     }
338     public Point(double a,double b){
339         this.x = a;
340         this.y = b;
341     }
342 
343     public void print(){
344         String x = String.format("%.6f",this.x);
345         String y = String.format("%.6f",this.y);
346         x = x.replaceAll("0+?$", "");
347         y = y.replaceAll("0+?$", "");
348         System.out.printf("(%s , %s)\n",this.x,this.y);
349     }
350 
351     //两点坐标相同
352     public boolean isSameTo(Point a){
353         return (this.x == a.x)&&(this.y == a.y);
354     }
355     //两点距离
356     public double disToPoint(Point another){
357         return Math.sqrt(Math.pow(this.x-another.x,2) + Math.pow(this.y-another.y,2));
358     }
359 }
360 class LandlinePhoneCharging extends ChargeMode {
361 
362     private double monthlyRent = 20;
363 
364     public LandlinePhoneCharging() {
365         super();
366         chargeRules.add(new LandPhoneInCityRule());
367         chargeRules.add(new LandPhoneInProvinceRule());
368         chargeRules.add(new LandPhoneInlandRule());
369     }
370 
371     @Override
372     public double calCost(UserRecords userRecords) {
373         double sumCost = 0;
374         for (ChargeRule rule : chargeRules) {
375             sumCost += rule.calCost(userRecords);
376         }
377         return sumCost;
378     }
379 
380     @Override
381     public double getMonthlyRent() {
382         return monthlyRent;
383     }
384 
385 }
386 
387 class MobilePhoneCharging extends ChargeMode {
388 
389     private double monthlyRent = 15;
390 
391     public MobilePhoneCharging() {
392         super();
393         chargeRules.add(new MobilePhoneInCityRule());
394         chargeRules.add(new MobilePhoneInProvinceRule());
395         chargeRules.add(new MobilePhoneInlandRule());
396     }
397 
398     @Override
399     public double calCost(UserRecords userRecords) {
400         double sumCost = 0;
401         for (ChargeRule rule : chargeRules) {
402             sumCost += rule.calCost(userRecords);
403         }
404         return sumCost;
405     }
406 
407     @Override
408     public double getMonthlyRent() {
409         return monthlyRent;
410     }
411 
412 }
413 
414 class LandPhoneInCityRule extends CallChargeRule {
415 
416     @Override
417     public double calCost(UserRecords userRecords) {
418         double sumCost = 0;
419         for (CallRecord call : userRecords.getCallingInCityRecords()) {
420             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
421             if (distanceS < 0) {
422                 continue;
423             }
424             double distanceM = (int) distanceS / 60;
425             if (distanceS % 60 != 0) {
426                 distanceM += 1;
427             }
428             if (call.getCallType().equals("11")) {
429                 sumCost += distanceM * 0.1;
430             } else if (call.getCallType().equals("12")) {
431                 sumCost += distanceM * 0.3;
432             } else if (call.getCallType().equals("13")) {
433                 sumCost += distanceM * 0.6;
434             }
435         }
436         return sumCost;
437     }
438 
439 }
440 
441 class LandPhoneInlandRule extends CallChargeRule {
442 
443     @Override
444     public double calCost(UserRecords userRecords) {
445         double sumCost = 0;
446         for (CallRecord call : userRecords.getCallingInLandRecords()) {
447             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
448             if (distanceS < 0) {
449                 continue;
450             }
451             double distanceM = (int) distanceS / 60;
452             if (distanceS % 60 != 0) {
453                 distanceM += 1;
454             }
455             sumCost += distanceM * 0.6;
456         }
457         return sumCost;
458     }
459 
460 }
461 
462 class LandPhoneInProvinceRule extends CallChargeRule {
463 
464     @Override
465     public double calCost(UserRecords userRecords) {
466         double sumCost = 0;
467         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
468             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
469             if (distanceS < 0) {
470                 continue;
471             }
472             double distanceM = (int) distanceS / 60;
473             if (distanceS % 60 != 0) {
474                 distanceM += 1;
475             }
476             sumCost += distanceM * 0.3;
477         }
478         return sumCost;
479     }
480 
481 }
482 
483 class MobilePhoneInCityRule extends CallChargeRule {
484 
485     @Override
486     public double calCost(UserRecords userRecords) {
487         double sumCost = 0;
488         for (CallRecord call : userRecords.getCallingInCityRecords()) {
489             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
490             if (distanceS < 0) {
491                 continue;
492             }
493             double distanceM = (int) distanceS / 60;
494             if (distanceS % 60 != 0) {
495                 distanceM += 1;
496             }
497             if (call.getCallType().equals("11")) {
498                 sumCost += distanceM * 0.1;
499             } else if (call.getCallType().equals("12")) {
500                 sumCost += distanceM * 0.2;
501             } else if (call.getCallType().equals("13")) {
502                 sumCost += distanceM * 0.3;
503             }
504 
505         }
506         return sumCost;
507     }
508 
509 }
510 
511 class MobilePhoneInlandRule extends CallChargeRule {
512 
513     @Override
514     public double calCost(UserRecords userRecords) {
515         double sumCost = 0;
516         for (CallRecord call : userRecords.getCallingInLandRecords()) {
517             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
518             if (distanceS < 0) {
519                 continue;
520             }
521             double distanceM = (int) distanceS / 60;
522             if (distanceS % 60 != 0) {
523                 distanceM += 1;
524             }
525             sumCost += distanceM * 0.6;
526         }
527         for (CallRecord call : userRecords.getAnswerInLandRecords()) {
528             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
529             if (distanceS < 0) {
530                 continue;
531             }
532             double distanceM = (int) distanceS / 60;
533             if (distanceS % 60 != 0) {
534                 distanceM += 1;
535             }
536             sumCost += distanceM * 0.3;
537         }
538         return sumCost;
539     }
540 
541 }
542 
543 class MobilePhoneInProvinceRule extends CallChargeRule {
544 
545     @Override
546     public double calCost(UserRecords userRecords) {
547         double sumCost = 0;
548         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
549             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
550             if (distanceS < 0) {
551                 continue;
552             }
553             double distanceM = (int) distanceS / 60;
554             if (distanceS % 60 != 0) {
555                 distanceM += 1;
556             }
557             if (call.getCallType().equals("21")) {
558                 sumCost += distanceM * 0.3;
559             } else if (call.getCallType().equals("22")) {
560                 sumCost += distanceM * 0.3;
561             } else if (call.getCallType().equals("23")) {
562                 sumCost += distanceM * 0.3;
563             }
564         }
565         return sumCost;
566     }
567 
568 }
569 
570 class MessageRecord extends CommunicationRecord {
571 
572     private String message;
573 
574     public String getMessage() {
575         return message;
576     }
577 
578     public void setMessage(String message) {
579         this.message = message;
580     }
581 }
582 
583 
584 class Input {
585 
586     public int check(String input) {
587         if (input.matches("[u]-0791\\d{7,8}\\s[0]") || input.matches("[u]-1\\d{10}\\s[1]")) {
588             return 1;
589         } else if (input.matches("(([t]-0791\\d{7,8}\\s" + "0\\d{9,11}\\s)|"
590                 + "([t]-0791\\d{7,8}\\s" + "1\\d{10}\\s" + "0[0-9]{2,3}\\s)|"
591                 + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "0[0-9]{9,11}\\s)|"
592                 + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s))"
593 
594                 + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?"
595                 + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((("
596                 + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"
597                 + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s"
598                 + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.("
599                 + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((("
600                 + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"
601                 + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])")) {
602             return 2;
603         }
604         return 0;
605     }
606 
607     @SuppressWarnings("unused")
608     private boolean validatet(String string) {
609         if (!string.matches("^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$")) {
610             return false;
611         }
612         return true;
613     }
614 
615     public static boolean validate(String dateString) {
616         // 使用正则表达式 测试 字符 符合 dddd.dd.dd 的格式(d表示数字)
617         Pattern p = Pattern.compile("\\d{4}+[\\.]\\d{1,2}+[\\.]\\d{1,2}+");
618         Matcher m = p.matcher(dateString);
619         if (!m.matches()) {
620             return false;
621         }
622 
623         // 得到年月日
624         String[] array = dateString.split("\\.");
625         int year = Integer.valueOf(array[0]);
626         int month = Integer.valueOf(array[1]);
627         int day = Integer.valueOf(array[2]);
628 
629         if (month < 1 || month > 12) {
630             return false;
631         }
632         int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
633         if (isLeapYear(year)) {
634             monthLengths[2] = 29;
635         } else {
636             monthLengths[2] = 28;
637         }
638         int monthLength = monthLengths[month];
639         if (day < 1 || day > monthLength) {
640             return false;
641         }
642         return true;
643     }
644 
645     /** 是否是闰年 */
646     private static boolean isLeapYear(int year) {
647         return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
648     }
649 
650     public boolean judge(String input) {
651 
652         return false;
653     }
654 
655     public void writeUser(ArrayList<User> users, String input) {
656         User usernew = new User();
657         String[] inputs = input.split(" ");
658         String num = inputs[0].substring(2);
659         for (User i : users) {
660             if (i.getNumber().equals(num)) {
661                 return;
662             }
663         }
664         usernew.setNumber(num);
665         int mode = Integer.parseInt(inputs[1]);
666         if (mode == 0) {
667             usernew.setChargeMode(new LandlinePhoneCharging());
668         } else if (mode == 1) {
669             usernew.setChargeMode(new MobilePhoneCharging());
670         }
671         users.add(usernew);
672     }
673 
674     public void writeRecord(ArrayList<User> users, String input) {
675         String[] inputs = input.split(" ");
676 
677         User callu = null, answeru = null;
678         CallRecord callrecord = new CallRecord(inputs);
679 
680         if (input.charAt(0) == 't') {
681             String out = inputs[0];
682             String in = "";
683             if (inputs.length == 6) {
684                 in = inputs[1];
685             } else if (inputs.length == 7) {
686                 in = inputs[1];
687             } else if (inputs.length == 8) {
688                 in = inputs[2];
689             }
690 
691             for (User i : users) {
692                 if (i.getNumber().equals(out)) {
693                     callu = i;
694                 }
695                 if (i.getNumber().equals(in)) {
696                     answeru = i;
697                 }
698                 if (callu != null && answeru != null) {
699                     break;
700                 }
701             }
702 
703             if (callu != null) {
704                 if (callrecord.getCallType().matches("^1[1-3]$")) {
705                     callu.getUserRecords().addCallingInCityRecords(callrecord);
706                 } else if (callrecord.getCallType().matches("^2[1-3]$")) {
707                     callu.getUserRecords().addCallingInProvinceRecords(callrecord);
708                 } else {
709                     callu.getUserRecords().addCallingInLandRecords(callrecord);
710                 }
711             }
712 
713             if (answeru != null) {
714                 if (callrecord.getCallType().matches("^[1-3]1$")) {
715                     answeru.getUserRecords().addAnswerInCityRecords(callrecord);
716                 } else if (callrecord.getCallType().matches("^[1-3]2$")) {
717                     answeru.getUserRecords().aaddAnswerInProvinceRecords(callrecord);
718                 } else {
719                     answeru.getUserRecords().addAnswerInLandRecords(callrecord);
720                 }
721             }
722         } else if (input.charAt(0) == 'm') {
723 
724         }
725 
726     }
727 
728 }
729 class show {
730 
731     @SuppressWarnings("deprecation")
732     public void output(double out) {
733         BigDecimal numb = new BigDecimal(out);
734         out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
735         System.out.print(out);
736     }
737 }
738 public class Main {
739 
740     public static void main(String[] args) {
741 
742         show outputtool = new show();
743 
744         Input inputdeal = new Input();
745 
746         ArrayList<User> users = new ArrayList<>();
747 
748         Scanner in = new Scanner(System.in);
749 
750         String input = in.nextLine();
751 
752         while (!input.equals("end")) {
753             if (1 == inputdeal.check(input)) {
754                 inputdeal.writeUser(users, input);
755             } else if (2 == inputdeal.check(input)) {
756                 inputdeal.writeRecord(users, input);
757             }
758             input = in.nextLine();
759         }
760 
761         users.sort(new Comparator<User>() {
762 
763             @Override
764             public int compare(User u1, User u2) {
765                 if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') {
766                     return -1;
767                 } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') {
768                     return 1;
769                 }
770                 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
771                     return 1;
772                 } else {
773                     return -1;
774                 }
775             }
776         });
777 
778         for (User u : users) {
779             System.out.print(u.getNumber() + " ");
780             outputtool.output(u.calCost());
781             System.out.print(" ");
782             outputtool.output(u.calBalance());
783             System.out.println();
784 
785         }
786 
787     }
788 
789 }
View Code

 

分析:

这道题相比于上道题,这道题的难点在于这个话费计算不到要考虑市内、省内、国内这种区域性问题,还要考虑你是接听方还是拨打方

以及是座机还是手机打电话,每一种计费方式都不同,都要变化,难度加大。

由上图分析可知,又是Max complexity过大,嵌套语句太多了,不用说,这几道题我都是if-else语句过多。

 

 

7-1 电信计费系列3-短信计费 分数 50 作者 蔡轲 单位 南昌航空大学

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

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

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

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

建议类图:
参见图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)。
 

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

输入样例:

在这里给出一组输入。例如:

u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaaaaaaaaaaaaa
end
 

输出样例:

在这里给出相应的输出。例如:

18907910010 0.3 99.7
 
### 输入样例1:
 

在这里给出一组输入。例如:

u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaa
m-18907910010 13305862264 aaaaaaa.
m-18907910010 13305862264 bb,bbbb
end
 

输出样例1:

在这里给出相应的输出。例如:

18907910010 0.5 99.5

源码:

(点加号)
  1 import java.math.BigDecimal;
  2 import java.text.ParseException;
  3 import java.text.SimpleDateFormat;
  4 import java.util.*;
  5 
  6 public class Main {
  7 
  8     public static void main(String[] args) {
  9         Scanner in = new Scanner(System.in);
 10         Input input = new Input();
 11         Output output = new Output();
 12         ArrayList<User> users = new ArrayList<>();
 13         String input1 = in.nextLine();
 14         while (!input1.equals("end")) {
 15             if (1 == input.check(input1)) {
 16                 input.writeUser(users, input1);
 17             } else if (2 == input.check(input1)) {
 18                 input.writeRecord(users, input1);
 19             }
 20             input1 = in.nextLine();
 21         }
 22 
 23         users.sort(new Comparator<User>() {
 24 
 25             @Override
 26             public int compare(User u1, User u2) {
 27                 if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') {
 28                     return -1;
 29                 } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') {
 30                     return 1;
 31                 }
 32                 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
 33                     return 1;
 34                 } else {
 35                     return -1;
 36                 }
 37             }
 38         });
 39 
 40         for (User u : users) {
 41             System.out.print(u.getNumber() + " ");
 42             output.output(u.calCost());
 43             System.out.print(" ");
 44             output.output(u.calBalance());
 45             System.out.println();
 46 
 47         }
 48 
 49     }
 50 
 51 }
 52 class User {
 53 
 54     private UserRecords userRecords = new UserRecords();
 55     private double balance = 100;
 56     private ChargeMode chargeMode;
 57     private String number;
 58 
 59     public double calCost() {
 60         return chargeMode.calCost(userRecords);
 61     }
 62 
 63     public double calBalance() {
 64         return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
 65     }
 66 
 67     public UserRecords getUserRecords() {
 68         return userRecords;
 69     }
 70 
 71     public void setUserRecords(UserRecords userRecords) {
 72         this.userRecords = userRecords;
 73     }
 74 
 75     public ChargeMode getChargeMode() {
 76         return chargeMode;
 77     }
 78 
 79     public void setChargeMode(ChargeMode chargeMode) {
 80         this.chargeMode = chargeMode;
 81     }
 82 
 83     public String getNumber() {
 84         return number;
 85     }
 86 
 87     public void setNumber(String number) {
 88         this.number = number;
 89     }
 90 
 91 }
 92 
 93 class Output {
 94 
 95     @SuppressWarnings("deprecation")
 96     public void output(double out) {
 97 
 98         BigDecimal numb = new BigDecimal(out);
 99         out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
100         System.out.print(out);
101     }
102 }
103 abstract class ChargeMode {
104     protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
105 
106     public abstract double calCost(UserRecords userRecords);
107 
108     public abstract double getMonthlyRent();
109 
110     public ArrayList<ChargeRule> getChargeRules() {
111         return chargeRules;
112     }
113 
114     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
115         this.chargeRules = chargeRules;
116     }
117 }
118 
119 class UserRecords {
120 
121     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
122     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
123     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
124     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
125     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
126     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
127     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
128     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
129 
130     public void addCallingInCityRecords(CallRecord callRecord) {
131         callingInCityRecords.add(callRecord);
132     }
133 
134     public void addCallingInProvinceRecords(CallRecord callRecord) {
135         callingInProvinceRecords.add(callRecord);
136     }
137 
138     public void addCallingInLandRecords(CallRecord callRecord) {
139         callingInLandRecords.add(callRecord);
140     }
141 
142     public void addAnswerInCityRecords(CallRecord callRecord) {
143         answerInCityRecords.add(callRecord);
144     }
145 
146     public void aaddAnswerInProvinceRecords(CallRecord callRecord) {
147         answerInProvinceRecords.add(callRecord);
148     }
149 
150     public void addAnswerInLandRecords(CallRecord callRecord) {
151         answerInLandRecords.add(callRecord);
152     }
153 
154     public void addSendMessageRecords(MessageRecord callRecord) {
155         sendMessageRecords.add(callRecord);
156     }
157 
158     public void addReceiveMessageRecords(MessageRecord callRecord) {
159         receiveMessageRecords.add(callRecord);
160     }
161 
162     public ArrayList<CallRecord> getCallingInCityRecords() {
163         return callingInCityRecords;
164     }
165 
166     public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
167         this.callingInCityRecords = callingInCityRecords;
168     }
169 
170     public ArrayList<CallRecord> getCallingInProvinceRecords() {
171         return callingInProvinceRecords;
172     }
173 
174     public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
175         this.callingInProvinceRecords = callingInProvinceRecords;
176     }
177 
178     public ArrayList<CallRecord> getCallingInLandRecords() {
179         return callingInLandRecords;
180     }
181 
182     public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
183         this.callingInLandRecords = callingInLandRecords;
184     }
185 
186     public ArrayList<CallRecord> getAnswerInCityRecords() {
187         return answerInCityRecords;
188     }
189 
190     public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
191         this.answerInCityRecords = answerInCityRecords;
192     }
193 
194     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
195         return answerInProvinceRecords;
196     }
197 
198     public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
199         this.answerInProvinceRecords = answerInProvinceRecords;
200     }
201 
202     public ArrayList<CallRecord> getAnswerInLandRecords() {
203         return answerInLandRecords;
204     }
205 
206     public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
207         this.answerInLandRecords = answerInLandRecords;
208     }
209 
210     public ArrayList<MessageRecord> getSendMessageRecords() {
211         return sendMessageRecords;
212     }
213 
214     public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
215         this.sendMessageRecords = sendMessageRecords;
216     }
217 
218     public ArrayList<MessageRecord> getReceiveMessageRecords() {
219         return receiveMessageRecords;
220     }
221 
222     public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
223         this.receiveMessageRecords = receiveMessageRecords;
224     }
225 
226 }
227 class MobilePhoneMassageCharging extends ChargeMode {
228 
229     private double monthlyRent = 0;
230 
231     public MobilePhoneMassageCharging() {
232         super();
233         chargeRules.add(new MobilePhoneMessageRule());
234     }
235 
236     @Override
237     public double calCost(UserRecords userRecords) {
238         double sumCost = 0;
239         for (ChargeRule rule : chargeRules) {
240             sumCost += rule.calCost(userRecords);
241         }
242         return sumCost;
243     }
244 
245     @Override
246     public double getMonthlyRent() {
247         return monthlyRent;
248     }
249 
250 }
251 class LandlinePhoneCharging extends ChargeMode {
252 
253     private double monthlyRent = 20;
254 
255     public LandlinePhoneCharging() {
256         super();
257         chargeRules.add(new LandPhoneInCityRule());
258         chargeRules.add(new LandPhoneInProvinceRule());
259         chargeRules.add(new LandPhoneInlandRule());
260     }
261 
262     @Override
263     public double calCost(UserRecords userRecords) {
264         double sumCost = 0;
265         for (ChargeRule rule : chargeRules) {
266             sumCost += rule.calCost(userRecords);
267         }
268         return sumCost;
269     }
270 
271     @Override
272     public double getMonthlyRent() {
273         return monthlyRent;
274     }
275 
276 }
277 
278 class MobilePhoneCharging extends ChargeMode {
279 
280     private double monthlyRent = 15;
281 
282     public MobilePhoneCharging() {
283         super();
284         chargeRules.add(new MobilePhoneInCityRule());
285         chargeRules.add(new MobilePhoneInProvinceRule());
286         chargeRules.add(new MobilePhoneInlandRule());
287     }
288 
289     @Override
290     public double calCost(UserRecords userRecords) {
291         double sumCost = 0;
292         for (ChargeRule rule : chargeRules) {
293             sumCost += rule.calCost(userRecords);
294         }
295         return sumCost;
296     }
297 
298     @Override
299     public double getMonthlyRent() {
300         return monthlyRent;
301     }
302 
303 }
304 
305 
306 class Input {
307 
308     public int check(String input) {
309         if (input.matches("[u]-0791[0-9]{7,8}\\s[0]") || input.matches("[u]-1[0-9]{10}\\s[13]")) {
310             return 1;
311         } else if (input.matches("[m]-1[0-9]{10}\\s" + "1[0-9]{10}\\s" + "[0-9a-zA-Z\\s\\.,]+")) {
312             return 2;
313         }
314         return 0;
315     }
316 
317     public void writeUser(ArrayList<User> users, String input) {
318         User usernew = new User();
319         String[] inputs = input.split(" ");
320         String num = inputs[0].substring(2);
321         for (User i : users) {
322             if (i.getNumber().equals(num)) {
323                 return;
324             }
325         }
326         usernew.setNumber(num);
327         int mode = Integer.parseInt(inputs[1]);
328         if (mode == 0) {
329             usernew.setChargeMode(new LandlinePhoneCharging());
330         } else if (mode == 1) {
331             usernew.setChargeMode(new MobilePhoneCharging());
332         } else if (mode == 3) {
333             usernew.setChargeMode(new MobilePhoneMassageCharging());
334         }
335         users.add(usernew);
336     }
337 
338     public void writeRecord(ArrayList<User> users, String input) {
339         String[] inputs = input.split(" ");
340         inputs[0] = inputs[0].substring(2);
341 
342         User callu = null, answeru = null;
343 
344         String out = inputs[0];
345         String in = "";
346         if (inputs.length == 6) {
347             in = inputs[1];
348         } else if (inputs.length == 7) {
349             in = inputs[1];
350         } else if (inputs.length == 8) {
351             in = inputs[2];
352         } else {
353             in = inputs[1];
354         }
355 
356         for (User i : users) {
357             if (i.getNumber().equals(out)) {
358                 callu = i;
359             }
360             if (i.getNumber().equals(in)) {
361                 answeru = i;
362             }
363             if (callu != null && answeru != null) {
364                 break;
365             }
366         }
367 
368         if (input.charAt(0) == 'm') {
369             MessageRecord messageRecord = new MessageRecord(input);
370             if (callu != null) {
371                 callu.getUserRecords().addSendMessageRecords(messageRecord);
372                 ;
373             }
374             if (answeru != null) {
375                 callu.getUserRecords().addReceiveMessageRecords(messageRecord);
376             }
377         }
378 
379     }
380 
381 }
382 
383 abstract class CommunicationRecord {
384     protected String callingNumber;
385     protected String answerNumbe;
386 
387     public String getCallingNumber() {
388         return callingNumber;
389     }
390 
391     public void setCallingNumber(String callingNumber) {
392         this.callingNumber = callingNumber;
393     }
394 
395     public String getAnswerNumbe() {
396         return answerNumbe;
397     }
398 
399     public void setAnswerNumbe(String answerNumbe) {
400         this.answerNumbe = answerNumbe;
401     }
402 
403 }
404 
405 abstract class ChargeRule {
406 
407     abstract public double calCost(UserRecords userRecords);
408 
409 }
410 
411 class CallRecord extends CommunicationRecord {
412     private Date startTime;
413     private Date endTime;
414     private String callingAddressAreaCode;
415     private String answerAddressAreaCode;
416 
417     public String getCallType() {
418         String type = "";
419         if (callingAddressAreaCode.equals("0791")) {
420             type = type.concat("1");
421         } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) {
422             type = type.concat("2");
423         } else {
424             type = type.concat("3");
425         }
426 
427         if (answerAddressAreaCode.equals("0791")) {
428             type = type.concat("1");
429         } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) {
430             type = type.concat("2");
431         } else {
432             type = type.concat("3");
433         }
434 
435         return type;
436     }
437 
438     public CallRecord(String[] inputs) {
439         super();
440 
441         char type = inputs[0].charAt(0);
442 
443         String sd = null, st = null, ed = null, et = null;
444 
445         if (type == 't') {
446             if (inputs.length == 6) {
447                 sd = inputs[2];
448                 st = inputs[3];
449                 ed = inputs[4];
450                 et = inputs[5];
451                 callingAddressAreaCode = inputs[0].substring(0, 4);
452                 answerAddressAreaCode = inputs[1].substring(0, 4);
453             } else if (inputs.length == 7) {
454                 sd = inputs[3];
455                 st = inputs[4];
456                 ed = inputs[5];
457                 et = inputs[6];
458                 if (inputs[0].charAt(0) != '0') {
459                     if (inputs[2].length() == 10) {
460                         answerAddressAreaCode = inputs[2].substring(0, 3);
461                     } else {
462                         answerAddressAreaCode = inputs[2].substring(0, 4);
463                     }
464                     callingAddressAreaCode = inputs[1];
465                 } else {
466                     if (inputs[0].length() == 10) {
467                         callingAddressAreaCode = inputs[0].substring(0, 3);
468                     } else {
469                         callingAddressAreaCode = inputs[0].substring(0, 4);
470                     }
471                     answerAddressAreaCode = inputs[2];
472                 }
473             } else if (inputs.length == 8) {
474                 sd = inputs[4];
475                 st = inputs[5];
476                 ed = inputs[6];
477                 et = inputs[7];
478                 callingAddressAreaCode = inputs[1];
479                 answerAddressAreaCode = inputs[3];
480             }
481         } else if (type == 'm') {
482 
483         }
484         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
485         try {
486             startTime = simpleDateFormat.parse(sd + " " + st);
487             endTime = simpleDateFormat.parse(ed + " " + et);
488         } catch (ParseException e) {
489         }
490 
491     }
492 
493     public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
494         super();
495         this.startTime = startTime;
496         this.endTime = endTime;
497         this.callingAddressAreaCode = callingAddressAreaCode;
498         this.answerAddressAreaCode = answerAddressAreaCode;
499     }
500 
501     public Date getStartTime() {
502         return startTime;
503     }
504 
505     public void setStartTime(Date startTime) {
506         this.startTime = startTime;
507     }
508 
509     public Date getEndTime() {
510         return endTime;
511     }
512 
513     public void setEndTime(Date endTime) {
514         this.endTime = endTime;
515     }
516 
517     public String getCallingAddressAreaCode() {
518         return callingAddressAreaCode;
519     }
520 
521     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
522         this.callingAddressAreaCode = callingAddressAreaCode;
523     }
524 
525     public String getAnswerAddressAreaCode() {
526         return answerAddressAreaCode;
527     }
528 
529     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
530         this.answerAddressAreaCode = answerAddressAreaCode;
531     }
532 }
533 
534 abstract class CallChargeRule extends ChargeRule {
535 
536 }
537 
538 class LandPhoneInCityRule extends CallChargeRule {
539 
540     @Override
541     public double calCost(UserRecords userRecords) {
542         double sumCost = 0;
543         for (CallRecord call : userRecords.getCallingInCityRecords()) {
544             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
545             if (distanceS < 0) {
546                 continue;
547             }
548             double distanceM = (int) distanceS / 60;
549             if (distanceS % 60 != 0) {
550                 distanceM += 1;
551             }
552             if (call.getCallType().equals("11")) {
553                 sumCost += distanceM * 0.1;
554             } else if (call.getCallType().equals("12")) {
555                 sumCost += distanceM * 0.3;
556             } else if (call.getCallType().equals("13")) {
557                 sumCost += distanceM * 0.6;
558             }
559         }
560         return sumCost;
561     }
562 
563 }
564 
565 class LandPhoneInlandRule extends CallChargeRule {
566 
567     @Override
568     public double calCost(UserRecords userRecords) {
569         double sumCost = 0;
570         for (CallRecord call : userRecords.getCallingInLandRecords()) {
571             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
572             if (distanceS < 0) {
573                 continue;
574             }
575             double distanceM = (int) distanceS / 60;
576             if (distanceS % 60 != 0) {
577                 distanceM += 1;
578             }
579             sumCost += distanceM * 0.6;
580         }
581         return sumCost;
582     }
583 
584 }
585 
586 class LandPhoneInProvinceRule extends CallChargeRule {
587 
588     @Override
589     public double calCost(UserRecords userRecords) {
590         double sumCost = 0;
591         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
592             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
593             if (distanceS < 0) {
594                 continue;
595             }
596             double distanceM = (int) distanceS / 60;
597             if (distanceS % 60 != 0) {
598                 distanceM += 1;
599             }
600             sumCost += distanceM * 0.3;
601         }
602         return sumCost;
603     }
604 
605 }
606 
607 class MobilePhoneInCityRule extends CallChargeRule {
608 
609     @Override
610     public double calCost(UserRecords userRecords) {
611         double sumCost = 0;
612         for (CallRecord call : userRecords.getCallingInCityRecords()) {
613             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
614             if (distanceS < 0) {
615                 continue;
616             }
617             double distanceM = (int) distanceS / 60;
618             if (distanceS % 60 != 0) {
619                 distanceM += 1;
620             }
621             if (call.getCallType().equals("11")) {
622                 sumCost += distanceM * 0.1;
623             } else if (call.getCallType().equals("12")) {
624                 sumCost += distanceM * 0.2;
625             } else if (call.getCallType().equals("13")) {
626                 sumCost += distanceM * 0.3;
627             }
628 
629         }
630         return sumCost;
631     }
632 
633 }
634 
635 class MobilePhoneInlandRule extends CallChargeRule {
636 
637     @Override
638     public double calCost(UserRecords userRecords) {
639         double sumCost = 0;
640         for (CallRecord call : userRecords.getCallingInLandRecords()) {
641             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
642             if (distanceS < 0) {
643                 continue;
644             }
645             double distanceM = (int) distanceS / 60;
646             if (distanceS % 60 != 0) {
647                 distanceM += 1;
648             }
649             sumCost += distanceM * 0.6;
650         }
651         for (CallRecord call : userRecords.getAnswerInLandRecords()) {
652             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
653             if (distanceS < 0) {
654                 continue;
655             }
656             double distanceM = (int) distanceS / 60;
657             if (distanceS % 60 != 0) {
658                 distanceM += 1;
659             }
660             sumCost += distanceM * 0.3;
661         }
662         return sumCost;
663     }
664 
665 }
666 
667 class MobilePhoneInProvinceRule extends CallChargeRule {
668 
669     @Override
670     public double calCost(UserRecords userRecords) {
671         double sumCost = 0;
672         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
673             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
674             if (distanceS < 0) {
675                 continue;
676             }
677             double distanceM = (int) distanceS / 60;
678             if (distanceS % 60 != 0) {
679                 distanceM += 1;
680             }
681             if (call.getCallType().equals("21")) {
682                 sumCost += distanceM * 0.3;
683             } else if (call.getCallType().equals("22")) {
684                 sumCost += distanceM * 0.3;
685             } else if (call.getCallType().equals("23")) {
686                 sumCost += distanceM * 0.3;
687             }
688         }
689         return sumCost;
690     }
691 
692 }
693 
694 class MobilePhoneMessageRule extends CallChargeRule {
695 
696     @Override
697     public double calCost(UserRecords userRecords) {
698         double sumCost = 0;
699         int number = 0;
700         for (MessageRecord m : userRecords.getSendMessageRecords()) {
701             int length = m.getMessage().length();
702             if (length <= 10) {
703                 number++;
704             } else {
705                 number += length / 10;
706                 if (length % 10 != 0) {
707                     number++;
708                 }
709             }
710         }
711         if (number <= 3) {
712             sumCost = number * 0.1;
713         } else if (number <= 5) {
714             sumCost = 0.3 + 0.2 * (number - 3);
715         } else {
716             sumCost = 0.7 + 0.3 * (number - 5);
717         }
718         return sumCost;
719     }
720 
721 }
722 
723 class MessageRecord extends CommunicationRecord {
724 
725     private String message;
726 
727     public MessageRecord(String input) {
728         super();
729         this.message = input.substring(26);
730     }
731 
732     public String getMessage() {
733         return message;
734     }
735 
736     public void setMessage(String message) {
737         this.message = message;
738     }
739 }
740  
View Code

 

分析:

在上一道题的基础上新增短信计费,需要将短信类重写。再加上一个短信计费的算法。注意判断短信内容分割时,用正则表达式注意空格。

 

(3)踩坑心得

电信计费1

建议使用正则表达式

注意时间必须符合"yyyy.MM.dd HH:mm:ss"格式。一般使用SimpleDateFormat类。

 

 

 电信计费2

注意考虑到座机、手机用户混合时非法输入以及座机、手机用户混合时重复的用户开户信息的情况。


 

 

 电信计费3

没什么好说的,注意怎么计算短信用费就好了

 

 

 

 

(4)改进建议

这几次作业难度都有所下降,完成度提高了,挺好的。

最大复杂度太大了,可以尽量少用嵌套语句。

对于抽象类怎么使用还需要加强训练,还有接口的使用。

(5)总结

10-16周不但有PTA的三次大作业,还有几次实验,经过这些,使我对于多态、抽象类理解掌握更深了。尤其是上转型还是下转型怎么使用终于搞明白了,

不再是云里雾里。对于怎么使用ArryList中的方法也有了一定的把握。明白可以抽象类实现对子类方法的重写以及扩展该模块的行为功能。但是对于接口

的使用还是有一点问题。还有写代码时有时候思路不清晰,一顿乱操作。除此之外,虽然这几次作业中没有线程和装饰器之类的题,但是课堂作业布置了,

我感觉这线程和装饰类比多态和抽象类要更好掌握。很开心能学到这些。总之这几周的学习让我对于类的理解与使用更透彻了,如何转型、怎么调用子类

或父类的方法有了自己的理解。

 

标签:inputs,return,String,double,ArrayList,BLOG,public
From: https://www.cnblogs.com/lmlin/p/16969026.html

相关文章

  • java第三次blog总结
    前言对10~16周学习的内容,由本次博客来进行一个总结。1.这几周主要是电信收费系列题目,考察我们对于正则表达式的掌握于运用。2.对......
  • BLOG-3
    (1)前言: 总结之前所涉及到的知识点、题量、难度等情况    题目集6:知识点:容器、接口、多态、类图相关知识,正则表达式 题量:中  难度:中  题目集7:知识点:容......
  • blog3
    一、前言这几次的作业题量适中,主要重点封装、继承、多态、抽象类的使用、正则表达式,接口,还有一些和javafx相关的知识,主要题型就是看类图补全代码,其中电信计费系列是比较难......
  • BLOG-3
    (一)前言(1)知识点1.ArrayList类的使用2.输入字符串的处理3.类设计的搭建与实现4.SimpleDateFormat类实现输入时间格式化处理 (2)题量三次以电信计费系列为主的pta,其他......
  • Blog3:nchu-software-oop-2022-6~8
    Blog3:nchu-software-oop-2022-6~8一、前言不知不觉,已到了本学期末尾,面向对象程序设计这门课也已经结课。课程虽然结束了,但需要学习和巩固的知识点还有很多。同时,这也......
  • Remember的Java-blog3
    一、前言    此次blog为电信计费系列的座机,手机,短信大作业总结。相对于前几次的多边形,这次在算法上更简单,但是涉及到的内容很多,比如容器的使用、抛出异常、抽象类......
  • BLOG-3
    (一)、前言  题目集六:7-1:电信计费系列1-座机计费难度:8知识点:正则表达式,类的继承,抽象类的使用,抽象方法重写7-2: 多态测试难度:2知识点:接口的实现......
  • BLOG-3对之前发布的6-8次PTA题目集(电信计费)总结
     for(Useru:users)前言:总结之前所涉及到的知识点、题量、难度等情况_____________________________________________________________________________________......
  • 面向对象程序设计(BLOG-3)
    面向对象程序设计(BLOG-3) 前言:本次博客的题目大都以多态、容器和继承的方式进行相关内容的考察,难度比之前的点线系列题目相对增加。 设计与分析 7-1电信计费......
  • BLOG-3
    1.前言该bolg将对近三次的大作业进行总结与分析。近三次大作业主要写了电信计费系统的主要功能,第一次大作业是座机计费功能,第一次电信计费题量不多,只有两题,电信计费第一次......