首页 > 其他分享 >BLOG-3

BLOG-3

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

1.前言:本次博客主要是对pta-6,pta-7,pta-8大作业的总结与收获。pta6-8考的是电信计费系列,第一次只考虑座机的情况且只考虑打电话的情况。主要运用的ArrayList的使用,以及考察类的设计,但是给了类的设计图,把难度减少了许多。总的来说,难度并不是很大。第二次,在座机的基础上增加了手机,还有地区之分,比如市内打电话给省内,市内打电话给市内,市内打电话给省外等一系列的情况。好在没处理信息收费的情况,但是难度较于第一次还是有很大的提升。情况变得更复杂,就需要你的类的设计更加的合理,更有复用性。pta-8的话,难度减少了许多。第三次,只考虑信息收费的情况,只有一种计费类型,可以不使用计费规则也能完成该计费。总之,三次大作业,第一第二次比较难,第三次比较简单。

 

2.设计与分析:

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

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

输入格式:

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

输出格式:

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

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

 

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    static User user,usernull;
    static UserRecords userrecords = new UserRecords();
    static CallRecord callrecord;
    static DataBase database = new DataBase();
    static boolean flag = true;
    static ArrayList<String> remember = new ArrayList<String>();//记录并防止重复
    private static Scanner in;

    public static void main(String[] args) throws ParseException {
        in = new Scanner(System.in);
        SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        while(true) {
            if(flag==false) {
                break;
            }
            String alp = in.nextLine();
            if(remember.contains(alp)) {
                continue;
            }else {
                remember.add(alp);
            }
            String regStr = "u-([0-9]){11,12} 0|t-[0-9]{11,12} [0-9]{10,12}( [0-9]{4}.([1-9]|10|11|12).([0-9]|[1-3][0-9]) ([0-9]|[0-2][0-9]):([0-5][0-9]):([0-5][0-9]))+|end";
            if(!Pattern.matches(regStr, alp)) {
                continue;
            }
            Pattern pattern = Pattern.compile("[0-9]{10,12}|0|end|[0-9]{4}.([1-9]|10|11|12).([1-9]|[1-3][0-9]) ([0-9]|[0-9][0-9]):([0-9]|[0-5][0-9]):([0-5][0-9])");//粗略的提取
            Matcher matcher = pattern.matcher(alp);//按照正则规则匹配
            int count = 0;
            while(matcher.find()) {//提取数据
                if(matcher.group(0).equals("end")) {
                    flag=false;
                }
                if(alp.charAt(0)=='u') {//开户
                    if(count==0) {
                        user = new User();
                        user.setNumber(matcher.group(0));//号码
                    }
                    if(count==1) {
                        user.setBillingmethod(matcher.group(0));//计费方式
                    }
                    if(count==1) {
                        database.add(user);
                        user = null;
                    }
                    count++;
                }
                else if(alp.charAt(0)=='t') {
                    if(count==2) {
                        if(check(matcher.group(0))) {
                            callrecord.setStartTime(simpleFormat.parse(matcher.group(0)));
                        }else {
                            break;
                        }
                    }
                    if(count==3) {
                        if(check(matcher.group(0))) {
                            callrecord.setEndTime(simpleFormat.parse(matcher.group(0)));
                        }else {
                            break;
                        }
                    }
                    if(count==0) {
                        callrecord = new CallRecord();
                        callrecord.setCallingNumber(matcher.group(0));
                        callrecord.setCallingAddressAreaCode(matcher.group(0).substring(0, 4));
                    }
                    if(count==1) {
                        callrecord.setAnswerNumber(matcher.group(0));
                        callrecord.setAnswerAddressAreaCode(matcher.group(0).substring(0, 4));
                    }
                    if(count==3) {
                        for(User element : database.getAllUser()) {//给对应的座机号添加对应的通话记录
                            if(element.getNumber().equals(callrecord.getCallingNumber())) {//号码匹配,说明这条通话记录是element的
                                addUserRecord(callrecord.getCallingAddressAreaCode(),callrecord.getAnswerAddressAreaCode(),callrecord,element);
                            }
                        }
                    }
                    count++;
                }
            }
        }
        Collections.sort(database.getAllUser());
        for(User element : database.getAllUser()) {
            System.out.println(element.getNumber()+" "+element.calCost()+" "+element.calBalance());
        }
    }

    public static boolean check(String str) {//检验日期是否合法
        return true;
    }

    public static void addUserRecord(String number1,String number2,CallRecord acallrecord,User user) {
        String regStr = "079[0-9]|0701";
        if(number1.equals("0791")&&number2.equals("0791")) {
            user.getUserRecords().addCallingInCityRecords(acallrecord);
        }else if(number1.equals("0791")&&Pattern.matches(regStr, number2)) {
            user.getUserRecords().addCallingInProvinceRecords(acallrecord);
        }else {
            user.getUserRecords().addCallingInLandRecords(acallrecord);
        }

    }
}

class User implements Comparable<User>{
    private UserRecords userRecords = new UserRecords();
    private float balance = 100;
    private ChargeMode chargeMode = new ChargeMode();
    private String number;
    private String Billingmethod;

