前言

最近作业不多,只有三次pta,主要就是座机的迭代和一些比较简单的附加题,主要考察对于继承与多态、封装、正则表达式、和类设计。

同时,这几次作业相比前几个星期的难度提升很大,需要投入更多的时间。

设计与分析

电信计费第一次作业

题目描述如下:

 

类图如下:

 

源码如下:

 

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

public class Main {
    public static void main(String[] args) throws ParseException{
        Control control = new Control();
        control.start();
    }
}

abstract class CallChargeRule extends ChargeRule{

    public abstract double calCost (ArrayList<CallRecord> callRecords);

}

class CallRecord extends CommunicationRecord{
    private Date startTime;
    private Date endTime;
    private String callingAddressAreaCode;
    private 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 {
    private ArrayList<ChargeRule> chargeRules = new ArrayList<>();


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

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

    public  abstract double calCost(UserRecords userRecords);

    public abstract double getMonthlyRent();
}

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

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

    public String getCallingNumber() {
        return callingNumber;
    }

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

    public String getAnswerNumber() {
        return answerNumber;
    }

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

class Control {
    Scanner in = new Scanner(System.in);
    private ArrayList<User> users = new ArrayList<>();
    ArrayList<String> areaNums = new ArrayList<>();

    public  Control(){
        areaNums.add("0790");
        areaNums.add("0791");
        areaNums.add("0792");
        areaNums.add("0793");
        areaNums.add("0794");
        areaNums.add("0795");
        areaNums.add("0796");
        areaNums.add("0797");
        areaNums.add("0798");
        areaNums.add("0799");
        areaNums.add("0701");
    }


    public void classify() throws ParseException {
        String line;
        String type1 = "u-0791\\d{7,8}\\s[0-2]";
        String part1 = "t-0791[0-9]{7,8}\\s0[0-9]{9,11}\\s";
        String part2 = "(((\\d{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?";
        String part3 = "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|1\\d|2[0-8]))))|(((";
        String part4 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))";
        String part5 = "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5][0-9])\\s";
        String part6 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9]\\d|[0-9][1-9][0-9]{2}|[1-9]\\d{3})\\.((([13578]|1[02])\\.(";
        String part7 = "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((";
        String part8 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))";
        String part9 = "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])";
        String type2 = part1 + part2 + part3+ part4+ part5+ part6+ part7+ part8+ part9;
        do{
            line = in.nextLine();
            if(line.matches(type1)){
                boolean flag = true;
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                User user = new User();
                for(User i:users){
                    if(i.getNumber().equals(b[0])){
                        flag = false;
                    }
                }
                if(flag){
                    user.setNumber(b[0]);
                    user.setChargeMode(new LandlinePhoneCharging());
                    users.add(user);
                }
            } else if (line.matches(type2)) {
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                for(int i = 0;i<users.size();i++){
                    if(users.get(i).getNumber().equals(b[0])){
                        String callingAddressAreaCode="";
                        String answerAddressAreaCode="";
                        for(int j = 0;j<4;j++){
                            callingAddressAreaCode += b[0].charAt(j);
                        }
                        for(int j = 0;j<4;j++){
                            answerAddressAreaCode += b[1].charAt(j);
                        }
                        if(callingAddressAreaCode.equals(answerAddressAreaCode)){
                            users.get(i).getUserRecords().addAnswerInCityRecords(getCallRecord(b));
                        } else if (areaNums.contains(callingAddressAreaCode)&&areaNums.contains(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addAnswerInProvinceRecords(getCallRecord(b));
                        }else{
                            users.get(i).getUserRecords().addAnswerInLandRecords(getCallRecord(b));
                        }

                    }
                }
            }
        }while(!line.equals("end"));

    }

    public CallRecord getCallRecord(String s[]) throws ParseException {
        String callingAddressAreaCode="";
        String answerAddressAreaCode="";
        for(int i = 0;i<4;i++){
            callingAddressAreaCode += s[0].charAt(i);
        }
        for(int i = 0;i<4;i++){
            answerAddressAreaCode += s[1].charAt(i);
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        Date startTime = simpleDateFormat.parse(s[2]+" "+s[3]);
        Date endTime = simpleDateFormat.parse(s[4]+" "+s[5]);
        return  new CallRecord(startTime,endTime,callingAddressAreaCode,answerAddressAreaCode);
    }

    public void start() throws ParseException {
        classify();
        for(int i=0;i<users.size()-1;i++) {
            for(int j=0;j<users.size()-1-i;j++) {
                if(users.get(j).getNumber().compareTo(users.get(j+1).getNumber()) > 0) {
                    User temp=users.get(j);
                    users.set(j,users.get(j+1));
                    users.set(j+1,temp);
                }
            }
        }
        for(User i:users){
            System.out.printf("%s %.1f %.1f\n",i.getNumber(),i.calCost(),i.calBanlance());
        }
    }
}

class LandlinePhoneCharging extends ChargeMode{//座机收费
    public LandlinePhoneCharging(){
        super();
        super.getChargeRules().add(new LandPhoneInCityRule());
        super.getChargeRules().add(new LandPhoneInProvinceRule());
        super.getChargeRules().add(new LandPhoneInlandRule());
    }
    @Override
    public  double calCost(UserRecords userRecords){
        return super.getChargeRules().get(0).calCost(userRecords.getAnswerInCityRecords())
                + super.getChargeRules().get(1).calCost(userRecords.getAnswerInProvinceRecords())
                + super.getChargeRules().get(2).calCost(userRecords.getAnswerInLandRecords());
    }

    @Override
    public  double getMonthlyRent (){
        return  20;
    }
}

class LandPhoneInCityRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            if(n==0){
                cost+=0.1;
            }
            if(remainder==0){
                cost+=n*0.1;
            }else{
                cost += (n+1)*0.1;
            }
        }
        return cost;
    }
}

