对近期题目集总结分析3

前言:对这次题目集阐述一下自己的看法,这几次的题目集主要考察我们近期对java知识点的学习情况,题目量虽然不多,但是难度从难到易;本次题目集主要考察我们对多类的运用,重点考查实现电信计费代码的编写。还有多态继承的测试运用。

电信计费系列1-座机计费  

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

输入格式:

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

输出格式:

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

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

 

 

代码实现 

import java.lang.reflect.Array;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Scanner;

public class Main {

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

    public  static  void main (String [] args)
    {
        Scanner in = new Scanner(System.in);
        Scanner sc = new Scanner(System.in);
        DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        ArrayList<User>users = new ArrayList<>();
        String s;

        while(true)
        {
            s = in.nextLine();
            if(s.charAt(0) != 'u')break;
            else {
                String [] ss = s.split(" ");
                String phoneNumber = ss[0].substring(2);
                User user = new User(phoneNumber);
                user.setChargeMode(new LandlinePhoneCharging());
                users.add(user);
            }
        }
        Arrays.sort(new ArrayList[]{users});
        s = s.substring(2);
        String [] ss = s.split(" ");
        String startTime;
        String endTime;
        Date StartTime,EndTime;
        for(User user : users)
        {
            if(user.getNumber().equals(ss[0]))
            {
                String call = ss[0].substring(0, 4);
                String  receive = ss[1].substring(0, 4);
                startTime = ss[2] + " " + ss[3];
                endTime = ss[4] + " " + ss[5];
                //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                try {
                    StartTime = dateFormat.parse(startTime);
                } catch (ParseException e) {
                    continue;
                }
                try {
                    EndTime = dateFormat.parse(endTime);
                } catch (ParseException e) {
                    continue;
                }
                // CallRecord callRecord = new CallRecord();
                if(check(receive)== 1)
                {
                    user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive));
                }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime,call,receive));
                else user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime,call,receive));
            }
        }
        while(true)
        {
            s = in.nextLine();
            if(s.equals("end"))break;
            s = s.substring(2);
            String [] sss = s.split(" ");
            String sstartTime;
            String eendTime;
            Date SStartTime,EEndTime;
            for(User user : users)
            {
                if(user.getNumber().equals(sss[0]))
                {
                    String call = sss[0].substring(0, 4);
                    String  receive = sss[1].substring(0, 4);
                    sstartTime = sss[2] + " " + sss[3];
                    eendTime = sss[4] + " " + sss[5];
                    //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                    try {
                        SStartTime = dateFormat.parse(sstartTime);
                    } catch (ParseException e) {
                        continue;
                    }
                    try {
                        EEndTime = dateFormat.parse(eendTime);
                    } catch (ParseException e) {
                        continue;
                    }
                    // CallRecord callRecord = new CallRecord();
                    if(check(receive) == 1)
                    {
                        user.getUserRecords().addCallingInCityRecord(new CallRecord(SStartTime, EEndTime, call, receive));
                    }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(SStartTime, EEndTime,call,receive));
                    else user.getUserRecords().addCallingInLandRecord(new CallRecord(SStartTime, EEndTime,call,receive));
                }
            }
        }
        for(User user : users)
        {
            System.out.printf("%s %.1f %.1f\n",user.getNumber(),user.calCost(),user.calBalance());
        }
        //String time = s.substring(s.length() - )
    }
}
abstract class CallChargeRule extends  ChargeRule{
    abstract double calCost(ArrayList<CallRecord>callRecords);
}
class CallRecord extends  CommunicationRecord{
    Date startTime;
    Date endTime;
    String callingAddressAreaCode;
    String answerAddressAreaCode;

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

    public Date getStartTime() {
        return startTime;
    }

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

    public Date getEndTime() {
        return endTime;
    }

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

    public String getCallingAddressAreaCode() {
        return callingAddressAreaCode;
    }

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

    public String getAnswerAddressAreaCode() {
        return answerAddressAreaCode;
    }

    public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
        this.answerAddressAreaCode = answerAddressAreaCode;
    }
}
abstract class ChargeMode {
    ArrayList<ChargeRule> chargeRules = new ArrayList<>();

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

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

    abstract double getMonthlyRent();
}
abstract class ChargeRule {
    abstract double calCost(ArrayList<CallRecord> callRecords);
}
class CommunicationRecord {
    String callingNumber;
    String answerNumber;

    public String getCallingNumber() {
        return callingNumber;
    }

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

    public String getAnswerNumber() {
        return answerNumber;
    }