    public float calBalance() {
        balance = balance-chargeMode.getMonthlyRent()-calCost();
        return (float)balance;
    }
    public float calCost() {
        return chargeMode.calCost(userRecords);
    }
    public UserRecords getUserRecords() {
        return userRecords;
    }
    public void setUserRecords(UserRecords userRecords) {
        this.userRecords = userRecords;
    }
    public double getBalance() {
        return balance;
    }
    public ChargeMode getChargeMode() {
        return chargeMode;
    }
    public void setChargeMode(ChargeMode chargeMode) {

    }
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public void setBillingmethod(String string) {
        this.Billingmethod = string;
    }
    @Override
    public int compareTo(User o) {
        // TODO Auto-generated method stub
        return this.number.compareTo(o.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 callRecord) {
        answerInCityRecords.add(callRecord);
    }
    public void addAnswerInProvinceRecords(CallRecord callRecord) {
        answerInProvinceRecords.add(callRecord);
    }
    public void addAnswerInLandRecords(CallRecord callRecord) {
        answerInLandRecords.add(callRecord);
    }
    public void addSendMessageRecords(CallRecord callRecord) {

    }
    public void addReceiveMessageRecords(CallRecord callRecord) {

    }
    public void addSendMessageRecords(MessageRecord sendMessageRecord) {

    }
    public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) {

    }
    public ArrayList<MessageRecord> getSendMessageRecords(){
        return sendMessageRecords;
    }
    public ArrayList<MessageRecord> getReceiveMessageRecords(){
        return receiveMessageRecords;
    }
    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;
    }
}

class ChargeMode{
    private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();
    private LandPhoneInCityRule cityrule = new LandPhoneInCityRule();
    private LandPhoneInlandRule landrule = new LandPhoneInlandRule();
    private LandPhoneInProvinceRule provincerule = new LandPhoneInProvinceRule();

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

    public float calCost(UserRecords userRecords) {
        double cost = 0;
        if(userRecords.getCallingInCityRecords().size()!=0) {
            cost = cost + cityrule.calCost(userRecords.getCallingInCityRecords(), '0');
        }
        if(userRecords.getCallingInProvinceRecords().size()!=0) {
            cost = cost + provincerule.calCost(userRecords.getCallingInProvinceRecords(), '0');
        }
        if(userRecords.getCallingInLandRecords().size()!=0) {
            cost = cost + landrule.calCost(userRecords.getCallingInLandRecords(), '0');
        }
        return (float)cost;
    }
    public float getMonthlyRent() {
        return 20;
    }
}

class LandlinePhoneCharging extends ChargeMode{
    private float monthlyRent = 20;

    public float calCost(UserRecords userRecords) {
        // TODO Auto-generated method stub
        return 0;
    }
    public float getMonthlyRent() {
        // TODO Auto-generated method stub
        return monthlyRent;
    }
}

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

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

class MessageRecord extends CommunicationRecord{
    private String message;

    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {

    }
}

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

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

class LandPhoneInCityRule extends CallChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords,char rule) {
        double cost = 0;
        for(CallRecord element : callRecords) {
            long startTime = element.getStartTime().getTime();
            long endTime = element.getEndTime().getTime();
            double minute = ((endTime - startTime)/1000.0/60.0);
            if(minute>(int) minute) {
                cost = cost + 0.1*((int)minute+1);
            }else {
                cost = cost + 0.1*minute;
            }
        }
        return cost;
    }

}

class LandPhoneInlandRule extends CallChargeRule{

    @Override
    public double calCost(ArrayList<CallRecord> callRecords,char rule) {
        double cost = 0;
        for(CallRecord element : callRecords) {
            long startTime = element.getStartTime().getTime();
            long endTime = element.getEndTime().getTime();
            double minute = ((endTime - startTime)/1000.0/60.0);
            if(minute>(int) minute) {
                cost = cost + 0.6*((int)minute+1);
            }else {
                cost = cost + 0.6*minute;
            }
        }
        return cost;
    }

}

class LandPhoneInProvinceRule extends CallChargeRule{
    @Override
    public double calCost(ArrayList<CallRecord> callRecords,char rule) {
        double cost = 0;
        for(CallRecord element : callRecords) {
            long startTime = element.getStartTime().getTime();
            long endTime = element.getEndTime().getTime();
            double minute = ((endTime - startTime)/1000.0/60.0);
            if(minute>(int) minute) {
                cost = cost + 0.3*((int)minute+1);
            }else {
                cost = cost + 0.3*minute;
            }
        }
        return cost;
    }

}

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

abstract class ChargeRule{

}

class DataBase{
    private ArrayList<User> list = new ArrayList<User>();

    public void add(User user) {
        list.add(user);
    }

    public ArrayList<User> getAllUser(){
        return list;
    }
}

 

 

 

 7-2 多态测试

定义容器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.math.BigDecimal;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner a = new Scanner(System.in);
        int n;

        n = a.nextInt();
        Container[] c = new Container[n];
        for (int i = 0; i < n; i++) {
            String zifu;
            zifu = a.next();
            if (zifu.equals("cube")) {
                Container shape = new Cube();
                ((Cube) shape).a = a.nextDouble();
                c[i] = shape;
            } else if (zifu.equals("cylinder")) {
                Container shape = new Cylinder();
                ((Cylinder) shape).r = a.nextDouble();
                ((Cylinder) shape).h = a.nextDouble();
                c[i] = shape;
            }
        }
        System.out.println(shuchu(Container.sumofArea(c)));
        System.out.println(shuchu(Container.sumofVolume(c)));
    }
    public static double shuchu ( double a)
    {
        double q;
        BigDecimal w = new BigDecimal(a);
        q = w.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return q;
    }

}