class LandPhoneInlandRule extends CallChargeRule {
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost = 0;
        for (CallRecord i : callRecords) {
            long remainder = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 % 60;
            long n = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 / 60;
            if (n == 0) {
                cost += 0.6;
            }
            if (remainder == 0) {
                cost += n * 0.6;
            } else {
                cost += (n + 1) * 0.6;
            }
        }
        return cost;
    }
}

class LandPhoneInProvinceRule extends CallChargeRule {
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            if(n==0){
                cost+=0.3;
            }
            if(remainder==0){
                cost+=n*0.3;
            }else{
                cost += (n+1)*0.3;
            }
        }
        return cost;
    }
}

class MessageRecord {
    private String message;

    public String getMessage() {
        return message;
    }

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

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

    public User() {
    }

    public double calBanlance(){
        return balance - calCost() - chargeMode.getMonthlyRent();
    }

    public 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 {
    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 answerRecord){
        answerInCityRecords.add(answerRecord);
    }

    public void addAnswerInProvinceRecords (CallRecord answerRecord){
        answerInProvinceRecords.add(answerRecord);
    }

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

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

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

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

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

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

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

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

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

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

    public ArrayList<MessageRecord> getReceiveMessageRecords() {
        return receiveMessageRecords;
    }
}
电信计费第一次作业

 

 

分析如下:

  本题难度不大,但需要耐心去参考题目所给类图和题意。比如说此处针对的是对于南昌市的座机进行开号,所以开户信息区号的正则只需要用“0791”即可,而不需要再判定其他区号。                 

对于非法输入,时间的合法性是做本题的关键。因为这要涉及到年月日的问题,比如说2月在平年只有28天,所以如果出现2月29日则是非法的。同时,除了二月外的每个月都有固定的天数,超过相应的天数,也是非法的。对于输出需要注意的是保留两位小数和需要排序后在输出。保留两位小数可以先用DecimalFormat,然后再输出,也可以直接在printf中用%.2f,此处我用的是后者。而对于排序,比较用compare to,因为此处是字符串,而遍历可以用for(int i; i < list.size(); i++),也可以用for(Object i:list),我倾向于后者因为更加简便。

 

电信计费第二次作业

题目描述如下: 

 

 

类图如下: 

 

 

 

 

 

源码如下:

 

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

public class Main {
    public static void main(String[] args) throws ParseException{
        Control control = new Control();
        control.start();
    }
}

class Control {
    Scanner in = new Scanner(System.in);
    private ArrayList<User> users = new ArrayList<>();

    public  Control(){
    }