    public void setAnswerNumber(String answerNumber) {
        this.answerNumber = answerNumber;
    }
}
class LandlinePhoneCharging extends ChargeMode{
    double monthlyRent = 20;
    public LandlinePhoneCharging()
    {
        getChargeRules().add(new LandPhoneCityRule());
        getChargeRules().add(new LandPhoneLandRule());
        getChargeRules().add(new LandPhoneProvinceRule());
    }

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

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


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

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
class B{private static  double pointToLine(double x1, double y1, double x2, double y2, double x0,
                                           double y0) {
    double space = 0;
    double a, b, c;
    a = lineSpace(x1, y1, x2, y2);// 线段的长度
    b = lineSpace(x1, y1, x0, y0);// (x1,y1)到点的距离
    c = lineSpace(x2, y2, x0, y0);// (x2,y2)到点的距离
    if (c <= 0.000001 || b <= 0.000001) {
        space = 0;
        return space;
    }
    if (a <= 0.000001) {
        space = b;
        return space;
    }
    if (c * c >= a * a + b * b) {
        space = b;
        return space;
    }
    if (b * b >= a * a + c * c) {
        space = c;
        return space;
    }
    double p = (a + b + c) / 2;// 半周长
    double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积
    space = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)
    return space;
}

    // 计算两点之间的距离
    private static double lineSpace(double x1, double y1, double x2, double y2) {
        double lineLength = 0;
        lineLength = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2)
                * (y1 - y2));
        return lineLength;
    }
    public static double ESP = 0.001;

    public static boolean isChonghe(float a, float b,float c, float d){
        return ( a==c && b==d);
    }

    public static boolean islegal(float a, float c) {  //是否垂直与x
        // System.out.println("Slope does not exist");
        return !(Math.abs(a - c) < ESP);
    }

    public static float xielv(float a, float b, float c, float d) {  //计算斜率
        if (b == d) return 0;
        return (float)((float)(d - b) / (float)(c - a));
    }



    public static void getIntersectPoint(float a, float b,float c, float d,float aa, float bb,float cc, float dd){

        float A1=b-d;
        float B1=c-a;
        float C1=(float)A1*a+(float)B1*b;

        float A2=bb-dd;
        float B2=cc-aa;
        float C2=(float)A2*aa+B2*bb;

        float det_k=(float)A1*B2-A2*B1;


        float a1= (float)B2/det_k;
        float b1=(float)-1*B1/det_k;
        float c1=(float)-1*A2/det_k;
        float d1=(float)A1/det_k;

        float x=(float)a1*C1+b1*C2;
        float y=(float)c1*C1+d1*C2;
        if(x==0.0)x=Math.abs(x);
        if(y==0.0)y=Math.abs(y);
        System.out.print(x + "," + y);

        System.out.print(" ");
        if( (  ((x>a&&x<c) && (y>b&&y<d)) && ((x>aa&&x<cc) && (y>bb&&y<dd))  ) )System.out.print("true");

        else System.out.print("false");

    }
    public static void prtXunHuan(float a){
        if((a*1000 % 10) !=0)System.out.printf("%.6f",a);
        else System.out.print(a);
    }}
class A{
    public static double ESP = 0.001;

    public static boolean isChonghe(float a, float b,float c, float d){
        return ( a==c && b==d);
    }

    public static boolean islegal(float a, float c) {  //是否垂直与x
        // System.out.println("Slope does not exist");
        return !(Math.abs(a - c) < ESP);
    }

    public static float xielv(float a, float b, float c, float d) {  //计算斜率
        if (b == d) return 0;
        return (float)((float)(d - b) / (float)(c - a));
    }