interface Container {
    public static final double pi = 3.1415926;

    public abstract double area();

    public abstract double volume();

    static double sumofArea(Container c[]) {
        double sum = 0;
        for (int i = 0; i < c.length; i++) {
            sum += c[i].area();
        }
        return sum;
    }

    static double sumofVolume(Container c[]) {
        double sum = 0;
        for (int i = 0; i < c.length; i++) {
            sum += c[i].volume();
        }
        return sum;
    }
}


class Cube implements Container {
    public double a;

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

    @Override
    public double volume() {
        return a * a * a;
    }
}

class Cylinder implements Container {
    public double r, h;

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

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

 

 

 

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

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

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

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

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

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
    public static void main(String[] args) throws ParseException {
        Scanner in = new Scanner(System.in);
        ArrayList<User> users = new ArrayList<>();
        String regex2 = "(079\\d|0701)";
        String a = in.nextLine();
        String[] s;
        while (!a.equals("end")){
            int l = 0;
            //座机开户
            if (a.matches("[u][-](0791)[0-9]{7,8}[ ][0]")){
                s = a.substring(2,a.length()).split("\\s");
                if (users.size()==0){
                    users.add(new User(s[0],new LandlinePhoneCharging()));}
                else {
                    for (int i = 0; i < users.size(); i++) {
                        if (s[0].equals(users.get(i).getNumber()))
                            l = 1;
                    }

                    if (l == 0 && users.size() != 0)
                        users.add(new User(s[0],new LandlinePhoneCharging()));
                } }
            //手机开户
            else if (a.matches("u-1[0-9]{10} [1]")){
                s = a.substring(2,a.length()).split("\\s");
                if (users.size()==0){
                    users.add(new User(s[0],new MobilePhoneCharging()));}
                else {
                    for (int i = 0; i < users.size(); i++) {
                        if (s[0].equals(users.get(i).getNumber())) {
                            l = 1;
                            break;
                        }
                    }
                    if (l == 0 && users.size() != 0)
                        users.add(new User(s[0],new MobilePhoneCharging()));
                } 
            }

            //两个手机用户(1-2月)
            else if (a.matches("t-1[0-9]{10}\\s(0[0-9]{3}|020)\\s[1][0-9]{10}\\s(0[0-9]{3}|020) \\d{4}.(1|//d{1,3}).\\d{1,3} \\d{2}:\\d{2}:\\d{2} \\d{4}.(1|2).\\d{1,3} \\d{2}:\\d{2}:\\d{2}")){
                s = a.substring(2,a.length()).split("\\s");
                for (User e:users){
                    if ( s[0].equals(e.getNumber())){
                        if (s[1].equals("0791")) {
                            if (s[1].equals(s[3]))
                                e.getUserRecords().addCallingInCityRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                            else if (s[3].matches("(079[0-9]|0701)"))
                                e.getUserRecords().addCallingInProvinceRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                            else
                                e.getUserRecords().addCallingInLandRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                        }
                        else if (s[1].matches("(0701|0790|079[2-9])")){
                            e.getUserRecords().addCallingInProvinceRoamRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                        }
                        else
                            e.getUserRecords().addCallingInLandRoamRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                    }
                    if (s[2].equals(e.getNumber())){
                        if (!s[3].matches("(079[0-9]|0701)"))
                            e.getUserRecords().addAnswerInLandRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                    }
                }
            }


            //两个手机用户
            else if (a.matches("t-1\\d{10} (\\d{3}|\\d{4}) \\d{11} (\\d{3}|\\d{4})\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d")){
                s = a.substring(2,a.length()).split("\\s");
                for (User e:users){
                    if ( s[0].equals(e.getNumber())){
                        if (s[1].equals("0791")) {
                            if (s[1].equals(s[3]))
                                e.getUserRecords().addCallingInCityRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                            else if (s[3].matches("(079[0-9]|0701)"))
                                e.getUserRecords().addCallingInProvinceRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                            else
                                e.getUserRecords().addCallingInLandRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                        }
                        else if (s[1].matches("(0701|0790|079[2-9])")){
                            e.getUserRecords().addCallingInProvinceRoamRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                        }
                        else
                            e.getUserRecords().addCallingInLandRoamRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                    }
                    if (s[2].equals(e.getNumber())){
                        if (!s[3].matches("(079[0-9]|0701)"))
                            e.getUserRecords().addAnswerInLandRecords(new CallRecord(s[4] + " " + s[5], s[6] + " " + s[7]));
                    }
                }
            }
            //先手机后座机(1-2月)
            else if (a.matches("t-1[0-9]{10}\\s(0[0-9]{3}|020)\\s(0[0-9]{3}|020)[0-9]{7,9} \\d{4}.1.\\d{1,3} \\d{2}:\\d{2}:\\d{2} \\d{4}.2.\\d{1,3} \\d{2}:\\d{2}:\\d{2}")){
                s = a.substring(2,a.length()).split("\\s");
                String num = s[2].substring(0,4);
                for (User e:users){
                    if (s[0].equals(e.getNumber())){
                        if (s[1].equals("0791")){
                            if (s[1].equals(num))
                                e.getUserRecords().addCallingInCityRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                            else if (num.matches("(079[0-9]|0701)"))
                                e.getUserRecords().addCallingInProvinceRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                            else
                                e.getUserRecords().addCallingInLandRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                        }
                        else if (s[1].matches("(0701|0790|079[2-9])")){
                            e.getUserRecords().addCallingInProvinceRoamRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                        }
                        else
                            e.getUserRecords().addCallingInLandRoamRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                    }

                }
            }

            //先手机后座机
            else if (a.matches( "t-1\\d{10} (020|0\\d{3}) \\d{10,13}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d" )){
                s = a.substring(2,a.length()).split("\\s");
                String num = s[2].substring(0,4);
                for (User e:users){
                    if (s[0].equals(e.getNumber())){
                        if (s[1].equals("0791")){
                            if (s[1].equals(num))
                                e.getUserRecords().addCallingInCityRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                            else if (num.matches("(079[0-9]|0701)"))
                                e.getUserRecords().addCallingInProvinceRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                            else
                                e.getUserRecords().addCallingInLandRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                        }
                        else if (s[1].matches("(0701|0790|079[2-9])")){
                            e.getUserRecords().addCallingInProvinceRoamRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                        }
                        else
                            e.getUserRecords().addCallingInLandRoamRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                    }

                }
            }

            //先座机后手机
            else if (a.matches("t-(0[0-9]{3}|020)\\d{7,9} 1\\d{10} (\\d{3}|\\d{4})\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d")){
                s = a.substring(2,a.length()).split("\\s");
                String num = s[0].substring(0,4);
                for (User e:users){
                    if (s[0].equals(e.getNumber())){
                            if (s[2].startsWith("0791")){
                                e.getUserRecords().addCallingInCityRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));}
                            else if (s[2].matches(regex2)){
                                e.getUserRecords().addCallingInProvinceRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));}
                            else {
                                e.getUserRecords().addCallingInLandRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));}
                        }
                    if (s[1].equals(e.getNumber())){
                        if (!s[2].matches("(079[0-9]|0701)"))
                            e.getUserRecords().addAnswerInLandRecords(new CallRecord(s[3] + " " + s[4], s[5] + " " + s[6]));
                    }
                    }

                }



            //两座机
            else if (a.matches("t-(0[0-9]{3}|020)\\d{7,9}\\s(\\d){10,12}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d")){
                s = a.substring(2,a.length()).split("\\s");
                for (User e:users){
                    if (s[0].equals(e.getNumber())) {
                        if (s[1].startsWith("0791")){
                            e.getUserRecords().addCallingInCityRecords(new CallRecord(s[2] + " " + s[3], s[4] + " " + s[5]));}
                        else if (s[1].substring(0,4).matches(regex2)){
                            e.getUserRecords().addCallingInProvinceRecords(new CallRecord(s[2] + " " + s[3], s[4] + " " + s[5]));}
                        else {
                            e.getUserRecords().addCallingInLandRecords(new CallRecord(s[2] + " " + s[3], s[4] + " " + s[5]));}
                    }
                }
            }

            a = in.nextLine();
        }
        Collections.sort(users);
        for (User e:users) {
            System.out.print(e.getNumber()+" ");
            System.out.printf("%.1f",e.calCost());
            System.out.print(" ");
            System.out.printf("%.1f",e.calBalance());
            System.out.println();
        }
    }
}