    public void classify() throws ParseException {
        String line;
        String LandPhone = "0\\d{2,3}[0-9]{7,8}\\s";
        String MobilePhone = "1\\d{10}\\s0\\d{2,3}\\s";

        String part1 = "(((\\d{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?";
        String part2 = "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|1\\d|2[0-8]))))|(((";
        String part3 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))";
        String part4 = "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5][0-9])\\s";
        String part5 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9]\\d|[0-9][1-9][0-9]{2}|[1-9]\\d{3})\\.((([13578]|1[02])\\.(";
        String part6 = "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((";
        String part7 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))";
        String part8 = "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])";

        String time = part1 + part2 + part3+ part4+ part5+ part6+ part7+ part8;
        do{
            line = in.nextLine();
            if(line.matches("u-0791[0-9]{7,8}\\s0")){
                boolean flag = true;
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                User user = new User();
                for(User i:users){
                    if(i.getNumber().equals(b[0])){
                        flag = false;
                        break;
                    }
                }
                if(flag){
                    user.setNumber(b[0]);
                    user.setChargeMode(new LandlinePhoneCharging());
                    users.add(user);
                }
            } else if(line.matches("u-1\\d{10}\\s1")){
                boolean flag = true;
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                User user = new User();
                for(User i:users){
                    if(i.getNumber().equals(b[0])){
                        flag = false;
                    }
                }
                if(flag){
                    user.setNumber(b[0]);
                    user.setChargeMode(new MobilePhoneCharging());
                    users.add(user);
                }
            } else if (line.matches("t-"+LandPhone+LandPhone+time)) {//座机打座机
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                String c[] = a[1].split(LandPhone+LandPhone);
                String d[] = c[1].split("\\s");
                for(int i = 0;i<users.size();i++){
                    if(users.get(i).getNumber().equals(b[0])){
                        String callingAddressAreaCode="";
                        String answerAddressAreaCode="";
                        for(int j = 0;j<4;j++){
                            callingAddressAreaCode += b[0].charAt(j);
                        }
                        for(int j = 0;j<4;j++){
                            answerAddressAreaCode += b[1].charAt(j);
                        }
                        //座机拨打
                        if(callingAddressAreaCode.equals(answerAddressAreaCode)){
                            users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        } else if (AreaNums.get().contains(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }else{
                            users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }

                    }
                }
            } else if (line.matches("t-"+LandPhone+MobilePhone+time)) {//座机打手机
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                String c[] = a[1].split(LandPhone+MobilePhone);
                String d[] = c[1].split("\\s");
                String callingAddressAreaCode="";
                String answerAddressAreaCode=b[2];
                for(int j = 0;j<4;j++){
                    callingAddressAreaCode += b[0].charAt(j);
                }
                //记录手机省外接听
                for(int k = 0;k<users.size();k++){
                    if(users.get(k).getNumber().equals(b[1])){
                        if(!AreaNums.get().contains(answerAddressAreaCode)){
                            users.get(k).getUserRecords().addAnswerInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                        break;
                    }
                }
                for(int i = 0;i<users.size();i++){
                    if(users.get(i).getNumber().equals(b[0])){
                        //记录座机拨打
                        if(callingAddressAreaCode.equals(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        } else if (AreaNums.get().contains(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }else{
                            users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                    }
                }
            } else if (line.matches("t-"+MobilePhone+LandPhone+time)) {//手机打座机
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                String c[] = a[1].split(MobilePhone+LandPhone);
                String d[] = c[1].split("\\s");
                String callingAddressAreaCode=b[1];
                String answerAddressAreaCode = "";
                for(int j = 0;j<4;j++){
                    answerAddressAreaCode += b[2].charAt(j);
                }
                for(int i = 0;i<users.size();i++){
                    if(users.get(i).getNumber().equals(b[0])){
                        //记录手机拨打
                        if(callingAddressAreaCode.equals(answerAddressAreaCode)){
                            users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        } else if (AreaNums.get().contains(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }else{
                            users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                    }
                }
            } else if (line.matches("t-"+MobilePhone+MobilePhone+time)) {//手机打手机
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                String c[] = a[1].split(MobilePhone+MobilePhone);
                String d[] = c[1].split("\\s");
                String callingAddressAreaCode=b[1];
                String answerAddressAreaCode=b[3];
                //记录手机省外接听
                for(int k = 0;k<users.size();k++){
                    if(users.get(k).getNumber().equals(b[2])){
                        if(!AreaNums.get().contains(answerAddressAreaCode)){
                            users.get(k).getUserRecords().addAnswerInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                        break;
                    }
                }
                for(int i = 0;i<users.size();i++){
                    if(users.get(i).getNumber().equals(b[0])){
                        //记录手机拨打
                        if(callingAddressAreaCode.equals(answerAddressAreaCode)){
                            users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        } else if (AreaNums.get().contains(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }else{
                            users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                    }
                }
            }
        }while(!line.equals("end"));
    }

    public CallRecord getCallRecord(String callingAddressAreaCode,String answerAddressAreaCode,String d[]) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        Date startTime = simpleDateFormat.parse(d[0]+" "+d[1]);
        Date endTime = simpleDateFormat.parse(d[2]+" "+d[3]);
        return  new CallRecord(startTime,endTime,callingAddressAreaCode,answerAddressAreaCode);
    }

    public void start() throws ParseException {
        classify();
        for(int i=0;i<users.size()-1;i++) {
            for(int j=0;j<users.size()-1-i;j++) {
                if(users.get(j).getNumber().compareTo(users.get(j+1).getNumber()) > 0) {
                    User temp=users.get(j);
                    users.set(j,users.get(j+1));
                    users.set(j+1,temp);
                }
            }
        }
        for(User i:users){
            System.out.printf("%s %.1f %.1f\n",i.getNumber(),i.calCost(),i.calBanlance());
        }
    }
}

class AnswerChargeRule extends ChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            if(n==0){
                cost+=0.3;
            }
            if(remainder==0){
                cost+=n*0.3;
            }else{
                cost += (n+1)*0.3;
            }
        }
        return cost;
    }
}

class AreaNums {
    static ArrayList<String> areaNums = new ArrayList<>();
    public AreaNums(){
    }

    public static ArrayList get(){
        areaNums.add("0790");
        areaNums.add("0791");
        areaNums.add("0792");
        areaNums.add("0793");
        areaNums.add("0794");
        areaNums.add("0795");
        areaNums.add("0796");
        areaNums.add("0797");
        areaNums.add("0798");
        areaNums.add("0799");
        areaNums.add("0701");
        return areaNums;
    }
}

abstract class CallChargeRule extends ChargeRule{

    public abstract double calCost (ArrayList<CallRecord> callRecords);

}

class CallRecord extends CommunicationRecord{
    private Date startTime;
    private Date endTime;
    private String callingAddressAreaCode;
    private 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 {
    private ArrayList<ChargeRule> chargeRules = new ArrayList<>();


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

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

    public  abstract double calCost(UserRecords userRecords);

    public abstract double getMonthlyRent();
}

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

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

    public String getCallingNumber() {
        return callingNumber;
    }

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

    public String getAnswerNumber() {
        return answerNumber;
    }

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

class LandlinePhoneCharging extends ChargeMode{//座机收费
    public LandlinePhoneCharging(){
        super();
        super.getChargeRules().add(new LandPhoneInCityRule());
        super.getChargeRules().add(new LandPhoneInProvinceRule());
        super.getChargeRules().add(new LandPhoneInLandRule());
    }
    @Override
    public  double calCost(UserRecords userRecords){
        return super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords())
                + super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords())
                + super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords());
    }

    @Override
    public  double getMonthlyRent (){
        return  20;
    }
}

class LandPhoneInCityRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            if(n==0){
                cost+=0.1;
            }
            if(remainder==0){
                cost+=n*0.1;
            }else{
                cost += (n+1)*0.1;
            }
        }
        return cost;
    }
}

