(1)前言:
10-16周很快就要结束了,这三次电信计费大作业总体比之前的四边形、五边形不要简单太多。主要是考察继承、多态、抽象类等的使用。
而且电信计费的类图都给定的,即总体框架直接给你了,所以才显得没有之前复杂。其中正则表达式这几道题的
重点,格式判断还是主要的。当然对于ArrayList、toString等方法也着重进行了考察。
(2)设计与分析:
7-1 电信计费系列1-座机计费 分数 80 作者 蔡轲 单位 南昌航空大学实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
输入格式:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码除区号外由是7-8位数字组成。
本题只考虑计费类型0-座机计费,电信系列2、3题会逐步增加计费类型。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
注意:
本题非法输入只做格式非法的判断,不做内容是否合理的判断(时间除外,否则无法计算),比如:
1、输入的所有通讯信息均认为是同一个月的通讯信息,不做日期是否在同一个月还是多个月的判定,直接将通讯费用累加,因此月租只计算一次。
2、记录中如果同一电话号码的多条通话记录时间出现重合,这种情况也不做判断,直接 计算每条记录的费用并累加。
3、用户区号不为南昌市的区号也作为正常用户处理。
输出格式:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,
单位元)。假设每个用户初始余额是100元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
建议类图:
参见图1、2、3,可根据理解自行调整:
图1
图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。
ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。
UserRecords是用户记录类,保存用户各种通话、短信的记录,
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。
图2
图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。
CallRecord(通话记录类)包含属性:
通话的起始、结束时间以及
拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。
区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。
图3
图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList<CallRecord> callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是
座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。
(提示:可以从UserRecords类中获取各种类型的callRecords)。
后续扩展说明:
后续题目集将增加手机用户,手机用户的计费方式中除了与座机计费类似的主叫通话费之外,还包含市外接听电话的漫游费以及发短信的费用。在本题的设计时可统一考虑。
通话记录中,手机需要额外记录拨打/接听的地点的区号,比如:
座机打手机:t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
短信的格式:m-主叫号码,接收号码,短信内容
m-18907910010 13305862264 welcome to jiangxi
m-13305862264 18907910010 thank you
输入样例:
在这里给出一组输入。例如:
u-079186300001 0
t-079186300001 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:25
end
输出样例:
在这里给出相应的输出。例如:
079186300001 3.0 77.0
其余参考样例详见附件,未尽事宜以附件样例为准:
源码:
(点加号)
import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main{ //控制小数点 public static void main(String[] args){ //Point p1=new Point(); Scanner input=new Scanner(System.in); String s=input.nextLine();//输入 Show outputtool = new Show(); Input inputdeal = new Input(); ArrayList<User> users = new ArrayList<>(); while (!s.equals("end")) { if (1 == inputdeal.check(s)) { inputdeal.writeUser(users, s); } else if (2 == inputdeal.check(s)) { inputdeal.writeRecord(users, s); } s= input.nextLine(); } users.sort(new Comparator<User>() { public int compare(User u1, User u2) { if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) { return 1; } else { return -1; } } }); for (User u : users) { System.out.print(u.getNumber() + " "); outputtool.output(u.calCost()); System.out.print(" "); outputtool.output(u.calBalance()); System.out.println(); } } } class Input{ public int check(String s){ String[] ss=s.split(" "); if(ss.length==2){ if(ss[0].matches("^u-[0-9]{11,13}$")){ if(Integer.parseInt(ss[1])>=0){ if(Integer.parseInt(ss[1])<=2) return 1; } } }else if(ss.length==6){ if (validate(ss[2])) if (validate(ss[4])) if (validatet(ss[3])) if (validatet(ss[5])) if (ss[0].matches("[t]-0791\\d{7,8}")) { if (ss[1].matches(".\\d{9,11}")) return 2; } } return 0; } private boolean validate(String s) { Pattern p=Pattern.compile("\\d{4}+\\.\\d{1,2}+\\.\\d{1,2}+"); Matcher m = p.matcher(s); if (!m.matches()) return false; // 得到年月日 String[] array = s.split("\\."); int year = Integer.valueOf(array[0]); int month = Integer.valueOf(array[1]); int day = Integer.valueOf(array[2]); if (month < 1 || month > 12) { return false; } int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (isLeapYear(year)) { monthLengths[2] = 29; } else { monthLengths[2] = 28; } int monthLength = monthLengths[month]; if (day < 1 || day > monthLength) { return false; } return true; } /** 是否是闰年 */ private static boolean isLeapYear(int year) { return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); } public boolean judge(String input) { return false; } public void writeUser(ArrayList<User> users, String input) { User usernew = new User(); String[] inputs = input.split(" "); String num = inputs[0].substring(2); for (User i : users) { if (i.getNumber().equals(num)) { return; } } usernew.setNumber(num); int mode = Integer.parseInt(inputs[1]); if (mode == 0) { usernew.setChargeMode(new LandlinePhoneCharging()); } users.add(usernew); } public void writeRecord(ArrayList<User> users, String input) { String[] inputs = input.split(" "); inputs[0] = inputs[0].replace("t-", ""); User callu = null, answeru = null; CallRecord callrecord = new CallRecord(inputs); for (User i : users) { if (i.getNumber().equals(inputs[0])) { callu = i; } if (i.getNumber().equals(inputs[1])) { answeru = i; } if (callu != null && answeru != null) { break; } } if (callu != null) { if (callrecord.getCallType() == 1) { callu.getUserRecords().addCallingInCityRecords(callrecord); } else if (callrecord.getCallType() == 2) { callu.getUserRecords().addCallingInProvinceRecords(callrecord); } else { callu.getUserRecords().addCallingInLandRecords(callrecord); } } if (answeru != null) { if (callrecord.getCallType() == 1) { answeru.getUserRecords().addAnswerInCityRecords(callrecord); } else if (callrecord.getCallType() == 2) { answeru.getUserRecords().aadAnswerInProvinceRecords(callrecord); } else { answeru.getUserRecords().addAnswerInLandRecords(callrecord); } } } private boolean validatet(String s) { Pattern p=Pattern.compile("^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"); Matcher m = p.matcher(s); if (!m.matches()) return false; return true; } } class Show { public void output(double out) { // java.text.DecimalFormat df=new java.text.DecimalFormat("#.#"); // String a=df.format(out); // System.out.print(a); BigDecimal numb = new BigDecimal(out); out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); System.out.print(out); } } abstract class ChargeMode { protected ArrayList<ChargeRule> chargeRules = new ArrayList<>(); public abstract double calCost(UserRecords userRecords); public abstract double getMonthlyRent(); public ArrayList<ChargeRule> getChargeRules() { return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } } class User{ private UserRecords userRecords = new UserRecords(); private double balance = 100; private ChargeMode chargeMode; private String number; public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public double calCost(){ return chargeMode.calCost(userRecords); } public double calBalance(){ return balance-chargeMode.getMonthlyRent()-chargeMode.calCost(userRecords); } public UserRecords getUserRecords(){ return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } } abstract class CommunicationRecord { protected String callingNumber; protected String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumbe() { return answerNumber; } public void setAnswerNumbe(String answerNumbe) { this.answerNumber = answerNumbe; } } class MessageRecord extends CommunicationRecord { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } abstract class ChargeRule { abstract public double calCost(UserRecords userRecords); } abstract class CallChargeRule extends ChargeRule { } class LandPhoneInCityRule extends CallChargeRule { public double calCost(UserRecords userRecords) { double sumCost = 0; for (CallRecord call : userRecords.getCallingInCityRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } sumCost += distanceM * 0.1; } return sumCost; } } class LandPhoneInlandRule extends CallChargeRule { public double calCost(UserRecords userRecords) { double sumCost = 0; for (CallRecord call : userRecords.getCallingInLandRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } sumCost += distanceM * 0.6; } return sumCost; } } class LandPhoneInProvinceRule extends CallChargeRule { public double calCost(UserRecords userRecords) { double sumCost = 0; for (CallRecord call : userRecords.getCallingInProvinceRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } sumCost += distanceM * 0.3; } return sumCost; } } class LandlinePhoneCharging extends ChargeMode { private double monthlyRent = 20; public LandlinePhoneCharging() { super(); chargeRules.add(new LandPhoneInCityRule()); chargeRules.add(new LandPhoneInProvinceRule()); chargeRules.add(new LandPhoneInlandRule()); } public double calCost(UserRecords userRecords) { double sumCost = 0; for (ChargeRule rule : chargeRules) { sumCost += rule.calCost(userRecords); } return sumCost; } public double getMonthlyRent() { return monthlyRent; } } class CallRecord extends CommunicationRecord { private Date startTime; private Date endTime; private String callingAddressAreaCode; private String answerAddressAreaCode; public int getCallType() { if (callingAddressAreaCode.equals(answerAddressAreaCode)) { return 1; } if (callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701")) { if (answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701")) { return 2; } } return 3; } public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { super(); this.startTime = startTime; this.endTime = endTime; this.callingAddressAreaCode = callingAddressAreaCode; this.answerAddressAreaCode = answerAddressAreaCode; } public CallRecord(String[] inputs) { super(); if (inputs[0].length() == 10) { callingAddressAreaCode = inputs[0].substring(0, 3); } else { callingAddressAreaCode = inputs[0].substring(0, 4); } if (inputs[1].length() == 10) { answerAddressAreaCode = inputs[1].substring(0, 3); } else { answerAddressAreaCode = inputs[1].substring(0, 4); } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault()); try { startTime = simpleDateFormat.parse(inputs[2] + " " + inputs[3]); endTime = simpleDateFormat.parse(inputs[4] + " " + inputs[5]); } catch (ParseException e) { } } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } class Point{ public double x, y; public Point(){ this.x = 0; this.y = 0; } public Point(double a,double b){ this.x = a; this.y = b; } public void print(){ String x = String.format("%.6f",this.x); String y = String.format("%.6f",this.y); x = x.replaceAll("0+?$", ""); y = y.replaceAll("0+?$", ""); System.out.printf("(%s , %s)\n",this.x,this.y); } //两点坐标相同 public boolean isSameTo(Point a){ return (this.x == a.x)&&(this.y == a.y); } //两点距离 public double disToPoint(Point another){ return Math.sqrt(Math.pow(this.x-another.x,2) + Math.pow(this.y-another.y,2)); } } class UserRecords{ private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); public void addCallingInCityRecords(CallRecord callRecord) { callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecords(CallRecord callRecord) { callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecords(CallRecord callRecord) { callingInLandRecords.add(callRecord); } public void addAnswerInCityRecords(CallRecord callRecord) { answerInCityRecords.add(callRecord); } public void aadAnswerInProvinceRecords(CallRecord callRecord) { answerInProvinceRecords.add(callRecord); } public void addAnswerInLandRecords(CallRecord callRecord) { answerInLandRecords.add(callRecord); } public void addSendMessageRecords(MessageRecord callRecord) { sendMessageRecords.add(callRecord); } public void addReceiveMessageRecords(MessageRecord callRecord) { receiveMessageRecords.add(callRecord); } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) { this.callingInCityRecords = callingInCityRecords; } public ArrayList<CallRecord> getCallingInProvinceRecords() { return callingInProvinceRecords; } public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) { this.callingInProvinceRecords = callingInProvinceRecords; } public ArrayList<CallRecord> getCallingInLandRecords() { return callingInLandRecords; } public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) { this.callingInLandRecords = callingInLandRecords; } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) { this.answerInCityRecords = answerInCityRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) { this.answerInProvinceRecords = answerInProvinceRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) { this.answerInLandRecords = answerInLandRecords; } public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) { this.sendMessageRecords = sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) { this.receiveMessageRecords = receiveMessageRecords; } }View Code
分析:
PTA头一次做这种题,相对于前两次的四边形和五边形大作业要简单的多。因为题目要求中给出了相应的类图,设计的总体框架已经给出,
根据类图就可以敲出相应代码,可谓完成了大部分。本题主要围绕如何判断输入信息的格式,以及判断后是如何将信息存储进记录。
然后由上图可知本题Max complexity(最大复杂度)过大,原因是设计中if-else语句用的太多。
7-1 电信计费系列2-手机+座机计费 分数 80 作者 蔡轲 单位 南昌航空大学
实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
1、针对市内座机用户采用的计费方式(与电信计费系列1内容相同):
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
假设本市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
2、针对手机用户采用实时计费方式:
月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟;
注:被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
输入:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,含手机和座机用户
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题在电信计费系列1基础上增加类型1-手机实时计费。
手机设置0或者座机设置成1,此种错误可不做判断。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
输入格式增加手机接打电话以及收发短信的格式,手机接打电话的信息除了号码之外需要额外记录拨打/接听的地点的区号,比如:
座机打手机:
t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:
t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。
建议类图:
参见图1、2、3:
图1
图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。
ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。
UserRecords是用户记录类,保存用户各种通话、短信的记录,
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。
图2
图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。CallRecord(通话记录类)包含属性:
通话的起始、结束时间以及
拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。
区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。
图3
图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList<CallRecord> callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。
SendMessageRule是发送短信的计费规则类,用于计算发送短信的费用。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。
(提示:可以从UserRecords类中获取各种类型的callRecords)。
注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。
输入样例:
在这里给出一组输入。例如:
u-13811111111 1
t-13811111111 0791 13811111110 020 2022.1.3 08:00:00 2022.1.3 08:09:20
end
输出样例:
在这里给出相应的输出。例如:
13811111111 3.0 82.0
更多内容详见附件:
源码:
(点加号)
1 import java.math.BigDecimal; 2 import java.text.ParseException; 3 import java.text.SimpleDateFormat; 4 import java.util.*; 5 import java.util.regex.Matcher; 6 import java.util.regex.Pattern; 7 8 9 abstract class ChargeMode { 10 protected ArrayList<ChargeRule> chargeRules = new ArrayList<>(); 11 12 public abstract double calCost(UserRecords userRecords); 13 14 public abstract double getMonthlyRent(); 15 16 public ArrayList<ChargeRule> getChargeRules() { 17 return chargeRules; 18 } 19 20 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 21 this.chargeRules = chargeRules; 22 } 23 } 24 25 class UserRecords { 26 27 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 28 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 29 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); 30 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); 31 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); 32 private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); 33 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); 34 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); 35 36 public void addCallingInCityRecords(CallRecord callRecord) { 37 callingInCityRecords.add(callRecord); 38 } 39 40 public void addCallingInProvinceRecords(CallRecord callRecord) { 41 callingInProvinceRecords.add(callRecord); 42 } 43 44 public void addCallingInLandRecords(CallRecord callRecord) { 45 callingInLandRecords.add(callRecord); 46 } 47 48 public void addAnswerInCityRecords(CallRecord callRecord) { 49 answerInCityRecords.add(callRecord); 50 } 51 52 public void aaddAnswerInProvinceRecords(CallRecord callRecord) { 53 answerInProvinceRecords.add(callRecord); 54 } 55 56 public void addAnswerInLandRecords(CallRecord callRecord) { 57 answerInLandRecords.add(callRecord); 58 } 59 60 public void addSendMessageRecords(MessageRecord callRecord) { 61 sendMessageRecords.add(callRecord); 62 } 63 64 public void addReceiveMessageRecords(MessageRecord callRecord) { 65 receiveMessageRecords.add(callRecord); 66 } 67 68 public ArrayList<CallRecord> getCallingInCityRecords() { 69 return callingInCityRecords; 70 } 71 72 public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) { 73 this.callingInCityRecords = callingInCityRecords; 74 } 75 76 public ArrayList<CallRecord> getCallingInProvinceRecords() { 77 return callingInProvinceRecords; 78 } 79 80 public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) { 81 this.callingInProvinceRecords = callingInProvinceRecords; 82 } 83 84 public ArrayList<CallRecord> getCallingInLandRecords() { 85 return callingInLandRecords; 86 } 87 88 public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) { 89 this.callingInLandRecords = callingInLandRecords; 90 } 91 92 public ArrayList<CallRecord> getAnswerInCityRecords() { 93 return answerInCityRecords; 94 } 95 96 public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) { 97 this.answerInCityRecords = answerInCityRecords; 98 } 99 100 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 101 return answerInProvinceRecords; 102 } 103 104 public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) { 105 this.answerInProvinceRecords = answerInProvinceRecords; 106 } 107 108 public ArrayList<CallRecord> getAnswerInLandRecords() { 109 return answerInLandRecords; 110 } 111 112 public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) { 113 this.answerInLandRecords = answerInLandRecords; 114 } 115 116 public ArrayList<MessageRecord> getSendMessageRecords() { 117 return sendMessageRecords; 118 } 119 120 public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) { 121 this.sendMessageRecords = sendMessageRecords; 122 } 123 124 public ArrayList<MessageRecord> getReceiveMessageRecords() { 125 return receiveMessageRecords; 126 } 127 128 public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) { 129 this.receiveMessageRecords = receiveMessageRecords; 130 } 131 132 } 133 class User { 134 135 private UserRecords userRecords = new UserRecords(); 136 private double balance = 100; 137 private ChargeMode chargeMode; 138 private String number; 139 140 public double calCost() { 141 return chargeMode.calCost(userRecords); 142 } 143 144 public double calBalance() { 145 return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords); 146 } 147 148 public UserRecords getUserRecords() { 149 return userRecords; 150 } 151 152 public void setUserRecords(UserRecords userRecords) { 153 this.userRecords = userRecords; 154 } 155 156 public ChargeMode getChargeMode() { 157 return chargeMode; 158 } 159 160 public void setChargeMode(ChargeMode chargeMode) { 161 this.chargeMode = chargeMode; 162 } 163 164 public String getNumber() { 165 return number; 166 } 167 168 public void setNumber(String number) { 169 this.number = number; 170 } 171 172 } 173 174 175 176 abstract class CommunicationRecord { 177 protected String callingNumber; 178 protected String answerNumbe; 179 180 public String getCallingNumber() { 181 return callingNumber; 182 } 183 184 public void setCallingNumber(String callingNumber) { 185 this.callingNumber = callingNumber; 186 } 187 188 public String getAnswerNumbe() { 189 return answerNumbe; 190 } 191 192 public void setAnswerNumbe(String answerNumbe) { 193 this.answerNumbe = answerNumbe; 194 } 195 196 } 197 198 abstract class ChargeRule { 199 200 abstract public double calCost(UserRecords userRecords); 201 202 } 203 204 class CallRecord extends CommunicationRecord { 205 private Date startTime; 206 private Date endTime; 207 private String callingAddressAreaCode; 208 private String answerAddressAreaCode; 209 210 public String getCallType() { 211 String type = ""; 212 if (callingAddressAreaCode.equals("0791")) { 213 type = type.concat("1"); 214 } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) { 215 type = type.concat("2"); 216 } else { 217 type = type.concat("3"); 218 } 219 220 if (answerAddressAreaCode.equals("0791")) { 221 type = type.concat("1"); 222 } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) { 223 type = type.concat("2"); 224 } else { 225 type = type.concat("3"); 226 } 227 228 return type; 229 } 230 231 public CallRecord(String[] inputs) { 232 super(); 233 234 char type = inputs[0].charAt(0); 235 inputs[0] = inputs[0].substring(2); 236 237 String sd = null, st = null, ed = null, et = null; 238 239 if (type == 't') { 240 if (inputs.length == 6) { 241 sd = inputs[2]; 242 st = inputs[3]; 243 ed = inputs[4]; 244 et = inputs[5]; 245 callingAddressAreaCode = inputs[0].substring(0, 4); 246 answerAddressAreaCode = inputs[1].substring(0, 4); 247 } else if (inputs.length == 7) { 248 sd = inputs[3]; 249 st = inputs[4]; 250 ed = inputs[5]; 251 et = inputs[6]; 252 if (inputs[0].charAt(0) != '0') { 253 if (inputs[2].length() == 10) { 254 answerAddressAreaCode = inputs[2].substring(0, 3); 255 } else { 256 answerAddressAreaCode = inputs[2].substring(0, 4); 257 } 258 callingAddressAreaCode = inputs[1]; 259 } else { 260 if (inputs[0].length() == 10) { 261 callingAddressAreaCode = inputs[0].substring(0, 3); 262 } else { 263 callingAddressAreaCode = inputs[0].substring(0, 4); 264 } 265 answerAddressAreaCode = inputs[2]; 266 } 267 } else if (inputs.length == 8) { 268 sd = inputs[4]; 269 st = inputs[5]; 270 ed = inputs[6]; 271 et = inputs[7]; 272 callingAddressAreaCode = inputs[1]; 273 answerAddressAreaCode = inputs[3]; 274 } 275 } else if (type == 'm') { 276 277 } 278 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault()); 279 try { 280 startTime = simpleDateFormat.parse(sd + " " + st); 281 endTime = simpleDateFormat.parse(ed + " " + et); 282 } catch (ParseException e) { 283 } 284 285 } 286 287 public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { 288 super(); 289 this.startTime = startTime; 290 this.endTime = endTime; 291 this.callingAddressAreaCode = callingAddressAreaCode; 292 this.answerAddressAreaCode = answerAddressAreaCode; 293 } 294 295 public Date getStartTime() { 296 return startTime; 297 } 298 299 public void setStartTime(Date startTime) { 300 this.startTime = startTime; 301 } 302 303 public Date getEndTime() { 304 return endTime; 305 } 306 307 public void setEndTime(Date endTime) { 308 this.endTime = endTime; 309 } 310 311 public String getCallingAddressAreaCode() { 312 return callingAddressAreaCode; 313 } 314 315 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 316 this.callingAddressAreaCode = callingAddressAreaCode; 317 } 318 319 public String getAnswerAddressAreaCode() { 320 return answerAddressAreaCode; 321 } 322 323 public void setAnswerAddressAreaCode(String answerAddressAreaCode) { 324 this.answerAddressAreaCode = answerAddressAreaCode; 325 } 326 } 327 328 abstract class CallChargeRule extends ChargeRule { 329 330 } 331 class Point{ 332 public double x, y; 333 334 public Point(){ 335 this.x = 0; 336 this.y = 0; 337 } 338 public Point(double a,double b){ 339 this.x = a; 340 this.y = b; 341 } 342 343 public void print(){ 344 String x = String.format("%.6f",this.x); 345 String y = String.format("%.6f",this.y); 346 x = x.replaceAll("0+?$", ""); 347 y = y.replaceAll("0+?$", ""); 348 System.out.printf("(%s , %s)\n",this.x,this.y); 349 } 350 351 //两点坐标相同 352 public boolean isSameTo(Point a){ 353 return (this.x == a.x)&&(this.y == a.y); 354 } 355 //两点距离 356 public double disToPoint(Point another){ 357 return Math.sqrt(Math.pow(this.x-another.x,2) + Math.pow(this.y-another.y,2)); 358 } 359 } 360 class LandlinePhoneCharging extends ChargeMode { 361 362 private double monthlyRent = 20; 363 364 public LandlinePhoneCharging() { 365 super(); 366 chargeRules.add(new LandPhoneInCityRule()); 367 chargeRules.add(new LandPhoneInProvinceRule()); 368 chargeRules.add(new LandPhoneInlandRule()); 369 } 370 371 @Override 372 public double calCost(UserRecords userRecords) { 373 double sumCost = 0; 374 for (ChargeRule rule : chargeRules) { 375 sumCost += rule.calCost(userRecords); 376 } 377 return sumCost; 378 } 379 380 @Override 381 public double getMonthlyRent() { 382 return monthlyRent; 383 } 384 385 } 386 387 class MobilePhoneCharging extends ChargeMode { 388 389 private double monthlyRent = 15; 390 391 public MobilePhoneCharging() { 392 super(); 393 chargeRules.add(new MobilePhoneInCityRule()); 394 chargeRules.add(new MobilePhoneInProvinceRule()); 395 chargeRules.add(new MobilePhoneInlandRule()); 396 } 397 398 @Override 399 public double calCost(UserRecords userRecords) { 400 double sumCost = 0; 401 for (ChargeRule rule : chargeRules) { 402 sumCost += rule.calCost(userRecords); 403 } 404 return sumCost; 405 } 406 407 @Override 408 public double getMonthlyRent() { 409 return monthlyRent; 410 } 411 412 } 413 414 class LandPhoneInCityRule extends CallChargeRule { 415 416 @Override 417 public double calCost(UserRecords userRecords) { 418 double sumCost = 0; 419 for (CallRecord call : userRecords.getCallingInCityRecords()) { 420 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 421 if (distanceS < 0) { 422 continue; 423 } 424 double distanceM = (int) distanceS / 60; 425 if (distanceS % 60 != 0) { 426 distanceM += 1; 427 } 428 if (call.getCallType().equals("11")) { 429 sumCost += distanceM * 0.1; 430 } else if (call.getCallType().equals("12")) { 431 sumCost += distanceM * 0.3; 432 } else if (call.getCallType().equals("13")) { 433 sumCost += distanceM * 0.6; 434 } 435 } 436 return sumCost; 437 } 438 439 } 440 441 class LandPhoneInlandRule extends CallChargeRule { 442 443 @Override 444 public double calCost(UserRecords userRecords) { 445 double sumCost = 0; 446 for (CallRecord call : userRecords.getCallingInLandRecords()) { 447 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 448 if (distanceS < 0) { 449 continue; 450 } 451 double distanceM = (int) distanceS / 60; 452 if (distanceS % 60 != 0) { 453 distanceM += 1; 454 } 455 sumCost += distanceM * 0.6; 456 } 457 return sumCost; 458 } 459 460 } 461 462 class LandPhoneInProvinceRule extends CallChargeRule { 463 464 @Override 465 public double calCost(UserRecords userRecords) { 466 double sumCost = 0; 467 for (CallRecord call : userRecords.getCallingInProvinceRecords()) { 468 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 469 if (distanceS < 0) { 470 continue; 471 } 472 double distanceM = (int) distanceS / 60; 473 if (distanceS % 60 != 0) { 474 distanceM += 1; 475 } 476 sumCost += distanceM * 0.3; 477 } 478 return sumCost; 479 } 480 481 } 482 483 class MobilePhoneInCityRule extends CallChargeRule { 484 485 @Override 486 public double calCost(UserRecords userRecords) { 487 double sumCost = 0; 488 for (CallRecord call : userRecords.getCallingInCityRecords()) { 489 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 490 if (distanceS < 0) { 491 continue; 492 } 493 double distanceM = (int) distanceS / 60; 494 if (distanceS % 60 != 0) { 495 distanceM += 1; 496 } 497 if (call.getCallType().equals("11")) { 498 sumCost += distanceM * 0.1; 499 } else if (call.getCallType().equals("12")) { 500 sumCost += distanceM * 0.2; 501 } else if (call.getCallType().equals("13")) { 502 sumCost += distanceM * 0.3; 503 } 504 505 } 506 return sumCost; 507 } 508 509 } 510 511 class MobilePhoneInlandRule extends CallChargeRule { 512 513 @Override 514 public double calCost(UserRecords userRecords) { 515 double sumCost = 0; 516 for (CallRecord call : userRecords.getCallingInLandRecords()) { 517 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 518 if (distanceS < 0) { 519 continue; 520 } 521 double distanceM = (int) distanceS / 60; 522 if (distanceS % 60 != 0) { 523 distanceM += 1; 524 } 525 sumCost += distanceM * 0.6; 526 } 527 for (CallRecord call : userRecords.getAnswerInLandRecords()) { 528 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 529 if (distanceS < 0) { 530 continue; 531 } 532 double distanceM = (int) distanceS / 60; 533 if (distanceS % 60 != 0) { 534 distanceM += 1; 535 } 536 sumCost += distanceM * 0.3; 537 } 538 return sumCost; 539 } 540 541 } 542 543 class MobilePhoneInProvinceRule extends CallChargeRule { 544 545 @Override 546 public double calCost(UserRecords userRecords) { 547 double sumCost = 0; 548 for (CallRecord call : userRecords.getCallingInProvinceRecords()) { 549 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 550 if (distanceS < 0) { 551 continue; 552 } 553 double distanceM = (int) distanceS / 60; 554 if (distanceS % 60 != 0) { 555 distanceM += 1; 556 } 557 if (call.getCallType().equals("21")) { 558 sumCost += distanceM * 0.3; 559 } else if (call.getCallType().equals("22")) { 560 sumCost += distanceM * 0.3; 561 } else if (call.getCallType().equals("23")) { 562 sumCost += distanceM * 0.3; 563 } 564 } 565 return sumCost; 566 } 567 568 } 569 570 class MessageRecord extends CommunicationRecord { 571 572 private String message; 573 574 public String getMessage() { 575 return message; 576 } 577 578 public void setMessage(String message) { 579 this.message = message; 580 } 581 } 582 583 584 class Input { 585 586 public int check(String input) { 587 if (input.matches("[u]-0791\\d{7,8}\\s[0]") || input.matches("[u]-1\\d{10}\\s[1]")) { 588 return 1; 589 } else if (input.matches("(([t]-0791\\d{7,8}\\s" + "0\\d{9,11}\\s)|" 590 + "([t]-0791\\d{7,8}\\s" + "1\\d{10}\\s" + "0[0-9]{2,3}\\s)|" 591 + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "0[0-9]{9,11}\\s)|" 592 + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s))" 593 594 + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?" 595 + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" 596 + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" 597 + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s" 598 + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.(" 599 + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" 600 + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" 601 + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])")) { 602 return 2; 603 } 604 return 0; 605 } 606 607 @SuppressWarnings("unused") 608 private boolean validatet(String string) { 609 if (!string.matches("^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$")) { 610 return false; 611 } 612 return true; 613 } 614 615 public static boolean validate(String dateString) { 616 // 使用正则表达式 测试 字符 符合 dddd.dd.dd 的格式(d表示数字) 617 Pattern p = Pattern.compile("\\d{4}+[\\.]\\d{1,2}+[\\.]\\d{1,2}+"); 618 Matcher m = p.matcher(dateString); 619 if (!m.matches()) { 620 return false; 621 } 622 623 // 得到年月日 624 String[] array = dateString.split("\\."); 625 int year = Integer.valueOf(array[0]); 626 int month = Integer.valueOf(array[1]); 627 int day = Integer.valueOf(array[2]); 628 629 if (month < 1 || month > 12) { 630 return false; 631 } 632 int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 633 if (isLeapYear(year)) { 634 monthLengths[2] = 29; 635 } else { 636 monthLengths[2] = 28; 637 } 638 int monthLength = monthLengths[month]; 639 if (day < 1 || day > monthLength) { 640 return false; 641 } 642 return true; 643 } 644 645 /** 是否是闰年 */ 646 private static boolean isLeapYear(int year) { 647 return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); 648 } 649 650 public boolean judge(String input) { 651 652 return false; 653 } 654 655 public void writeUser(ArrayList<User> users, String input) { 656 User usernew = new User(); 657 String[] inputs = input.split(" "); 658 String num = inputs[0].substring(2); 659 for (User i : users) { 660 if (i.getNumber().equals(num)) { 661 return; 662 } 663 } 664 usernew.setNumber(num); 665 int mode = Integer.parseInt(inputs[1]); 666 if (mode == 0) { 667 usernew.setChargeMode(new LandlinePhoneCharging()); 668 } else if (mode == 1) { 669 usernew.setChargeMode(new MobilePhoneCharging()); 670 } 671 users.add(usernew); 672 } 673 674 public void writeRecord(ArrayList<User> users, String input) { 675 String[] inputs = input.split(" "); 676 677 User callu = null, answeru = null; 678 CallRecord callrecord = new CallRecord(inputs); 679 680 if (input.charAt(0) == 't') { 681 String out = inputs[0]; 682 String in = ""; 683 if (inputs.length == 6) { 684 in = inputs[1]; 685 } else if (inputs.length == 7) { 686 in = inputs[1]; 687 } else if (inputs.length == 8) { 688 in = inputs[2]; 689 } 690 691 for (User i : users) { 692 if (i.getNumber().equals(out)) { 693 callu = i; 694 } 695 if (i.getNumber().equals(in)) { 696 answeru = i; 697 } 698 if (callu != null && answeru != null) { 699 break; 700 } 701 } 702 703 if (callu != null) { 704 if (callrecord.getCallType().matches("^1[1-3]$")) { 705 callu.getUserRecords().addCallingInCityRecords(callrecord); 706 } else if (callrecord.getCallType().matches("^2[1-3]$")) { 707 callu.getUserRecords().addCallingInProvinceRecords(callrecord); 708 } else { 709 callu.getUserRecords().addCallingInLandRecords(callrecord); 710 } 711 } 712 713 if (answeru != null) { 714 if (callrecord.getCallType().matches("^[1-3]1$")) { 715 answeru.getUserRecords().addAnswerInCityRecords(callrecord); 716 } else if (callrecord.getCallType().matches("^[1-3]2$")) { 717 answeru.getUserRecords().aaddAnswerInProvinceRecords(callrecord); 718 } else { 719 answeru.getUserRecords().addAnswerInLandRecords(callrecord); 720 } 721 } 722 } else if (input.charAt(0) == 'm') { 723 724 } 725 726 } 727 728 } 729 class show { 730 731 @SuppressWarnings("deprecation") 732 public void output(double out) { 733 BigDecimal numb = new BigDecimal(out); 734 out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); 735 System.out.print(out); 736 } 737 } 738 public class Main { 739 740 public static void main(String[] args) { 741 742 show outputtool = new show(); 743 744 Input inputdeal = new Input(); 745 746 ArrayList<User> users = new ArrayList<>(); 747 748 Scanner in = new Scanner(System.in); 749 750 String input = in.nextLine(); 751 752 while (!input.equals("end")) { 753 if (1 == inputdeal.check(input)) { 754 inputdeal.writeUser(users, input); 755 } else if (2 == inputdeal.check(input)) { 756 inputdeal.writeRecord(users, input); 757 } 758 input = in.nextLine(); 759 } 760 761 users.sort(new Comparator<User>() { 762 763 @Override 764 public int compare(User u1, User u2) { 765 if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') { 766 return -1; 767 } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') { 768 return 1; 769 } 770 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) { 771 return 1; 772 } else { 773 return -1; 774 } 775 } 776 }); 777 778 for (User u : users) { 779 System.out.print(u.getNumber() + " "); 780 outputtool.output(u.calCost()); 781 System.out.print(" "); 782 outputtool.output(u.calBalance()); 783 System.out.println(); 784 785 } 786 787 } 788 789 }View Code
分析:
这道题相比于上道题,这道题的难点在于这个话费计算不到要考虑市内、省内、国内这种区域性问题,还要考虑你是接听方还是拨打方
以及是座机还是手机打电话,每一种计费方式都不同,都要变化,难度加大。
由上图分析可知,又是Max complexity过大,嵌套语句太多了,不用说,这几道题我都是if-else语句过多。
7-1 电信计费系列3-短信计费 分数 50 作者 蔡轲 单位 南昌航空大学
实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
1、接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。
2、如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。
输入:
输入信息包括两种类型
1、逐行输入南昌市手机用户开户的信息,每行一个用户。
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐 3-手机短信计费)
例如:u-13305862264 3
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题只针对类型3-手机短信计费。
2、逐行输入本月某些用户的短信信息,短信的格式:
m-主叫号码,接收号码,短信内容 (短信内容只能由数字、字母、空格、英文逗号、英文句号组成)
m-18907910010 13305862264 welcome to jiangxi.
m-13305862264 18907910010 thank you.
注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出:
根据输入的详细短信信息,计算所有已开户的用户的当月短信费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码、自己给自己打电话等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。
本题只考虑短信计费,不考虑通信费用以及月租费。
建议类图:
参见图1、2、3:
图1
图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。
ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。
UserRecords是用户记录类,保存用户各种通话、短信的记录,
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。
图2
图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。
图3
图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。
SendMessageRule是发送短信的计费规则类,用于计算发送短信的费用。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。
(提示:可以从UserRecords类中获取各种类型的callRecords)。
注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。
输入样例:
在这里给出一组输入。例如:
u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaaaaaaaaaaaaa
end
输出样例:
在这里给出相应的输出。例如:
18907910010 0.3 99.7
### 输入样例1:
在这里给出一组输入。例如:
u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaa
m-18907910010 13305862264 aaaaaaa.
m-18907910010 13305862264 bb,bbbb
end
输出样例1:
在这里给出相应的输出。例如:
18907910010 0.5 99.5
源码:
(点加号)
1 import java.math.BigDecimal; 2 import java.text.ParseException; 3 import java.text.SimpleDateFormat; 4 import java.util.*; 5 6 public class Main { 7 8 public static void main(String[] args) { 9 Scanner in = new Scanner(System.in); 10 Input input = new Input(); 11 Output output = new Output(); 12 ArrayList<User> users = new ArrayList<>(); 13 String input1 = in.nextLine(); 14 while (!input1.equals("end")) { 15 if (1 == input.check(input1)) { 16 input.writeUser(users, input1); 17 } else if (2 == input.check(input1)) { 18 input.writeRecord(users, input1); 19 } 20 input1 = in.nextLine(); 21 } 22 23 users.sort(new Comparator<User>() { 24 25 @Override 26 public int compare(User u1, User u2) { 27 if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') { 28 return -1; 29 } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') { 30 return 1; 31 } 32 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) { 33 return 1; 34 } else { 35 return -1; 36 } 37 } 38 }); 39 40 for (User u : users) { 41 System.out.print(u.getNumber() + " "); 42 output.output(u.calCost()); 43 System.out.print(" "); 44 output.output(u.calBalance()); 45 System.out.println(); 46 47 } 48 49 } 50 51 } 52 class User { 53 54 private UserRecords userRecords = new UserRecords(); 55 private double balance = 100; 56 private ChargeMode chargeMode; 57 private String number; 58 59 public double calCost() { 60 return chargeMode.calCost(userRecords); 61 } 62 63 public double calBalance() { 64 return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords); 65 } 66 67 public UserRecords getUserRecords() { 68 return userRecords; 69 } 70 71 public void setUserRecords(UserRecords userRecords) { 72 this.userRecords = userRecords; 73 } 74 75 public ChargeMode getChargeMode() { 76 return chargeMode; 77 } 78 79 public void setChargeMode(ChargeMode chargeMode) { 80 this.chargeMode = chargeMode; 81 } 82 83 public String getNumber() { 84 return number; 85 } 86 87 public void setNumber(String number) { 88 this.number = number; 89 } 90 91 } 92 93 class Output { 94 95 @SuppressWarnings("deprecation") 96 public void output(double out) { 97 98 BigDecimal numb = new BigDecimal(out); 99 out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); 100 System.out.print(out); 101 } 102 } 103 abstract class ChargeMode { 104 protected ArrayList<ChargeRule> chargeRules = new ArrayList<>(); 105 106 public abstract double calCost(UserRecords userRecords); 107 108 public abstract double getMonthlyRent(); 109 110 public ArrayList<ChargeRule> getChargeRules() { 111 return chargeRules; 112 } 113 114 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 115 this.chargeRules = chargeRules; 116 } 117 } 118 119 class UserRecords { 120 121 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 122 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 123 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); 124 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); 125 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); 126 private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); 127 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); 128 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); 129 130 public void addCallingInCityRecords(CallRecord callRecord) { 131 callingInCityRecords.add(callRecord); 132 } 133 134 public void addCallingInProvinceRecords(CallRecord callRecord) { 135 callingInProvinceRecords.add(callRecord); 136 } 137 138 public void addCallingInLandRecords(CallRecord callRecord) { 139 callingInLandRecords.add(callRecord); 140 } 141 142 public void addAnswerInCityRecords(CallRecord callRecord) { 143 answerInCityRecords.add(callRecord); 144 } 145 146 public void aaddAnswerInProvinceRecords(CallRecord callRecord) { 147 answerInProvinceRecords.add(callRecord); 148 } 149 150 public void addAnswerInLandRecords(CallRecord callRecord) { 151 answerInLandRecords.add(callRecord); 152 } 153 154 public void addSendMessageRecords(MessageRecord callRecord) { 155 sendMessageRecords.add(callRecord); 156 } 157 158 public void addReceiveMessageRecords(MessageRecord callRecord) { 159 receiveMessageRecords.add(callRecord); 160 } 161 162 public ArrayList<CallRecord> getCallingInCityRecords() { 163 return callingInCityRecords; 164 } 165 166 public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) { 167 this.callingInCityRecords = callingInCityRecords; 168 } 169 170 public ArrayList<CallRecord> getCallingInProvinceRecords() { 171 return callingInProvinceRecords; 172 } 173 174 public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) { 175 this.callingInProvinceRecords = callingInProvinceRecords; 176 } 177 178 public ArrayList<CallRecord> getCallingInLandRecords() { 179 return callingInLandRecords; 180 } 181 182 public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) { 183 this.callingInLandRecords = callingInLandRecords; 184 } 185 186 public ArrayList<CallRecord> getAnswerInCityRecords() { 187 return answerInCityRecords; 188 } 189 190 public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) { 191 this.answerInCityRecords = answerInCityRecords; 192 } 193 194 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 195 return answerInProvinceRecords; 196 } 197 198 public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) { 199 this.answerInProvinceRecords = answerInProvinceRecords; 200 } 201 202 public ArrayList<CallRecord> getAnswerInLandRecords() { 203 return answerInLandRecords; 204 } 205 206 public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) { 207 this.answerInLandRecords = answerInLandRecords; 208 } 209 210 public ArrayList<MessageRecord> getSendMessageRecords() { 211 return sendMessageRecords; 212 } 213 214 public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) { 215 this.sendMessageRecords = sendMessageRecords; 216 } 217 218 public ArrayList<MessageRecord> getReceiveMessageRecords() { 219 return receiveMessageRecords; 220 } 221 222 public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) { 223 this.receiveMessageRecords = receiveMessageRecords; 224 } 225 226 } 227 class MobilePhoneMassageCharging extends ChargeMode { 228 229 private double monthlyRent = 0; 230 231 public MobilePhoneMassageCharging() { 232 super(); 233 chargeRules.add(new MobilePhoneMessageRule()); 234 } 235 236 @Override 237 public double calCost(UserRecords userRecords) { 238 double sumCost = 0; 239 for (ChargeRule rule : chargeRules) { 240 sumCost += rule.calCost(userRecords); 241 } 242 return sumCost; 243 } 244 245 @Override 246 public double getMonthlyRent() { 247 return monthlyRent; 248 } 249 250 } 251 class LandlinePhoneCharging extends ChargeMode { 252 253 private double monthlyRent = 20; 254 255 public LandlinePhoneCharging() { 256 super(); 257 chargeRules.add(new LandPhoneInCityRule()); 258 chargeRules.add(new LandPhoneInProvinceRule()); 259 chargeRules.add(new LandPhoneInlandRule()); 260 } 261 262 @Override 263 public double calCost(UserRecords userRecords) { 264 double sumCost = 0; 265 for (ChargeRule rule : chargeRules) { 266 sumCost += rule.calCost(userRecords); 267 } 268 return sumCost; 269 } 270 271 @Override 272 public double getMonthlyRent() { 273 return monthlyRent; 274 } 275 276 } 277 278 class MobilePhoneCharging extends ChargeMode { 279 280 private double monthlyRent = 15; 281 282 public MobilePhoneCharging() { 283 super(); 284 chargeRules.add(new MobilePhoneInCityRule()); 285 chargeRules.add(new MobilePhoneInProvinceRule()); 286 chargeRules.add(new MobilePhoneInlandRule()); 287 } 288 289 @Override 290 public double calCost(UserRecords userRecords) { 291 double sumCost = 0; 292 for (ChargeRule rule : chargeRules) { 293 sumCost += rule.calCost(userRecords); 294 } 295 return sumCost; 296 } 297 298 @Override 299 public double getMonthlyRent() { 300 return monthlyRent; 301 } 302 303 } 304 305 306 class Input { 307 308 public int check(String input) { 309 if (input.matches("[u]-0791[0-9]{7,8}\\s[0]") || input.matches("[u]-1[0-9]{10}\\s[13]")) { 310 return 1; 311 } else if (input.matches("[m]-1[0-9]{10}\\s" + "1[0-9]{10}\\s" + "[0-9a-zA-Z\\s\\.,]+")) { 312 return 2; 313 } 314 return 0; 315 } 316 317 public void writeUser(ArrayList<User> users, String input) { 318 User usernew = new User(); 319 String[] inputs = input.split(" "); 320 String num = inputs[0].substring(2); 321 for (User i : users) { 322 if (i.getNumber().equals(num)) { 323 return; 324 } 325 } 326 usernew.setNumber(num); 327 int mode = Integer.parseInt(inputs[1]); 328 if (mode == 0) { 329 usernew.setChargeMode(new LandlinePhoneCharging()); 330 } else if (mode == 1) { 331 usernew.setChargeMode(new MobilePhoneCharging()); 332 } else if (mode == 3) { 333 usernew.setChargeMode(new MobilePhoneMassageCharging()); 334 } 335 users.add(usernew); 336 } 337 338 public void writeRecord(ArrayList<User> users, String input) { 339 String[] inputs = input.split(" "); 340 inputs[0] = inputs[0].substring(2); 341 342 User callu = null, answeru = null; 343 344 String out = inputs[0]; 345 String in = ""; 346 if (inputs.length == 6) { 347 in = inputs[1]; 348 } else if (inputs.length == 7) { 349 in = inputs[1]; 350 } else if (inputs.length == 8) { 351 in = inputs[2]; 352 } else { 353 in = inputs[1]; 354 } 355 356 for (User i : users) { 357 if (i.getNumber().equals(out)) { 358 callu = i; 359 } 360 if (i.getNumber().equals(in)) { 361 answeru = i; 362 } 363 if (callu != null && answeru != null) { 364 break; 365 } 366 } 367 368 if (input.charAt(0) == 'm') { 369 MessageRecord messageRecord = new MessageRecord(input); 370 if (callu != null) { 371 callu.getUserRecords().addSendMessageRecords(messageRecord); 372 ; 373 } 374 if (answeru != null) { 375 callu.getUserRecords().addReceiveMessageRecords(messageRecord); 376 } 377 } 378 379 } 380 381 } 382 383 abstract class CommunicationRecord { 384 protected String callingNumber; 385 protected String answerNumbe; 386 387 public String getCallingNumber() { 388 return callingNumber; 389 } 390 391 public void setCallingNumber(String callingNumber) { 392 this.callingNumber = callingNumber; 393 } 394 395 public String getAnswerNumbe() { 396 return answerNumbe; 397 } 398 399 public void setAnswerNumbe(String answerNumbe) { 400 this.answerNumbe = answerNumbe; 401 } 402 403 } 404 405 abstract class ChargeRule { 406 407 abstract public double calCost(UserRecords userRecords); 408 409 } 410 411 class CallRecord extends CommunicationRecord { 412 private Date startTime; 413 private Date endTime; 414 private String callingAddressAreaCode; 415 private String answerAddressAreaCode; 416 417 public String getCallType() { 418 String type = ""; 419 if (callingAddressAreaCode.equals("0791")) { 420 type = type.concat("1"); 421 } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) { 422 type = type.concat("2"); 423 } else { 424 type = type.concat("3"); 425 } 426 427 if (answerAddressAreaCode.equals("0791")) { 428 type = type.concat("1"); 429 } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) { 430 type = type.concat("2"); 431 } else { 432 type = type.concat("3"); 433 } 434 435 return type; 436 } 437 438 public CallRecord(String[] inputs) { 439 super(); 440 441 char type = inputs[0].charAt(0); 442 443 String sd = null, st = null, ed = null, et = null; 444 445 if (type == 't') { 446 if (inputs.length == 6) { 447 sd = inputs[2]; 448 st = inputs[3]; 449 ed = inputs[4]; 450 et = inputs[5]; 451 callingAddressAreaCode = inputs[0].substring(0, 4); 452 answerAddressAreaCode = inputs[1].substring(0, 4); 453 } else if (inputs.length == 7) { 454 sd = inputs[3]; 455 st = inputs[4]; 456 ed = inputs[5]; 457 et = inputs[6]; 458 if (inputs[0].charAt(0) != '0') { 459 if (inputs[2].length() == 10) { 460 answerAddressAreaCode = inputs[2].substring(0, 3); 461 } else { 462 answerAddressAreaCode = inputs[2].substring(0, 4); 463 } 464 callingAddressAreaCode = inputs[1]; 465 } else { 466 if (inputs[0].length() == 10) { 467 callingAddressAreaCode = inputs[0].substring(0, 3); 468 } else { 469 callingAddressAreaCode = inputs[0].substring(0, 4); 470 } 471 answerAddressAreaCode = inputs[2]; 472 } 473 } else if (inputs.length == 8) { 474 sd = inputs[4]; 475 st = inputs[5]; 476 ed = inputs[6]; 477 et = inputs[7]; 478 callingAddressAreaCode = inputs[1]; 479 answerAddressAreaCode = inputs[3]; 480 } 481 } else if (type == 'm') { 482 483 } 484 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault()); 485 try { 486 startTime = simpleDateFormat.parse(sd + " " + st); 487 endTime = simpleDateFormat.parse(ed + " " + et); 488 } catch (ParseException e) { 489 } 490 491 } 492 493 public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { 494 super(); 495 this.startTime = startTime; 496 this.endTime = endTime; 497 this.callingAddressAreaCode = callingAddressAreaCode; 498 this.answerAddressAreaCode = answerAddressAreaCode; 499 } 500 501 public Date getStartTime() { 502 return startTime; 503 } 504 505 public void setStartTime(Date startTime) { 506 this.startTime = startTime; 507 } 508 509 public Date getEndTime() { 510 return endTime; 511 } 512 513 public void setEndTime(Date endTime) { 514 this.endTime = endTime; 515 } 516 517 public String getCallingAddressAreaCode() { 518 return callingAddressAreaCode; 519 } 520 521 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 522 this.callingAddressAreaCode = callingAddressAreaCode; 523 } 524 525 public String getAnswerAddressAreaCode() { 526 return answerAddressAreaCode; 527 } 528 529 public void setAnswerAddressAreaCode(String answerAddressAreaCode) { 530 this.answerAddressAreaCode = answerAddressAreaCode; 531 } 532 } 533 534 abstract class CallChargeRule extends ChargeRule { 535 536 } 537 538 class LandPhoneInCityRule extends CallChargeRule { 539 540 @Override 541 public double calCost(UserRecords userRecords) { 542 double sumCost = 0; 543 for (CallRecord call : userRecords.getCallingInCityRecords()) { 544 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 545 if (distanceS < 0) { 546 continue; 547 } 548 double distanceM = (int) distanceS / 60; 549 if (distanceS % 60 != 0) { 550 distanceM += 1; 551 } 552 if (call.getCallType().equals("11")) { 553 sumCost += distanceM * 0.1; 554 } else if (call.getCallType().equals("12")) { 555 sumCost += distanceM * 0.3; 556 } else if (call.getCallType().equals("13")) { 557 sumCost += distanceM * 0.6; 558 } 559 } 560 return sumCost; 561 } 562 563 } 564 565 class LandPhoneInlandRule extends CallChargeRule { 566 567 @Override 568 public double calCost(UserRecords userRecords) { 569 double sumCost = 0; 570 for (CallRecord call : userRecords.getCallingInLandRecords()) { 571 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 572 if (distanceS < 0) { 573 continue; 574 } 575 double distanceM = (int) distanceS / 60; 576 if (distanceS % 60 != 0) { 577 distanceM += 1; 578 } 579 sumCost += distanceM * 0.6; 580 } 581 return sumCost; 582 } 583 584 } 585 586 class LandPhoneInProvinceRule extends CallChargeRule { 587 588 @Override 589 public double calCost(UserRecords userRecords) { 590 double sumCost = 0; 591 for (CallRecord call : userRecords.getCallingInProvinceRecords()) { 592 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 593 if (distanceS < 0) { 594 continue; 595 } 596 double distanceM = (int) distanceS / 60; 597 if (distanceS % 60 != 0) { 598 distanceM += 1; 599 } 600 sumCost += distanceM * 0.3; 601 } 602 return sumCost; 603 } 604 605 } 606 607 class MobilePhoneInCityRule extends CallChargeRule { 608 609 @Override 610 public double calCost(UserRecords userRecords) { 611 double sumCost = 0; 612 for (CallRecord call : userRecords.getCallingInCityRecords()) { 613 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 614 if (distanceS < 0) { 615 continue; 616 } 617 double distanceM = (int) distanceS / 60; 618 if (distanceS % 60 != 0) { 619 distanceM += 1; 620 } 621 if (call.getCallType().equals("11")) { 622 sumCost += distanceM * 0.1; 623 } else if (call.getCallType().equals("12")) { 624 sumCost += distanceM * 0.2; 625 } else if (call.getCallType().equals("13")) { 626 sumCost += distanceM * 0.3; 627 } 628 629 } 630 return sumCost; 631 } 632 633 } 634 635 class MobilePhoneInlandRule extends CallChargeRule { 636 637 @Override 638 public double calCost(UserRecords userRecords) { 639 double sumCost = 0; 640 for (CallRecord call : userRecords.getCallingInLandRecords()) { 641 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 642 if (distanceS < 0) { 643 continue; 644 } 645 double distanceM = (int) distanceS / 60; 646 if (distanceS % 60 != 0) { 647 distanceM += 1; 648 } 649 sumCost += distanceM * 0.6; 650 } 651 for (CallRecord call : userRecords.getAnswerInLandRecords()) { 652 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 653 if (distanceS < 0) { 654 continue; 655 } 656 double distanceM = (int) distanceS / 60; 657 if (distanceS % 60 != 0) { 658 distanceM += 1; 659 } 660 sumCost += distanceM * 0.3; 661 } 662 return sumCost; 663 } 664 665 } 666 667 class MobilePhoneInProvinceRule extends CallChargeRule { 668 669 @Override 670 public double calCost(UserRecords userRecords) { 671 double sumCost = 0; 672 for (CallRecord call : userRecords.getCallingInProvinceRecords()) { 673 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; 674 if (distanceS < 0) { 675 continue; 676 } 677 double distanceM = (int) distanceS / 60; 678 if (distanceS % 60 != 0) { 679 distanceM += 1; 680 } 681 if (call.getCallType().equals("21")) { 682 sumCost += distanceM * 0.3; 683 } else if (call.getCallType().equals("22")) { 684 sumCost += distanceM * 0.3; 685 } else if (call.getCallType().equals("23")) { 686 sumCost += distanceM * 0.3; 687 } 688 } 689 return sumCost; 690 } 691 692 } 693 694 class MobilePhoneMessageRule extends CallChargeRule { 695 696 @Override 697 public double calCost(UserRecords userRecords) { 698 double sumCost = 0; 699 int number = 0; 700 for (MessageRecord m : userRecords.getSendMessageRecords()) { 701 int length = m.getMessage().length(); 702 if (length <= 10) { 703 number++; 704 } else { 705 number += length / 10; 706 if (length % 10 != 0) { 707 number++; 708 } 709 } 710 } 711 if (number <= 3) { 712 sumCost = number * 0.1; 713 } else if (number <= 5) { 714 sumCost = 0.3 + 0.2 * (number - 3); 715 } else { 716 sumCost = 0.7 + 0.3 * (number - 5); 717 } 718 return sumCost; 719 } 720 721 } 722 723 class MessageRecord extends CommunicationRecord { 724 725 private String message; 726 727 public MessageRecord(String input) { 728 super(); 729 this.message = input.substring(26); 730 } 731 732 public String getMessage() { 733 return message; 734 } 735 736 public void setMessage(String message) { 737 this.message = message; 738 } 739 } 740View Code
分析:
在上一道题的基础上新增短信计费,需要将短信类重写。再加上一个短信计费的算法。注意判断短信内容分割时,用正则表达式注意空格。
(3)踩坑心得
电信计费1
建议使用正则表达式
注意时间必须符合"yyyy.MM.dd HH:mm:ss"格式。一般使用SimpleDateFormat类。
电信计费2
注意考虑到座机、手机用户混合时非法输入以及座机、手机用户混合时重复的用户开户信息的情况。
电信计费3
没什么好说的,注意怎么计算短信用费就好了
(4)改进建议
这几次作业难度都有所下降,完成度提高了,挺好的。
最大复杂度太大了,可以尽量少用嵌套语句。
对于抽象类怎么使用还需要加强训练,还有接口的使用。
(5)总结
10-16周不但有PTA的三次大作业,还有几次实验,经过这些,使我对于多态、抽象类理解掌握更深了。尤其是上转型还是下转型怎么使用终于搞明白了,
不再是云里雾里。对于怎么使用ArryList中的方法也有了一定的把握。明白可以抽象类实现对子类方法的重写以及扩展该模块的行为功能。但是对于接口
的使用还是有一点问题。还有写代码时有时候思路不清晰,一顿乱操作。除此之外,虽然这几次作业中没有线程和装饰器之类的题,但是课堂作业布置了,
我感觉这线程和装饰类比多态和抽象类要更好掌握。很开心能学到这些。总之这几周的学习让我对于类的理解与使用更透彻了,如何转型、怎么调用子类
或父类的方法有了自己的理解。
标签:inputs,return,String,double,ArrayList,BLOG,public From: https://www.cnblogs.com/lmlin/p/16969026.html