class User implements Comparable<User>{                                               //用户类
    private UserRecords userRecords = new UserRecords(); //用户记录
    private double balance = 100;                        //余额
    private ChargeMode chargeMode ;                       //计费方式
    private String number;                               //手机号码

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

    public double calBalance(){
        this.balance = balance - calCost()-chargeMode.getMonthlyRent();
        return balance;
    }

    public double calCost(){
        double cityCost = 0,provinceCost = 0, landCost = 0,provinceRoamCost = 0 ,landRoamCost = 0 ,landAnswerCost = 0,Cost = 0 ;
        
        if (chargeMode.judgeMode() == 0 ){
            ArrayList<LandPhoneInCityRule> cityRules = new ArrayList<>();
            ArrayList<LandPhoneInProvinceRule> provinceRules = new ArrayList<>();
            ArrayList<LandPhoneInlandRule> landRules = new ArrayList<>();
        cityRules.add(new LandPhoneInCityRule(this.getUserRecords().getCallingInCityRecords()));
        provinceRules.add(new LandPhoneInProvinceRule(this.getUserRecords().getCallingInProvinceRecords()));
        landRules.add(new LandPhoneInlandRule(this.getUserRecords().getCallingInLandRecords()));
        
        for (LandPhoneInCityRule e :cityRules) {
            cityCost=e.calCost(this.getUserRecords().getCallingInCityRecords()) + cityCost;
        }

        for (LandPhoneInProvinceRule e :provinceRules) {
            provinceCost= e.calCost(this.getUserRecords().getCallingInProvinceRecords()) + provinceCost;
        }

        for (LandPhoneInlandRule e :landRules) {
            landCost= e.calCost(this.getUserRecords().getCallingInLandRecords()) + landCost;
        }
        Cost = cityCost+provinceCost+landCost;}

        else if (chargeMode.judgeMode() == 1){
            ArrayList<MobilePhoneInCityRule> cityRules = new ArrayList<>();
            ArrayList<MobilePhoneInProvinceRule> provinceRules = new ArrayList<>();
            ArrayList<MobilePhoneInlandRule> landRules = new ArrayList<>();
            ArrayList<MobilePhoneInProvinceRoamRule> provinceRoamRules = new ArrayList<>(); //漫游
            ArrayList<MobilePhoneInlandRoamRule> landRoamRules = new ArrayList<>();
            ArrayList<LandPhoneInlandAnswerRule> landPhoneInlandAnswerRules= new ArrayList<>();

            cityRules.add(new MobilePhoneInCityRule(this.getUserRecords().getCallingInCityRecords()));
            provinceRules.add(new MobilePhoneInProvinceRule(this.getUserRecords().getCallingInProvinceRecords()));
            landRules.add(new MobilePhoneInlandRule(this.getUserRecords().getCallingInLandRecords()));
            provinceRoamRules.add(new MobilePhoneInProvinceRoamRule(this.getUserRecords().getCallingInProvinceRoamRecords()));
            landRoamRules.add(new MobilePhoneInlandRoamRule(this.getUserRecords().getCallingInLandRoamRecords()));
            landPhoneInlandAnswerRules.add(new LandPhoneInlandAnswerRule(this.getUserRecords().getAnswerInLandRecords()));

            for (MobilePhoneInCityRule e :cityRules) {
                cityCost=e.calCost(this.getUserRecords().getCallingInCityRecords()) + cityCost;
            }

            for (MobilePhoneInProvinceRule e :provinceRules) {
                provinceCost= e.calCost(this.getUserRecords().getCallingInProvinceRecords()) + provinceCost;
            }

            for (MobilePhoneInlandRule e :landRules) {
                landCost= e.calCost(this.getUserRecords().getCallingInLandRecords()) + landCost;
            }

            for (MobilePhoneInProvinceRoamRule e :provinceRoamRules) {
                provinceRoamCost=e.calCost(this.getUserRecords().getCallingInProvinceRoamRecords()) + provinceRoamCost;
            }

            for (MobilePhoneInlandRoamRule e :landRoamRules) {
                landRoamCost= e.calCost(this.getUserRecords().getCallingInLandRoamRecords()) + landRoamCost;
            }

            for (LandPhoneInlandAnswerRule e :landPhoneInlandAnswerRules) {
                landAnswerCost = e.calCost(this.getUserRecords().getAnswerInLandRecords()) + landAnswerCost;
            }
            Cost = cityCost+provinceCost+landCost+provinceRoamCost+landRoamCost+landAnswerCost;
        }


        return Cost;

    }