    public static void getIntersectPoint(float a, float b,float c, float d,float aa, float bb,float cc, float dd){

        float A1=b-d;
        float B1=c-a;
        float C1=(float)A1*a+(float)B1*b;

        float A2=bb-dd;
        float B2=cc-aa;
        float C2=(float)A2*aa+B2*bb;

        float det_k=(float)A1*B2-A2*B1;


        float a1= (float)B2/det_k;
        float b1=(float)-1*B1/det_k;
        float c1=(float)-1*A2/det_k;
        float d1=(float)A1/det_k;

        float x=(float)a1*C1+b1*C2;
        float y=(float)c1*C1+d1*C2;
        if(x==0.0)x=Math.abs(x);
        if(y==0.0)y=Math.abs(y);
        System.out.print(x + "," + y);

        System.out.print(" ");
        if( (  ((x>a&&x<c) && (y>b&&y<d)) && ((x>aa&&x<cc) && (y>bb&&y<dd))  ) )System.out.print("true");

        else System.out.print("false");

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

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

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

    public UserRecords getUserRecords() {
        return userRecords;
    }

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

    public double getBalance() {
        return balance;
    }

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

    public ChargeMode getChargeMode() {
        return chargeMode;
    }

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

    public String getNumber() {
        return number;
    }

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

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 addCallingInCityRecord(CallRecord callRecord)
    {
        callingInCityRecords.add(callRecord);
    }
    public void addCallingInProvinceRecord(CallRecord callRecord)
    {
        callingInProvinceRecords.add(callRecord);
    }
    public void addCallingInLandRecord(CallRecord callRecord)
    {
        callingInLandRecords.add(callRecord);
    }
    public void answerInCityRecord(CallRecord callRecord)
    {
        answerInCityRecords.add(callRecord);
    }
    public void answerInProvinceRecord(CallRecord callRecord)
    {
        answerInProvinceRecords.add(callRecord);
    }
    public void answerInLandRecord(CallRecord callRecord)
    {
        answerInLandRecords.add(callRecord);
    }
    public void addSendMessageRecords(MessageRecord sendMessageRecord)
    {
        sendMessageRecords.add(sendMessageRecord);
    }
    public void addReceiveMessageRecords(MessageRecord receiveMessageRecord)
    {
        receiveMessageRecords.add(receiveMessageRecord);
    }
    public ArrayList<CallRecord> getCallingInCityRecords() {
        return callingInCityRecords;
    }

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

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

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

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

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

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

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

代码实现  根据所给类图进行类的编写 对输入的数据进行提取,调用类进行计算,运用正则表达式处理用户输入数据。

 

多态测试

定义容器Container接口。模拟实现一个容器类层次结构,并进行接口的实现、抽象方法重写和多态机制测试。各容器类实现求表面积、体积的方法。

  1. 定义接口Container:
    属性:
    public static final double pi=3.1415926;
    抽象方法:
    public abstract double area();
    public abstract double volume();
    static double sumofArea(Container c[]);
    static double sumofVolume(Container c[]);
    其中两个静态方法分别计算返回容器数组中所有对象的面积之和、周长之和;
  2. 定义Cube类、Cylinder类均实现自Container接口。
    Cube类(属性:边长double类型)、Cylinder类(属性:底圆半径、高,double类型)。

输入格式:

第一行n表示对象个数,对象类型用cube、cylinder区分,cube表示立方体对象,后面输入边长,输入cylinder表示圆柱体对象,后面是底圆半径、高。

输出格式:

分别输出所有容器对象的表面积之和、体积之和,结果保留小数点后2位。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String str = new String();
        
        int i = in.nextInt();
        Cube cu[] = new Cube[i];
        Cylinder cy[] = new Cylinder[i];
        int a = 0,b = 0;
        double S=0 , V=0 ;
        for (int j = 0; j < i; j++) {
            str = in.next();
            if (str.equalsIgnoreCase("cube")) {
                double y = in.nextDouble();
                cu[a] = new Cube(y);
                
                a++;
            }
            else if (str.equalsIgnoreCase("cylinder")) {
                double r = in.nextDouble();
                double h = in.nextDouble();
                cy[b] = new Cylinder(r,h);
                
                b++;
            }
        }
        S+=Container.sumofArea(cu) ;
        V+=Container.sumofVolume(cu) ;
        S+=Container.sumofArea(cy) ;
        V+=Container.sumofVolume(cy) ;
        System.out.println(String.format("%.2f",S));
        System.out.println(String.format("%.2f",V));

    }
}
    interface  Container{
        double pi=3.1415926;
    double area();
    double volume();
    static double sumofArea(Container c[]){
        double S = 0 ;
        int i = 0 ;
        while(c[i]!=null) {
            S+=c[i].area();
            i++;
        }
        return S ;
    }
    static double sumofVolume(Container c[]){
        double V = 0 ;
        int i = 0 ;
        while(c[i]!=null) {
            V+=c[i].volume();
            i++;
        }
        return V;
    }
}
 class Cube implements Container{
        double a ;

    public Cube(double a) {
        this.a = a;
    }

    public double area(){
            return 6*a*a;
        }

    @Override
    public double volume() {
        return a*a*a;
    }
}
class Cylinder implements Container{
        double r ;
        double h ;

    public Cylinder(double r ,double h) {
        this.r = r;
        this.h = h ;
    }

    public  double area(){
            return 2*pi*r*r+2*pi*r*h ;
        }

    @Override
    public double volume() {
        return pi*r*r*h;
    }
}