class LandPhoneInLandRule extends CallChargeRule {
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost = 0;
        for (CallRecord i : callRecords) {
            long remainder = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 % 60;
            long n = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 / 60;
            if (n == 0) {
                cost += 0.6;
            }
            if (remainder == 0) {
                cost += n * 0.6;
            } else {
                cost += (n + 1) * 0.6;
            }
        }
        return cost;
    }
}

class LandPhoneInProvinceRule extends CallChargeRule {
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            if(n==0){
                cost+=0.3;
            }
            if(remainder==0){
                cost+=n*0.3;
            }else{
                cost += (n+1)*0.3;
            }
        }
        return cost;
    }
}

class MessageRecord {
    private String message;

    public String getMessage() {
        return message;
    }

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

class MobilePhoneCharging extends ChargeMode{//手机收费
    public MobilePhoneCharging(){
        super();
        super.getChargeRules().add(new MobilePhoneInCityRule());
        super.getChargeRules().add(new MobilePhoneInProvinceRule());
        super.getChargeRules().add(new MobilePhoneInLandRule());
        super.getChargeRules().add(new AnswerChargeRule());
    }
    @Override
    public  double calCost(UserRecords userRecords){
        return super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords())
                + super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords())
                + super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords())
                + super.getChargeRules().get(3).calCost(userRecords.getAnswerInLandRecords());
    }

    @Override
    public  double getMonthlyRent (){
        return  15;
    }
}

class MobilePhoneInCityRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            double charge;
            if(i.getCallingAddressAreaCode().equals("0791")){
                charge = 0.1;
            } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) {
                charge = 0.3;
            }else{
                charge = 0.6;
            }
            if(n==0){
                cost+=charge;
            }
            if(remainder==0){
                cost+=n*charge;
            }else{
                cost += (n+1)*charge;
            }
        }
        return cost;
    }
}

class MobilePhoneInLandRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            double charge;
            if(i.getCallingAddressAreaCode().equals("0791")){
                charge = 0.3;
            } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) {
                charge = 0.3;
            }else{
                charge = 0.6;
            }
            if(n==0){
                cost+=charge;
            }
            if(remainder==0){
                cost+=n*charge;
            }else{
                cost += (n+1)*charge;
            }
        }
        return cost;
    }
}

class MobilePhoneInProvinceRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            double charge;
            if(i.getCallingAddressAreaCode().equals("0791")){
                charge = 0.2;
            } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) {
                charge = 0.3;
            }else{
                charge = 0.6;
            }
            if(n==0){
                cost+=charge;
            }
            if(remainder==0){
                cost+=n*charge;
            }else{
                cost += (n+1)*charge;
            }
        }
        return cost;
    }
}

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

    public User() {
    }

    public double calBanlance(){
        return balance - calCost() - chargeMode.getMonthlyRent();
    }

    public 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 {
    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 answerRecord){
        answerInCityRecords.add(answerRecord);
    }

    public void addAnswerInProvinceRecords (CallRecord answerRecord){
        answerInProvinceRecords.add(answerRecord);
    }

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

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

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

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

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

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

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

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

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

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

    public ArrayList<MessageRecord> getReceiveMessageRecords() {
        return receiveMessageRecords;
    }
}
电信计费第二次作业

 

分析如下:

  本题是对于上一次作业的一次迭代,最大的变化是增加了手机这个与座机在机制上有很大区别的类型,所以需要为手机用户做一套与座机用户相似的系统,而这就需要用到继承,比如从类图中可以看出,座机收费机制的类和手机收费机制的类都继承于CalChargeRule,提高了的代码的复用性,也为后期的维护提供了便利。同时由于手机用户的收费机制有特殊的漫游机制(省内漫游和省外漫游),所以座机呼叫座机,座机呼叫手机,手机呼叫手机,需要不同的方式录入。对于拨打信息中时间部分的提取,我用split()通过前面部分的正则,将字符串分割为""和时间部分。据我所知,很多同学用的是text(),但我觉得用这个不便于下一次复用,因为时间部分是第几个字符开始是不确定的。

 

电信计费第三次作业

题目描述如下:

 

类图如下:

 

 

 

源码如下:

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

public class Main {
    public static void main(String[] args) throws ParseException{
        Control control = new Control();
        control.start();
    }
}

class Control {
    Scanner in = new Scanner(System.in);
    private ArrayList<User> users = new ArrayList<>();

    public  Control(){
    }