    public UserRecords getUserRecords() {
        return userRecords;
    }

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

    public double getBalance() {
        return balance;
    }

    public ChargeMode getChargeMode() {
        return chargeMode;
    }

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

    public String getNumber() {
        return number;
    }

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

    @Override
    public int compareTo(User o) {
        return this.getNumber().compareTo(o.getNumber());
    }
}

abstract class ChargeMode{         //计费方式的抽象类
    private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();//计费方式所包含的各种计费规则的集合

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

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

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

    public double getMonthlyRent(){
        return 0;
    }

    public int judgeMode() {
        return 0;
    }


}

class UserRecords{                           //是用户记录类,保存用户各种通话、短信的记录, 各种计费规则将使用其中的部分或者全部记录。
    private ArrayList<CallRecord> callingInCityRecords = new ArrayList<>();//市内拨打电话的记录
    private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<>();//省内(不含市内)拨打电话的记录
    private ArrayList<CallRecord> callingInLandRecords = new ArrayList<>();//省外拨打电话的记录

    private ArrayList<CallRecord> callingInLandRoamRecords = new ArrayList<>();//省外漫游拨打电话的记录
    private ArrayList<CallRecord> callingInProvinceRoamRecords = new ArrayList<>();//省内漫游接听电话的记录

    private ArrayList<CallRecord> answerInCityRecords = new ArrayList<>();//市内接听电话的记录
    private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<>();//省内(不含市内)接听电话的记录
    private ArrayList<CallRecord> answerInLandRecords = new ArrayList<>();//省外接听电话的记录(漫游)

    private ArrayList<CallRecord> sendMessageRecords = new ArrayList<>();//发送短信的记录
    private ArrayList<CallRecord> receiveMessageRecords = new ArrayList<>();//接受短信的记录

    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 addCallingInLandRoamRecords(CallRecord callRecord){
        callingInLandRoamRecords.add(callRecord);
    }