代码实现  运用接口调用多类提取数据进行运算。

电信计费系列2-手机+座机计费

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

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

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

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

 

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

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

image.png
图1

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

image.png

图2

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

image.png
图3

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

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

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



public class Main {
    static boolean checkString(String str) {
        //月份:((((20)\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\d|3[01]))|(((19|20)\d{2}).(0?[469]|11).(0?[1-9]|[12]\d|30))|(((19|20)\d{2}).0?2.(0?[1-9]|1\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]
        //座机打座机
        //座机打手机           t-0[0-9]{10,11} 1[0-9]{10} [0-9]{3,4}
        if(str.matches("t-0[0-9]{10,11} 0[0-9]{9,11} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]"))
            return true;
        else
        if(str.matches("t-0[0-9]{10,11} 1[0-9]{10} [0-9]{3,4} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]"))
            return true;
        else if(str.matches("t-1[0-9]{10} [0-9]{3,4} 0[0-9]{9,11} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]"))
            return true;
        else if(str.matches("t-1[0-9]{10} [0-9]{3,4} 1[0-9]{10} [0-9]{3,4} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]"))
            return  true;
        //手机打座机
        //手机打手机
        //if(str.matches())
        else
        return false;
    }

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

    public static boolean checkillegal(String[] s) {
        for (int i = 0; i <= 1; i++) {
            if (s[i].length() < 7) return true;
            for (int j = 0; j < s[i].length(); i++) {
                if (s[i].charAt(j) < '0' || s[i].charAt(j) > '9') return true;
            }
        }
        return false;
    }

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

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        ArrayList<User> users = new ArrayList<>();
        String [] s = new String[100];
        int i = 0;
        while(true)
        {
            s[i] = in.nextLine();
            if(s[i].equals("end"))break;
            i ++;
        }
        for(int j = 0;j < i;j ++)
        {
            if(s[j].charAt(0) == 'u')
            {
                if (s[j].equals("")) continue;
                if (checkFirst(s[j]) == false) continue;
                String[] ss = s[j].split(" ");
                String phoneNumber = ss[0].substring(2);
                boolean f = false;
                for (User user : users)
                    if (user.getNumber().equals(phoneNumber)) {
                        f = true;
                        break;
                    }
                if (f) continue;
                User user = new User(phoneNumber);
                if (s[j].charAt(s[j].length() - 1) == '0')user.setChargeMode(new LandlinePhoneCharging());
                else user.setChargeMode(new MobilePhoneCharging());
                users.add(user);
            }
        }
        for(int j = 0;j < i;j ++)
        {
            if(s[j].equals(""))continue;
            if(s[j].charAt(0) == 't')
            {
                if (checkString(s[j]) == true) {
                    s[j] = s[j].substring(2);
                    String[] ss = s[j].split(" ");
                    String startTime;
                    String endTime;
                    Date StartTime = null, EndTime = null;
                    boolean haveEfficient = false;
                    for (User user : users) {
                        if (user.getNumber().equals(ss[0])) {
                            haveEfficient = true;
                            if (ss.length == 6) {
                                String call = ss[0].substring(0, 4);
                                String receive = ss[1].substring(0, 4);
                                startTime = ss[2] + " " + ss[3];
                                endTime = ss[4] + " " + ss[5];
                                //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                                try {
                                    StartTime = dateFormat.parse(startTime);
                                } catch (ParseException e) {
                                    continue;
                                }
                                try {
                                    EndTime = dateFormat.parse(endTime);
                                } catch (ParseException e) {
                                    continue;
                                }
                                if (checkCode(receive) == 1) {String n = in.next();float num = in.nextInt();
                                float a = in.nextInt(),b = in.nextInt();
                                int c = in.nextInt(),d = in.nextInt();
                                c = in.nextInt();d = in.nextInt();
                                c = in.nextInt();d = in.nextInt();
                                System.out.printf("中国银行欢迎您的到来!\n" +
                                        "您的余额有%.1f元。\n" +
                                        "您的密码错误!\n" +
                                        "您的余额不足!\n" +
                                        "请取走钞票,您的余额还有%.1f元。\n" +
                                        "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);} else if (checkCode(receive) == 2)
                                    user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime, call, receive));
                                else
                                {
                                    float a = in.nextInt(),b = in.nextInt();
                                    int c = in.nextInt(),d = in.nextInt();
                                    c = in.nextInt();d = in.nextInt();
                                    c = in.nextInt();d = in.nextInt();
                                    System.out.printf("中国银行欢迎您的到来!\n" +
                                            "您的余额有%.1f元。\n" +
                                            "您的密码错误!\n" +
                                            "您的余额不足!\n" +
                                            "请取走钞票,您的余额还有%.1f元。\n" +
                                            "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);}
                            }else if(ss.length == 8)
                            {
                                String call = ss[1];
                                String receive = ss[3];
                                startTime = ss[4] + " " + ss[5];
                                endTime = ss[6] + " " + ss[7];
                                //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                                try {
                                    StartTime = dateFormat.parse(startTime);
                                } catch (ParseException e) {
                                    continue;
                                }
                                try {
                                    EndTime = dateFormat.parse(endTime);
                                } catch (ParseException e) {
                                    continue;
                                }
                                if(checkCode(call) == 1 && checkCode(receive) == 1)
                                {String n = in.next();float num = in.nextInt();
                                float a = in.nextInt(),b = in.nextInt();
                                int c = in.nextInt(),d = in.nextInt();
                                c = in.nextInt();d = in.nextInt();
                                c = in.nextInt();d = in.nextInt();
                                System.out.printf("中国银行欢迎您的到来!\n" +
                                        "您的余额有%.1f元。\n" +
                                        "您的密码错误!\n" +
                                        "您的余额不足!\n" +
                                        "请取走钞票,您的余额还有%.1f元。\n" +
                                        "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);}else if(checkCode(call) == 1 && checkCode(receive) == 2) {String n = in.next();float num = in.nextInt();
                                        float a = in.nextInt(),b = in.nextInt();
                                        int c = in.nextInt(),d = in.nextInt();
                                        c = in.nextInt();d = in.nextInt();
                                        c = in.nextInt();d = in.nextInt();
                                        System.out.printf("中国银行欢迎您的到来!\n" +
                                                "您的余额有%.1f元。\n" +
                                                "您的密码错误!\n" +
                                                "您的余额不足!\n" +
                                                "请取走钞票,您的余额还有%.1f元。\n" +
                                                "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);}else if(checkCode(call) == 1 && checkCode(receive) == 3){
                                    user.getUserRecords().getMobilePhoneCityCallLand().add(new CallRecord(StartTime, EndTime, call, receive));
                                    ///判断接听电话的有没有开户
                                    for(User user1 : users)
                                    {
                                        if(user1.getNumber().equals(ss[2]) == true)
                                        {
                                            user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                            break;
                                        }
                                    }
                                }else if(checkCode(call) == 2){
                                    user.getUserRecords().getMobilePhoneProvincialRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive));
                                    if(checkCode(receive) == 3)
                                    {
                                        for(User user1 : users)
                                        {
                                            if(user1.getNumber().equals(ss[2]) == true)
                                            {
                                                user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                                break;
                                            }
                                        }
                                    }
                                }else if(checkCode(call) == 3){
                                    user.getUserRecords().getMobilePhoneDomesticRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive));
                                    if(checkCode(receive) == 3)
                                    {
                                        for(User user1 : users)
                                        {
                                            if(user1.getNumber().equals(ss[2]) == true)
                                            {
                                                user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                                break;
                                            }
                                        }
                                    }
                                }
                            }else if(ss.length == 7)
                            {
                                if(ss[0].charAt(0) == '1')//手机打座机
                                {String n = in.next();float num = in.nextInt();
                                float a = in.nextInt(),b = in.nextInt();
                                int c = in.nextInt(),d = in.nextInt();
                                c = in.nextInt();d = in.nextInt();
                                c = in.nextInt();d = in.nextInt();
                                System.out.printf("中国银行欢迎您的到来!\n" +
                                        "您的余额有%.1f元。\n" +
                                        "您的密码错误!\n" +
                                        "您的余额不足!\n" +
                                        "请取走钞票,您的余额还有%.1f元。\n" +
                                        "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);}else//座机打手机
                                {
                                    String call = ss[0].substring(0, 4);
                                    String receive = ss[2];
                                    startTime = ss[3] + " " + ss[4];
                                    endTime = ss[5] + " " + ss[6];
                                    //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                                    try {
                                        StartTime = dateFormat.parse(startTime);
                                    } catch (ParseException e) {
                                        continue;
                                    }
                                    try {
                                        EndTime = dateFormat.parse(endTime);
                                    } catch (ParseException e) {
                                        continue;
                                    }
                                    if(checkCode(receive) == 1)
                                    {
                                        user.getUserRecords().getCallingInCityRecords().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }else if(checkCode(receive) == 2)
                                    {
                                        user.getUserRecords().getCallingInProvinceRecord().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                                    else if (checkCode(receive) == 3) {
                                        user.getUserRecords().getCallingInLandRecord().add(new CallRecord(StartTime, EndTime, call, receive));
                                        for(User user1 : users)
                                            if(user1.getNumber().equals(ss[1]) == true) {
                                                user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                                break;
                                            }
                                    }
                                }
                            }
                        }
                    }
                    if(haveEfficient == false)
                    {
                        if(ss.length == 8) {String n = in.next();float num = in.nextInt();
                        float a = in.nextInt(),b = in.nextInt();
                        int c = in.nextInt(),d = in.nextInt();
                        c = in.nextInt();d = in.nextInt();
                        c = in.nextInt();d = in.nextInt();
                        System.out.printf("中国银行欢迎您的到来!\n" +
                                "您的余额有%.1f元。\n" +
                                "您的密码错误!\n" +
                                "您的余额不足!\n" +
                                "请取走钞票,您的余额还有%.1f元。\n" +
                                "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);}else if(ss.length == 7 && ss[0].charAt(0) == '0')
                        {
                            String call = ss[0].substring(0,4);
                            String receive = ss[2];
                            startTime = ss[3] + " " + ss[4];
                            endTime = ss[5] + " " + ss[6];
                            try {
                                StartTime = dateFormat.parse(startTime);
                            } catch (ParseException e) {
                                // continue;
                            }
                            try {
                                EndTime = dateFormat.parse(endTime);
                            } catch (ParseException e) {
                                // continue;
                            }
                            //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode
                            ///判断接听电话的有没有开户
                            for(User user : users)
                                if(user.getNumber().equals(ss[1]))
                                    if (checkCode(receive) == 3) {
                                        user.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive));
                                    }
                        }
                    }
                }
            }
        }
        //座机打座机 座机打手机 手机打座机 手机打手机
        TreeMap<String, User> treeMap = new TreeMap<>();
        for (User user : users) {
            treeMap.put(user.getNumber(), user);
        }
        Iterator<User> t = treeMap.values().iterator();
        while (t.hasNext()) {
            User user = t.next();
            System.out.println(user.number + " " + user.calCost() + " " + user.calBalance());
        }
    }
    private static  double pointToLine(double x1, double y1, double x2, double y2, double x0,
               double y0) {
            double space = 0;
            double a, b, c;
            a = lineSpace(x1, y1, x2, y2);// 线段的长度
            b = lineSpace(x1, y1, x0, y0);// (x1,y1)到点的距离
            c = lineSpace(x2, y2, x0, y0);// (x2,y2)到点的距离
            if (c <= 0.000001 || b <= 0.000001) {
               space = 0;
               return space;
            }
            if (a <= 0.000001) {
               space = b;
               return space;
            }
            if (c * c >= a * a + b * b) {
               space = b;
               return space;
            }
            if (b * b >= a * a + c * c) {
               space = c;
               return space;
            }
            double p = (a + b + c) / 2;// 半周长
            double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积
            space = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)
            return space;
        }
         
        // 计算两点之间的距离
        private static double lineSpace(double x1, double y1, double x2, double y2) {
            double lineLength = 0;
            lineLength = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2)
                   * (y1 - y2));
            return lineLength;
        }
 public static double ESP = 0.001;

 public static boolean isChonghe(float a, float b,float c, float d){
     return ( a==c && b==d);
 }

 public static boolean islegal(float a, float c) {  //是否垂直与x
     // System.out.println("Slope does not exist");
     return !(Math.abs(a - c) < ESP);
 }

 public static float xielv(float a, float b, float c, float d) {  //计算斜率
     if (b == d) return 0;
     return (float)((float)(d - b) / (float)(c - a));
 }

 

 public static void getIntersectPoint(float a, float b,float c, float d,float aa, float bb,float cc, float dd){

     float A1=b-d;
     float B1=c-a;
     float C1=(float)A1*a+(float)B1*b;

     float A2=bb-dd;
     float B2=cc-aa;
     float C2=(float)A2*aa+B2*bb;

     float det_k=(float)A1*B2-A2*B1;


     float a1= (float)B2/det_k;
     float b1=(float)-1*B1/det_k;
     float c1=(float)-1*A2/det_k;
     float d1=(float)A1/det_k;

     float x=(float)a1*C1+b1*C2;
     float y=(float)c1*C1+d1*C2;
     if(x==0.0)x=Math.abs(x);
     if(y==0.0)y=Math.abs(y);
     System.out.print(x + "," + y);

     System.out.print(" ");
     if( (  ((x>a&&x<c) && (y>b&&y<d)) && ((x>aa&&x<cc) && (y>bb&&y<dd))  ) )System.out.print("true");

     else System.out.print("false");
     
 }
 public static void prtXunHuan(float a){
     if((a*1000 % 10) !=0)System.out.printf("%.6f",a);
     else System.out.print(a);
 }
    public abstract static class ChargeRule {
        abstract double calCost(ArrayList<CallRecord> callRecords);
    }

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

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

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

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

    public static class MessageRecord extends CommunicationRecord {
        String message ;
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    }

    public static class LandlinePhoneCharging extends ChargeMode {
        double monthlyRent = 20;
        public LandlinePhoneCharging()
        {
            getChargeRules().add(new LandPhoneCityRule());
            getChargeRules().add(new LandPhoneLandRule());
            getChargeRules().add(new LandPhoneProvinceRule());
        }
    
        @Override
        double calCost(UserRecords userRecords) {
            double cost = 0;
            cost = getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) +
                    getChargeRules().get(1).calCost(userRecords.getCallingInLandRecord()) +
                    getChargeRules().get(2).calCost(userRecords.getCallingInProvinceRecord());
            return cost;
        }
    
        @Override
        public double getMonthlyRent() {
            return monthlyRent;
        }
    }

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

    public static class CommunicationRecord {
        String callingNumber;
        String answerNumber;
    
        public String getCallingNumber() {
            return callingNumber;
        }
    
        public void setCallingNumber(String callingNumber) {
            this.callingNumber = callingNumber;
        }
    
        public String getAnswerNumber() {
            return answerNumber;
        }
    
        public void setAnswerNumber(String answerNumber) {
            this.answerNumber = answerNumber;
        }
    }

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

    public static class User {
        UserRecords userRecords = new UserRecords();
        double balance = 100;
        ChargeMode chargeMode;
        String number;
    
        public User(String number) {
            this.number = number;
        }
    
        double calBalance()
        {
            return getBalance() - calCost() - chargeMode.getMonthlyRent();
        }
        double calCost(){
            return chargeMode.calCost(userRecords);
        }
    
        public UserRecords getUserRecords() {
            return userRecords;
        }
    
        public void setUserRecords(UserRecords userRecords) {
            this.userRecords = userRecords;
        }
    
        public double getBalance() {
            return balance;
        }
    
        public void setBalance(double balance) {
            this.balance = balance;
        }
    
        public ChargeMode getChargeMode() {
            return chargeMode;
        }
    
        public void setChargeMode(ChargeMode chargeMode) {
            this.chargeMode = chargeMode;
        }
    
        public String getNumber() {
            return number;
        }
    
        public void setNumber(String number) {
            this.number = number;
        }
    }

    public static class CallRecord extends CommunicationRecord {
        Date startTime;
        Date endTime;
        String callingAddressAreaCode;
        String answerAddressAreaCode;
    
        public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
            this.startTime = startTime;
            this.endTime = endTime;
            this.callingAddressAreaCode = callingAddressAreaCode;
            this.answerAddressAreaCode = answerAddressAreaCode;
        }
    
        public Date getStartTime() {
            return startTime;
        }
    
        public void setStartTime(Date startTime) {
            this.startTime = startTime;
        }
    
        public Date getEndTime() {
            return endTime;
        }
    
        public void setEndTime(Date endTime) {
            this.endTime = endTime;
        }
    
        public String getCallingAddressAreaCode() {
            return callingAddressAreaCode;
        }
    
        public void setCallingAddressAreaCode(String callingAddressAreaCode) {
            this.callingAddressAreaCode = callingAddressAreaCode;
        }
    
        public String getAnswerAddressAreaCode() {
            return answerAddressAreaCode;
        }
    
        public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
            this.answerAddressAreaCode = answerAddressAreaCode;
        }
    }

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

    public static class UserRecords {
        ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord>callingInLandRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord>answerInCityRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord>answerInProvinceRecords = new ArrayList<CallRecord>();
        ArrayList<CallRecord>answerInLandRecords = new ArrayList<CallRecord>();
        ArrayList<MessageRecord>sendMessageRecords = new ArrayList<MessageRecord>();
        ArrayList<MessageRecord>receiveMessageRecords = new ArrayList<MessageRecord>();
        ArrayList<CallRecord> mobilePhoneCityCallCity = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneCityCallProvince = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneCityCallLand = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneDomesticRoamingCall = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneProvincialRoamingCall = new ArrayList<CallRecord>();
        ArrayList<CallRecord> mobilePhoneRoamingAnsweringOutsideProvince = new ArrayList<CallRecord>();
        public void addMobilePhoneCityCallCity(CallRecord callRecord){mobilePhoneCityCallCity.add(callRecord);};
        public void addMobilePhoneCityCallProvince(CallRecord callRecord){mobilePhoneCityCallProvince.add(callRecord);};
        public void addMobilePhoneCityCallLand(CallRecord callRecord){mobilePhoneCityCallLand.add(callRecord);};
        public void addMobilePhoneDomesticRoamingCall(CallRecord callRecord){mobilePhoneDomesticRoamingCall.add(callRecord);};
        public void addMobilePhoneProvincialRoamingCall(CallRecord callRecord){mobilePhoneProvincialRoamingCall.add(callRecord);};
        public void addMobilePhoneRoamingAnsweringOutsideProvince(CallRecord callRecord){mobilePhoneRoamingAnsweringOutsideProvince.add(callRecord);};
        public void addCallingInCityRecord(CallRecord callRecord)
        {
            callingInCityRecords.add(callRecord);
        }
        public void addCallingInProvinceRecord(CallRecord callRecord)
        {
            callingInProvinceRecords.add(callRecord);
        }
        public void addCallingInLandRecord(CallRecord callRecord)
        {
            callingInLandRecords.add(callRecord);
        }
        public void answerInCityRecord(CallRecord callRecord)
        {
            answerInCityRecords.add(callRecord);
        }
        public void answerInProvinceRecord(CallRecord callRecord)
        {
            answerInProvinceRecords.add(callRecord);
        }
        public void answerInLandRecord(CallRecord callRecord)
        {
            answerInLandRecords.add(callRecord);
        }
        public void addSendMessageRecords(MessageRecord sendMessageRecord)
        {
            sendMessageRecords.add(sendMessageRecord);
        }
        public void addReceiveMessageRecords(MessageRecord receiveMessageRecord)
        {
            receiveMessageRecords.add(receiveMessageRecord);
        }
    
        public ArrayList<CallRecord> getMobilePhoneCityCallCity() {
            return mobilePhoneCityCallCity;
        }
    
        public ArrayList<CallRecord> getMobilePhoneCityCallProvince() {
            return mobilePhoneCityCallProvince;
        }
    
        public ArrayList<CallRecord> getMobilePhoneCityCallLand() {
            return mobilePhoneCityCallLand;
        }
    
        public ArrayList<CallRecord> getMobilePhoneDomesticRoamingCall() {
            return mobilePhoneDomesticRoamingCall;
        }
    
        public ArrayList<CallRecord> getMobilePhoneProvincialRoamingCall() {
            return mobilePhoneProvincialRoamingCall;
        }
    
        public ArrayList<CallRecord> getMobilePhoneRoamingAnsweringOutsideProvince() {
            return mobilePhoneRoamingAnsweringOutsideProvince;
        }
    
        public ArrayList<CallRecord> getCallingInCityRecords() {
            return callingInCityRecords;
        }
    
        public ArrayList<CallRecord> getCallingInProvinceRecord() {
            return callingInProvinceRecords;
        }
    
        public ArrayList<CallRecord> getCallingInLandRecord() {
            return callingInLandRecords;
        }
    
        public ArrayList<CallRecord> getAnswerInCityRecords() {
            return answerInCityRecords;
        }
    
        public ArrayList<CallRecord> getAnswerInProvinceRecords() {
            return answerInProvinceRecords;
        }
    
        public ArrayList<CallRecord> getAnswerInLandRecords() {
            return answerInLandRecords;
        }
    
        public ArrayList<MessageRecord> getSendMessageRecord() {
            return sendMessageRecords;
        }
    
        public ArrayList<MessageRecord> getReceiveMessageRecord() {
            return receiveMessageRecords;
        }
    }

    public abstract static class ChargeMode {
        ArrayList<ChargeRule> chargeRules = new ArrayList<>();
    
        public ArrayList<ChargeRule> getChargeRules() {
            return chargeRules;
        }
    
        public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
            this.chargeRules = chargeRules;
        }
        abstract double calCost(UserRecords userRecords);
    
        abstract double getMonthlyRent();
    }

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

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

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

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

运用正则表达式提取用户输入数据 。通过类储存用户信息。在调用uesr类进行多种运算

总结 本阶段学会运用父类继承。收悉类与类之间的关系。写代码熟练进行多种类结合调用。类的分类运用,合理进行代码框架的设计。编写代码熟练度提高。编译代码能力改善。

posted @ 2022-06-10 14:18  21201509-黄添  阅读(46)  评论(0)    收藏  举报