    public void classify() throws ParseException {
        String line;
        String LandPhone = "0\\d{2,3}[0-9]{7,8}\\s";
        String MobilePhone = "1\\d{10}\\s0\\d{2,3}\\s";

        String part1 = "(((\\d{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?";
        String part2 = "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|1\\d|2[0-8]))))|(((";
        String part3 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))";
        String part4 = "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5][0-9])\\s";
        String part5 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9]\\d|[0-9][1-9][0-9]{2}|[1-9]\\d{3})\\.((([13578]|1[02])\\.(";
        String part6 = "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((";
        String part7 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))";
        String part8 = "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])";

        String time = part1 + part2 + part3+ part4+ part5+ part6+ part7+ part8;
        do{
            line = in.nextLine();
            if(line.matches("u-0791[0-9]{7,8}\\s0")){
                boolean flag = true;
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                User user = new User();
                for(User i:users){
                    if(i.getNumber().equals(b[0])){
                        flag = false;
                        break;
                    }
                }
                if(flag){
                    user.setNumber(b[0]);
                    user.setChargeMode(new LandlinePhoneCharging());
                    users.add(user);
                }
            } else if(line.matches("u-1\\d{10}\\s1")){
                boolean flag = true;
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                User user = new User();
                for(User i:users){
                    if(i.getNumber().equals(b[0])){
                        flag = false;
                    }
                }
                if(flag){
                    user.setNumber(b[0]);
                    user.setChargeMode(new MobilePhoneCharging());
                    users.add(user);
                }
            } else if (line.matches("t-"+LandPhone+LandPhone+time)) {//座机打座机
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                String c[] = a[1].split(LandPhone+LandPhone);
                String d[] = c[1].split("\\s");
                for(int i = 0;i<users.size();i++){
                    if(users.get(i).getNumber().equals(b[0])){
                        String callingAddressAreaCode="";
                        String answerAddressAreaCode="";
                        for(int j = 0;j<4;j++){
                            callingAddressAreaCode += b[0].charAt(j);
                        }
                        for(int j = 0;j<4;j++){
                            answerAddressAreaCode += b[1].charAt(j);
                        }
                        //座机拨打
                        if(callingAddressAreaCode.equals(answerAddressAreaCode)){
                            users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        } else if (AreaNums.get().contains(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }else{
                            users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }

                    }
                }
            } else if (line.matches("t-"+LandPhone+MobilePhone+time)) {//座机打手机
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                String c[] = a[1].split(LandPhone+MobilePhone);
                String d[] = c[1].split("\\s");
                String callingAddressAreaCode="";
                String answerAddressAreaCode=b[2];
                for(int j = 0;j<4;j++){
                    callingAddressAreaCode += b[0].charAt(j);
                }
                //记录手机省外接听
                for(int k = 0;k<users.size();k++){
                    if(users.get(k).getNumber().equals(b[1])){
                        if(!AreaNums.get().contains(answerAddressAreaCode)){
                            users.get(k).getUserRecords().addAnswerInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                        break;
                    }
                }
                for(int i = 0;i<users.size();i++){
                    if(users.get(i).getNumber().equals(b[0])){
                        //记录座机拨打
                        if(callingAddressAreaCode.equals(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        } else if (AreaNums.get().contains(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }else{
                            users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                    }
                }
            } else if (line.matches("t-"+MobilePhone+LandPhone+time)) {//手机打座机
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                String c[] = a[1].split(MobilePhone+LandPhone);
                String d[] = c[1].split("\\s");
                String callingAddressAreaCode=b[1];
                String answerAddressAreaCode = "";
                for(int j = 0;j<4;j++){
                    answerAddressAreaCode += b[2].charAt(j);
                }
                for(int i = 0;i<users.size();i++){
                    if(users.get(i).getNumber().equals(b[0])){
                        //记录手机拨打
                        if(callingAddressAreaCode.equals(answerAddressAreaCode)){
                            users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        } else if (AreaNums.get().contains(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }else{
                            users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                    }
                }
            } else if (line.matches("t-"+MobilePhone+MobilePhone+time)) {//手机打手机
                String a[] = line.split("-");
                String b[] = a[1].split("\\s");
                String c[] = a[1].split(MobilePhone+MobilePhone);
                String d[] = c[1].split("\\s");
                String callingAddressAreaCode=b[1];
                String answerAddressAreaCode=b[3];
                //记录手机省外接听
                for(int k = 0;k<users.size();k++){
                    if(users.get(k).getNumber().equals(b[2])){
                        if(!AreaNums.get().contains(answerAddressAreaCode)){
                            users.get(k).getUserRecords().addAnswerInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                        break;
                    }
                }
                for(int i = 0;i<users.size();i++){
                    if(users.get(i).getNumber().equals(b[0])){
                        //记录手机拨打
                        if(callingAddressAreaCode.equals(answerAddressAreaCode)){
                            users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        } else if (AreaNums.get().contains(answerAddressAreaCode)) {
                            users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }else{
                            users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d));
                        }
                    }
                }
            }
        }while(!line.equals("end"));
    }

    public CallRecord getCallRecord(String callingAddressAreaCode,String answerAddressAreaCode,String d[]) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        Date startTime = simpleDateFormat.parse(d[0]+" "+d[1]);
        Date endTime = simpleDateFormat.parse(d[2]+" "+d[3]);
        return  new CallRecord(startTime,endTime,callingAddressAreaCode,answerAddressAreaCode);
    }

    public void start() throws ParseException {
        classify();
        for(int i=0;i<users.size()-1;i++) {
            for(int j=0;j<users.size()-1-i;j++) {
                if(users.get(j).getNumber().compareTo(users.get(j+1).getNumber()) > 0) {
                    User temp=users.get(j);
                    users.set(j,users.get(j+1));
                    users.set(j+1,temp);
                }
            }
        }
        for(User i:users){
            System.out.printf("%s %.1f %.1f\n",i.getNumber(),i.calCost(),i.calBanlance());
        }
    }
}

class AnswerChargeRule extends ChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            if(n==0){
                cost+=0.3;
            }
            if(remainder==0){
                cost+=n*0.3;
            }else{
                cost += (n+1)*0.3;
            }
        }
        return cost;
    }
}

class AreaNums {
    static ArrayList<String> areaNums = new ArrayList<>();
    public AreaNums(){
    }

    public static ArrayList get(){
        areaNums.add("0790");
        areaNums.add("0791");
        areaNums.add("0792");
        areaNums.add("0793");
        areaNums.add("0794");
        areaNums.add("0795");
        areaNums.add("0796");
        areaNums.add("0797");
        areaNums.add("0798");
        areaNums.add("0799");
        areaNums.add("0701");
        return areaNums;
    }
}

abstract class CallChargeRule extends ChargeRule{

    public abstract double calCost (ArrayList<CallRecord> callRecords);

}

class CallRecord extends CommunicationRecord{
    private Date startTime;
    private Date endTime;
    private String callingAddressAreaCode;
    private 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 {
    private ArrayList<ChargeRule> chargeRules = new ArrayList<>();


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

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

    public  abstract double calCost(UserRecords userRecords);

    public abstract double getMonthlyRent();
}

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

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

    public String getCallingNumber() {
        return callingNumber;
    }

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

    public String getAnswerNumber() {
        return answerNumber;
    }

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

class LandlinePhoneCharging extends ChargeMode{//座机收费
    public LandlinePhoneCharging(){
        super();
        super.getChargeRules().add(new LandPhoneInCityRule());
        super.getChargeRules().add(new LandPhoneInProvinceRule());
        super.getChargeRules().add(new LandPhoneInLandRule());
    }
    @Override
    public  double calCost(UserRecords userRecords){
        return super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords())
                + super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords())
                + super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords());
    }

    @Override
    public  double getMonthlyRent (){
        return  20;
    }
}

class LandPhoneInCityRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            if(n==0){
                cost+=0.1;
            }
            if(remainder==0){
                cost+=n*0.1;
            }else{
                cost += (n+1)*0.1;
            }
        }
        return cost;
    }
}

class LandPhoneInLandRule extends CallChargeRule {
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost = 0;
        for (CallRecord i : callRecords) {
            long remainder = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 % 60;
            long n = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 / 60;
            if (n == 0) {
                cost += 0.6;
            }
            if (remainder == 0) {
                cost += n * 0.6;
            } else {
                cost += (n + 1) * 0.6;
            }
        }
        return cost;
    }
}

class LandPhoneInProvinceRule extends CallChargeRule {
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            if(n==0){
                cost+=0.3;
            }
            if(remainder==0){
                cost+=n*0.3;
            }else{
                cost += (n+1)*0.3;
            }
        }
        return cost;
    }
}

class MessageRecord {
    private String message;

    public String getMessage() {
        return message;
    }

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

class MobilePhoneCharging extends ChargeMode{//手机收费
    public MobilePhoneCharging(){
        super();
        super.getChargeRules().add(new MobilePhoneInCityRule());
        super.getChargeRules().add(new MobilePhoneInProvinceRule());
        super.getChargeRules().add(new MobilePhoneInLandRule());
        super.getChargeRules().add(new AnswerChargeRule());
    }
    @Override
    public  double calCost(UserRecords userRecords){
        return super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords())
                + super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords())
                + super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords())
                + super.getChargeRules().get(3).calCost(userRecords.getAnswerInLandRecords());
    }

    @Override
    public  double getMonthlyRent (){
        return  15;
    }
}

class MobilePhoneInCityRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            double charge;
            if(i.getCallingAddressAreaCode().equals("0791")){
                charge = 0.1;
            } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) {
                charge = 0.3;
            }else{
                charge = 0.6;
            }
            if(n==0){
                cost+=charge;
            }
            if(remainder==0){
                cost+=n*charge;
            }else{
                cost += (n+1)*charge;
            }
        }
        return cost;
    }
}

class MobilePhoneInLandRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            double charge;
            if(i.getCallingAddressAreaCode().equals("0791")){
                charge = 0.3;
            } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) {
                charge = 0.3;
            }else{
                charge = 0.6;
            }
            if(n==0){
                cost+=charge;
            }
            if(remainder==0){
                cost+=n*charge;
            }else{
                cost += (n+1)*charge;
            }
        }
        return cost;
    }
}

class MobilePhoneInProvinceRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost=0;
        for(CallRecord i:callRecords){
            long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60;
            long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60;
            double charge;
            if(i.getCallingAddressAreaCode().equals("0791")){
                charge = 0.2;
            } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) {
                charge = 0.3;
            }else{
                charge = 0.6;
            }
            if(n==0){
                cost+=charge;
            }
            if(remainder==0){
                cost+=n*charge;
            }else{
                cost += (n+1)*charge;
            }
        }
        return cost;
    }
}

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

    public User() {
    }

    public double calBanlance(){
        return balance - calCost() - chargeMode.getMonthlyRent();
    }

    public 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 {
    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 answerRecord){
        answerInCityRecords.add(answerRecord);
    }

    public void addAnswerInProvinceRecords (CallRecord answerRecord){
        answerInProvinceRecords.add(answerRecord);
    }

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

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

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

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

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

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

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

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

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

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

    public ArrayList<MessageRecord> getReceiveMessageRecords() {
        return receiveMessageRecords;
    }
}
电信收费第三次作业

 

分析如下:

  本题虽然是对于上一次的迭代,但上一次的电话收费根本没有用到,只需要单独设计短信收费机制即可。虽然看起来比上一次简单,但还是有很多点需要注意,首先最为重要的是要理解短信的收费机制。我一开始并没有理解,误认为收费的叠加只针对每一次短信的发送,而不是总体。当我理解收费叠加机制是针对与总体时,我尝试将每一次发送的内容加起来成为一条长短信,如何根据每十个字符一条短信来计算短信条数,最后根据收费叠加机制计算,但这也是错误的。因为在一条短信发送中,可以有多条短信,同时在一次短信发送中,小于十个字符要算一条短信。所以需要根据每次短信的发送来单独计算条数。所以最终的方案是先单独算出每次发送的条数,然后累加得到短信总条数,然后再根据收费叠加机制计算总费用。

 

 

踩坑心得

  相比之前一看到题目就动手,在这几次作业中,我先进行大致的类设计再进行具体的完善和实现。这样的思路让我相比之前效率提升了很多,也让认识类设计的重要性。

 

内容总结

  最近期末将近,考试繁多,故题量有所下降,难度也没之前高了,但我还是从中收获了很多。对于继承与多态、封装、正则表达式的理解和运用更加深入,对于错误原因的分析能力也得到了增长。

posted on 2022-06-15 22:55  不知明月照何人  阅读(25)  评论(0)    收藏  举报