    public void addCallingInProvinceRoamRecords(CallRecord callRecord){
        callingInProvinceRoamRecords.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(CallRecord sendMessageRecord){
        sendMessageRecords.add(sendMessageRecord);
    }

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

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

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

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

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

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

    public ArrayList<CallRecord> getCallingInLandRoamRecords() {
        return callingInLandRoamRecords;
    }

    public ArrayList<CallRecord> getCallingInProvinceRoamRecords() {
        return callingInProvinceRoamRecords;
    }

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

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

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


class LandlinePhoneCharging extends ChargeMode{
    private double monthlyRent = 20;

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

    public double getMonthlyRent(){
        return monthlyRent;
    }

    public int judgeMode(){
        return 0;
    }
}

class MobilePhoneCharging extends ChargeMode{
    private double monthlyRent = 15;

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

    public double getMonthlyRent(){
        return monthlyRent;
    }

    public int judgeMode(){
        return 1;
    }
}

abstract class CommunicationRecord{         //抽象的通讯记录类:
    protected String callingNumber;//拨打号码
    protected String answerNumber;//接听号码

    public String getCallingNumber() {
        return callingNumber;
    }

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

    public String getAnswerNumber() {
        return answerNumber;
    }

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

class CallRecord extends CommunicationRecord{     //通话记录
    private Date startTime;                //通话的起始时间
    private Date endTime;                   //通话的结束时间
    private String callingAddressAreaCode;//拨号地点的区号
    private String answerAddressAreaCode;//接听地点的区号

    public CallRecord(String startTime,String endTime) throws ParseException {
        this.startTime =  new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").parse(startTime);
        this.endTime = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").parse(endTime);
    }

    public Date getStartTime() {
        return startTime;
    }

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

    public Date getEndTime() {
        return endTime;
    }

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

    public String getCallingAddressAreaCode() {
        return callingAddressAreaCode;
    }

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

    public String getAnswerAddressAreaCode() {
        return answerAddressAreaCode;
    }

    public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
        this.answerAddressAreaCode = answerAddressAreaCode;
    }
}

class MessageRecord extends CommunicationRecord{      //短信记录
    private String message;

    public String getMessage() {
        return message;
    }

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

abstract class ChargeRule{
}

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


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


class LandPhoneInCityRule extends CallChargeRule{
    ArrayList<CallRecord> callRecords;

    public LandPhoneInCityRule(){}

    public LandPhoneInCityRule(ArrayList<CallRecord> callRecords){
        this.callRecords = callRecords;
    }

    public double calCost(ArrayList<CallRecord> callRecords){
        double cost = 0;
        double  minutes;
        for (CallRecord e: callRecords){
            minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000);
            cost += 0.1*minutes;}
        return cost;
    }
}

class LandPhoneInlandRule extends CallChargeRule{
    ArrayList<CallRecord> callRecords;
    public LandPhoneInlandRule( ArrayList<CallRecord> callRecords){
        this.callRecords = callRecords;
    }

    public double calCost(ArrayList<CallRecord> callRecords){
        double cost = 0;
        double minutes;
        for (CallRecord e: callRecords){
            minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000);
            cost += 0.6*minutes;}
        return cost;
    }
}

class LandPhoneInProvinceRule extends CallChargeRule{
    ArrayList<CallRecord> callRecords;
    public LandPhoneInProvinceRule( ArrayList<CallRecord> callRecords){
        this.callRecords = callRecords;
    }

    public double calCost(ArrayList<CallRecord> callRecords){
        double cost = 0;
        double minutes;
        for (CallRecord e: callRecords){
            minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000);
            cost += 0.3*minutes;}
        return cost;
    }
}

class  MobilePhoneInCityRule extends CallChargeRule{
    ArrayList<CallRecord> callRecords;
    public MobilePhoneInCityRule( ArrayList<CallRecord> callRecords){
        this.callRecords = callRecords;
    }

    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost = 0;
        double minutes;
        for (CallRecord e: callRecords){
            minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000);
            cost += 0.1*minutes;}
        return cost;
    }
}

class  MobilePhoneInProvinceRule extends CallChargeRule{
    ArrayList<CallRecord> callRecords;
    public MobilePhoneInProvinceRule( ArrayList<CallRecord> callRecords){
        this.callRecords = callRecords;
    }
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost = 0;
        double minutes;
        for (CallRecord e: callRecords){
            minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000);
            cost += 0.2*minutes;}
        return cost;
    }
}

class  MobilePhoneInlandRule extends CallChargeRule{
    ArrayList<CallRecord> callRecords;
    public MobilePhoneInlandRule( ArrayList<CallRecord> callRecords){
        this.callRecords = callRecords;
    }
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost = 0;
        double minutes;
        for (CallRecord e: callRecords){
            minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000);
            cost += 0.3*minutes;}
        return cost;
    }
}

class  MobilePhoneInProvinceRoamRule extends CallChargeRule{ //省内漫游
    ArrayList<CallRecord> callRecords;
    public MobilePhoneInProvinceRoamRule( ArrayList<CallRecord> callRecords){
        this.callRecords = callRecords;
    }
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost = 0;
        double minutes;
        for (CallRecord e: callRecords){
            minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000);
            cost += 0.3*minutes;}
        return cost;
    }
}


class  MobilePhoneInlandRoamRule extends CallChargeRule{ //省外漫游
    ArrayList<CallRecord> callRecords;
    public MobilePhoneInlandRoamRule( ArrayList<CallRecord> callRecords){
        this.callRecords = callRecords;
    }
    @Override
    public double calCost(ArrayList<CallRecord> callRecords) {
        double cost = 0;
        double minutes;
        for (CallRecord e: callRecords){
            minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000);
            cost += 0.6*minutes;}
        return cost;
    }
}

class LandPhoneInlandAnswerRule extends AnswerChargeRule{
    ArrayList<CallRecord> callRecords;
    public LandPhoneInlandAnswerRule( ArrayList<CallRecord> callRecords){
        this.callRecords = callRecords;
    }

    public double calCost(ArrayList<CallRecord> callRecords){
        double cost = 0;
        double minutes;
        for (CallRecord e: callRecords){
            minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000);
            cost += 0.3*minutes;}
        return cost;
    }
}

 

 

 

 

 

 

7-2 sdut-Collection-sort--C~K的班级(II)

经过不懈的努力,C~K终于当上了班主任。

现在他要统计班里学生的名单,但是C~K在教务系统中导出班级名单时出了问题,发现会有同学的信息重复,现在他想把重复的同学信息删掉,只保留一个,
但是工作量太大了,所以找到了会编程的你,你能帮他解决这个问题吗?

输入格式:

第一行输入一个N,代表C~K导出的名单共有N行(N<100000).

接下来的N行,每一行包括一个同学的信息,学号 姓名 年龄 性别。

输出格式:

第一行输出一个n,代表删除重复名字后C~K的班级共有几人。

接下来的n行,输出每一个同学的信息,输出按照学号从小到大的顺序。

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        ArrayList<String> strings = new ArrayList<String>();
        int inNumber = sc.nextInt();
        if (inNumber <= 0||inNumber>=10000){
            System.exit(0);
        }
        else {
            String s = sc.nextLine();
            for (int z = 0; z < inNumber; z++) {
                s = sc.nextLine();
                if (z==0) {
                    strings.add(s);
                }
                else {
                    int mark = 1;
                    for (int check = 0 ; check < strings.size() ; check++){
                        if (s.matches(strings.get(check))){
                            mark = 0 ;
                            break;
                        }
                    }
                    if (mark==1) {
                        strings.add(s);
                    }
                }
            }


            for (int i = 0 ; i < strings.size()-1 ; i++){
                for (int j = i+1 ; j < strings.size();j++){
                    String s1;
                    if (Integer.parseInt(strings.get(i).substring(0,4))>Integer.parseInt(strings.get(j).substring(0,4))){
                        s1 = strings.get(i);
                        strings.set(i,strings.get(j));
                        strings.set(j,s1);
                    }
                }
            }
            System.out.println(strings.size());
            for (int y = 0 ; y < strings.size() ; y++){
                if (y==strings.size()-1)
                    System.out.print(strings.get(y));
                else
                    System.out.println(strings.get(y));
            }
        }
    }
}

 

 

7-3 阅读程序,按照题目需求修改程序

功能需求:
使用集合存储3个员工的信息(有序);
通过迭代器依次找出所有的员工。

提示:学生复制以下代码到编程区,并按需求进行调试修改。
// 1、导入相关包

//定义员工类
class Employee {

private String name;
private int age;

public Employee() {
super();
}

public Employee(String name, int age) {
super();
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

//主函数
public class Main {

public static void main(String[] args) {
// 1、创建有序集合对象
Collection c ;

// 创建3个员工元素对象
for (int i = 0; i < 3; i++) {
Scanner sc = new Scanner(System.in);
String employeeName = sc.nextLine();
int employeeAge = sc.nextInt();

Employee employee = new Employee(employeeName, employeeAge);
c.add(employee);
}

// 2、创建迭代器遍历集合
Iterator it;

//3、遍历
while (it.hasnext) {

//4、集合中对象未知,向下转型
Employee e = it.next();

System.out.println(e.getName() + "---" + e.getAge());
}
}

}

 

import java.util.Collection;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Iterator;
class Employee {
 
    private String name;
    private int age;
 
    public Employee() {
        super();
    }
 
    public Employee(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
}

public class Main {
 
    public static void main(String[] args) {
            Collection c = new ArrayList<Employee>();
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < 3; i++) {
            String employeeName = sc.next();
            int employeeAge = sc.nextInt();
            Employee employee = new Employee(employeeName, employeeAge);
            c.add(employee);
        }
                Iterator it = c.iterator();
            Employee e = (Employee)it.next();
                while (it.hasNext()) {
                    
                    System.out.println(e.getName() + "---" + e.getAge());
                }
    }
}

 

7-1 电信计费系列3-短信计费

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

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

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

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

import java.util.ArrayList;
import java.util.Scanner;
import java.text.DecimalFormat;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        String mq=sc.nextLine();
        ArrayList<User> Users=new ArrayList<User>();
        DecimalFormat df = new DecimalFormat("0.00");
        User user;
        Xiaoxi xiaoxi;
        String nr;
        String hm2;
        while(!mq.equals("end")) {
            
        if(mq.matches("u-1[0-9]{10} 3")) {
            user=new User();
            user.number=mq.substring(2,13);
            Users.add(user);
            }

        else if(mq.matches("m-1[0-9]{10} 1[0-9]{10} [a-z A-Z 0-9,.]+")) {
                hm2=mq.substring(2,13);
                for(User xd: Users) {
                    if(hm2.equals(xd.number)) {
                        xiaoxi=new Xiaoxi();
                        xiaoxi.number1=mq.substring(2,13);
                        xiaoxi.number2=mq.substring(14,25);
                        nr=mq.substring(26);
                        xiaoxi.isneirong=nr;
                        if(Xiaoxi.isduanxin(nr)) {
                            for(User a:Users) {
                                if(a.number.equals(xiaoxi.number1))
                                    a.All.add(xiaoxi);
                            }
                        }
                    }
             }
                
                
           }
            else
                {}
            mq=sc.nextLine();
         }
        int sum=0;
        for(User a:Users) {
            for(Xiaoxi b:a.All) {
                double n1=b.isneirong.length()/10.0;
                int n2=(int) n1;
                if(n1-n2>0)    n2++;
                    sum+=n2;
            }
            if(sum>5)
                a.buy+=0.7+(sum-5)*0.3;
            else if(sum>3)
                a.buy+=0.3+(sum-3)*0.2;
            else
                a.buy+=sum*0.1;
            a.balance-=a.buy;
            
            sum=0;
        }
        Users.sort(new Sort_length());
        for(User a:Users) {
            System.out.println(a.number+" "+Double.valueOf(df.format(a.buy))+" "+Double.valueOf(df.format(a.balance)));
        }
    }
}

class Sort_length implements Comparator<User>{
    public int compare(User a,User b) {
        return a.number.compareTo(b.number);
    }
}

class Number{
    public static boolean isdianhua(String haoma) {
        if(haoma.matches("u-1[0-9]{10} 3")) {
            return true;
        }
        return false;
    }
    
}
class Xiaoxi{
    public String isneirong;
    String number1;
    String number2;
    
    public static boolean isduanxin(String xinxi) {
    if(xinxi.matches("[0-9 a-z A-Z,.]+")) {
        return true;
    }
    return false;
    }
}
class User{
    String number;
    double balance=100;
    double buy=0;
    ArrayList<Xiaoxi> All = new  ArrayList<Xiaoxi>();
    
}

 

 

 

3.采坑心得:主要还是对题目看着很复杂,所以有点不是很自信,容易被绕晕。在运用SimpleDateFormat类时不是很懂,在这个地方花费了许多的时间来处理这个点。再则就是,输入时的正则表达式总有情况没有考虑进去,总是在这个点上拿不了全分。

4.改进建议:其实在计费方法少的时候可以不用计费规则来处理。比如短信计费,只有一种计费方法。这样的话其实可以减少数据,减少时间和复杂度。

5.总结:学到了许多的新知识,新的处理方法,新的考虑角度。深刻理解了什么叫做真正的面对对象来解决问题,我觉得这点是最重要的。也认识到自己的主动与自学能力的不足。建议:希望的题目难度少一点,难度梯度小一点,时间长一点。最好在每一次作业后,可以把答案发在群里。

 

标签:return,String,double,ArrayList,BLOG,new,public
From: https://www.cnblogs.com/ChestnutJim/p/16960335.html

相关文章

  • BLOG-3
    前言:在上一个月的课程学习中,我吸收掌握了很多具有拓展性、延申性的知识,其中包含类与对象的构造、组成,以及在封装、继承、多态三原则优化后的代码结构基础上,进行抽象类......
  • BLOG-3
                                                         ......
  • blog_03
    第三次博客作业目录第三次博客作业1.前言2.设计与分析(1)题目集67-1电信计费系列1-座机计费(2)题目集77-1电信计费系列2-手机+座机计费(3)题目集87-1电信计费系列3-......
  • OO第三次java学习blog
    第三次java学习blog第三次java学习blog前言涉及知识点:题量与难度设计与分析电信计费1电信计费2电信计费3踩坑心得改进建议总结前言涉及知识点:1.......
  • Blog3-电信计费系列题目集
    前言电信计费系列题目虽然难度相对于多边形系列有所下降,但涉及知识点很广,主要如下:1、容器的使用2、抛出异常3、抽象类4、继承与多态5、正则表达式6、类和对象设计......
  • BLOG-3
    一、前言难度分析:近三次大作业难度相较与前面多边形难度有所下降,手机计费比座机计费大,而最后的短信计费难度则又降低。题量:题量适中知识点:继承多态容器,正则表达式等......
  • 基于yolo进行目标检测的实验和研究【BLOG】
          根据我接触到的项目经验来看,需要我们进行检测的不是自然场景下的任意物体,而是特定场景下一类物体。典型的就是钢管识别,这些照片一般都是在厂区里面拍的、......
  • 介绍一个JAVA的开源blog--APACHE ROLLER
    开源的BLOG系统,最推荐的依然是PHP的,非常多选择,JAVA的可选择的不多,但今天居然发现一个APACHE的顶级项目roller,项目地址是​​​http://rolller.......
  • weblogic12版本节点启动报错问题处理
    问题:<Sep12,202211:00:13AMCST><Warning><DeploymentService><BEA-290074><Deploymentserviceservletreceivedfiledownloadrequestforfile"security/Se......
  • 使用cnblog上传markdown文件到博客园
    下载并且安装python3地址:https://www.python.org/安装完以后:下载pycnblog地址:https://github.com/dongfanger/pycnblo将下载的pycnblog工具解压,打开config.yaml......