blog-3
一、前言:
这三周大作业相对于前面的pta大作业算法上比较简单,但是后面三次大作业逻辑上比较难,但是经过后面三次的大作业的完成,知道了怎么面向对象,虽然要建立很多类,但是这样管理起来更方便,修改起来,或者添加功能也更加的方便,不用去大段的修改代码,也避免了大量的代码重复。同时,对于其他那些看代码的人也可以很好的看懂,也更直观。电信系列的大作业主要涉及了容器的知识,对信息的储存和便利,同时还考了容器内部排序,通过Collections函数进行排序,也通过对不同的用户进行不同的分类,放在不同的容器中。当然,其中也还涉及到子类、父类,分类,类的创建,类的管理,正则表达式等等。不过相比于上次只“白手起家”,这次大作业给了类图,只要跟随类图创造即可。本次大作业也应用了一些新东西,比如:计算时间差需要运用SimpleDateformat类,用collection类将每个新开账户的费用输出,再比如要将新开账户的通话记录收集到一起。
二、设计与分析:
实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租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
其余参考样例详见附件,未尽事宜以附件样例为准:
64
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); ArrayList<User> users1 = new ArrayList<User>(); ArrayList<User> users2 = new ArrayList<User>(); ChargeMode chargeMode; ArrayList<CallRecord> callRecords = new ArrayList<CallRecord>(); SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); String[] tokens = null; Date time1=null,time2=null; while(true) { String number=in.nextLine(); if(number.equals("end")) break; int f=0; f=JudgeFormat.judge(number); if(f!=0) { for(int i=0;i<number.length();i++) { tokens=number.split("[- ]"); } if(tokens[0].equals("u")){//开户 CallRecord callRecord = new CallRecord(); String areaCode; LandlinePhoneCharging m = new LandlinePhoneCharging();//座机 MobilePhoneCharging n =new MobilePhoneCharging();//手机 chargeMode = m; chargeMode = n; if(f==1) { boolean judge=true; areaCode = tokens[1].substring(0, 4); callRecord.setCallingAddressAreaCode(areaCode);//区号 for(User user : users1) { if(user.getNumber().equals(tokens[1]))//判断是否已开户 judge=false; } if(judge) {//如果没有就开户 User u = new User(m,tokens[1]); users1.add(u);//开户 } } else if(f==2) { boolean judge=true; for(User user : users2) { if(user.getNumber().equals(tokens[1]))//判断是否已开户 judge=false; } if(judge) {//如果没有就开户 User u = new User(n,tokens[1]); users2.add(u);//开户 } } } if(tokens[0].equals("t")) { CallRecord callRecord = new CallRecord(); String anwserareaCode,callareaCode; if(f==3) { callareaCode = tokens[1].substring(0, 4);//拨打区号 callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号 callRecord.setCallingNumber(tokens[1]);//传入拨打号码 anwserareaCode = tokens[2].substring(0, 4);//接通地址 callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号 callRecord.setAnswerNumber(tokens[2]);//传入接通号码 try { time1 = df.parse(tokens[3]+" "+tokens[4]); } catch (ParseException e1) { e1.printStackTrace(); } try { time2 = df.parse(tokens[5]+" "+tokens[6]); } catch (ParseException e) { e.printStackTrace(); } callRecord.setStartTime(time1);//开始时间 callRecord.setEndTime(time2);//结束时间 callRecords.add(callRecord);//添加用户记录 } if(f==4) { callareaCode = tokens[1].substring(0, 4);//拨打区号 callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号 callRecord.setCallingNumber(tokens[1]);//传入拨打号码 anwserareaCode = tokens[3];//接通地址 callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号 callRecord.setAnswerNumber(tokens[2]);//传入接通号码 try { time1 = df.parse(tokens[4]+" "+tokens[5]); } catch (ParseException e1) { e1.printStackTrace(); } try { time2 = df.parse(tokens[6]+" "+tokens[7]); } catch (ParseException e) { e.printStackTrace(); } callRecord.setStartTime(time1);//开始时间 callRecord.setEndTime(time2);//结束时间 callRecords.add(callRecord);//添加用户记录 } if(f==5) { callareaCode = tokens[2];//拨打区号 callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号 callRecord.setCallingNumber(tokens[1]);//传入拨打号码 anwserareaCode = tokens[4];//接通地址 callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号 callRecord.setAnswerNumber(tokens[3]);//传入接通号码 try { time1 = df.parse(tokens[5]+" "+tokens[6]); } catch (ParseException e1) { e1.printStackTrace(); } try { time2 = df.parse(tokens[7]+" "+tokens[8]); } catch (ParseException e) { e.printStackTrace(); } callRecord.setStartTime(time1);//开始时间 callRecord.setEndTime(time2);//结束时间 callRecords.add(callRecord);//添加用户记录 } if(f==6) { callareaCode = tokens[2];//拨打区号 callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号 callRecord.setCallingNumber(tokens[1]);//传入拨打号码 anwserareaCode = tokens[3].substring(0,4);//接通地址 callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号 callRecord.setAnswerNumber(tokens[3]);//传入接通号码 try { time1 = df.parse(tokens[4]+" "+tokens[5]); } catch (ParseException e1) { e1.printStackTrace(); } try { time2 = df.parse(tokens[6]+" "+tokens[7]); } catch (ParseException e) { e.printStackTrace(); } callRecord.setStartTime(time1);//开始时间 callRecord.setEndTime(time2);//结束时间 callRecords.add(callRecord);//添加用户记录 } } } } // for(int i=0;i<callRecords.size();i++) { // System.out.println(callRecords.get(i).getAnswerNumber()+" "+callRecords.get(i).getCallingNumber()+" "+callRecords.get(i).getCallingAddressAreaCode()+" "+callRecords.get(i).getAnswerAddressAreaCode()); // } // Collections.sort(users1,new Comparator<User>() { public int compare(User s1,User s2){ double n1 = Double.parseDouble(s1.getNumber()); double n2 = Double.parseDouble(s2.getNumber()); if(n1 > n2) { return 1; } return -1; } }); Collections.sort(users2,new Comparator<User>() { public int compare(User s1,User s2){ double n1 = Double.parseDouble(s1.getNumber()); double n2 = Double.parseDouble(s2.getNumber()); if(n1 > n2) { return 1; } return -1; } }); for(int i=0; i<users1.size(); i++) { UserRecords userRecords = new UserRecords();//用户记录 for(int j=0;j<callRecords.size();j++) { if(users1.get(i).getNumber().equals(callRecords.get(j).getCallingNumber())) { if(callRecords.get(j).getAnswerAddressAreaCode().matches("0791"))//市内打电话 userRecords.addCallingInCityRecords(callRecords.get(j)); else if(callRecords.get(j).getAnswerAddressAreaCode().matches("((079\\d)|0701)"))//省内打电话 userRecords.addCallingInProvinceRecords(callRecords.get(j)); else//国内打电话 userRecords.addCallingInLandRecords(callRecords.get(j)); } if(users1.get(i).getNumber().equals(callRecords.get(j).getAnswerNumber())) { if(callRecords.get(j).getCallingAddressAreaCode().matches("0791"))//市内接电话 userRecords.addAnswerInCityRecords(callRecords.get(j)); else if(callRecords.get(j).getCallingAddressAreaCode().matches("((079\\d)|0701)"))//省内接电话 userRecords.addAnswerInProvinceRecords(callRecords.get(j)); else //国内接电话 userRecords.addAnswerInLandRecords(callRecords.get(j)); } } // 将用户记录存入对应用户中 users1.get(i).setUserRecords(userRecords); } for(int i=0; i<users2.size(); i++) { UserRecords userRecords = new UserRecords();//用户记录 for(int j=0; j<callRecords.size(); j++) { if(users2.get(i).getNumber().equals(callRecords.get(j).getCallingNumber())) { if(callRecords.get(j).getCallingAddressAreaCode().equals("0791")) { if(callRecords.get(j).getAnswerAddressAreaCode().matches("0791")) {//市内打市内电话 userRecords.addCallingInCityRecords(callRecords.get(j)); } else if(callRecords.get(j).getAnswerAddressAreaCode().matches("((079\\d)|0701)")) {//市内打省内电话 userRecords.addCallingInProvinceRecords(callRecords.get(j)); } else {//市内打国内电话 userRecords.addCallingInLandRecords(callRecords.get(j)); } } else if(callRecords.get(j).getCallingAddressAreaCode().matches("((079\\d)|0701)")) { userRecords.addPcallingRecords(callRecords.get(j)); } else { userRecords.addLcallingRecords(callRecords.get(j)); } } if(users2.get(i).getNumber().equals(callRecords.get(j).getAnswerNumber())) { if(callRecords.get(j).getAnswerAddressAreaCode().matches("0791")) {//市内接电话 userRecords.addAnswerInCityRecords(callRecords.get(j)); } else if(callRecords.get(j).getAnswerAddressAreaCode().matches("((079\\d)|0701)")) {//省内接电话 userRecords.addAnswerInProvinceRecords(callRecords.get(j)); } else {//国内接电话 userRecords.addAnswerInLandRecords(callRecords.get(j)); } } } users2.get(i).setUserRecords(userRecords);//将用户记录存入对应用户中 } for(User u : users1) { System.out.println(u.getNumber()+" "+String.format("%.1f", u.calCost())+" "+String.format("%.1f", u.getBalance())); } for(User u : users2) { System.out.println(u.getNumber()+" "+String.format("%.1f", u.calCost())+" "+String.format("%.1f", u.getBalance())); } } } abstract class CallChargeRule extends ChargeRule{ public abstract double calCost(ArrayList<CallRecord> callRecords); } class CallRecord extends CommunicationRecord{ private Date startTime;//开始时间 private Date endTime;//结束时间 private String callingAddressAreaCode;//拨号地点的区号 private String answerAddressAreaCode;//接听地点的区号 public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } abstract class ChargeMode { private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>(); public ArrayList<ChargeRule> getChargeRules(){ return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules=chargeRules; } public abstract double calCost(UserRecords userRecords); public abstract double getMonthlyRent(); } abstract class ChargeRule { } abstract class CommunicationRecord { private String callingNumber;//拨打电话 private String answerNumber;//接听电话 public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } class JudgeFormat { public static int judge(String number) { if( number.matches("u-0791\\d{7,9} 0") ) return 1;//座机开户 else if( number.matches("u-1\\d{10} 1") ) return 2;//手机开户 else if( number.matches("t-\\d{11,13} \\d{10,13} [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d") ) return 3;//座机打座机 else if ( number.matches("t-\\d{10,13} 1\\d{10} 0\\d{2,4} [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d") ) return 4;//座机打手机 else if ( number.matches("t-1\\d{10} 0\\d{3,5} 1\\d{10} 0\\d{2,4} [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d") ) return 5;//手机互打 else if( number.matches("t-1\\d{10} 0\\d{3,5} 0791\\d{7,9} [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d") ) return 6;//手机打座机 return 0; } } class LandlinePhoneCharging extends ChargeMode{ private double monthlyRent=20;//月租 @Override public double calCost(UserRecords userRecords) {//话费 double rent = 0; ArrayList<CallRecord> callInCityRecords = userRecords.getCallingInCityRecords();//获取拨打市内电话记录 ArrayList<CallRecord> callInProvinceRecords = userRecords.getCallingInProvinceRecords();//获取拨打省内电话记录 ArrayList<CallRecord> callInLandRecords = userRecords.getCallingInLandRecords();//获取拨打国内电话记录 CallChargeRule landPhoneInCityRule = new LandPhoneInCityRule();//市内主叫市内 CallChargeRule landPhoneInProvinceRule = new LandPhoneInProvinceRule();//市内主叫省内 CallChargeRule landPhoneInLandRule = new LandPhoneInlandRule();//市内主叫国内 // CallChargeRule callChargeRule = new LandPhoneInCityRule(); rent+=landPhoneInCityRule.calCost(callInCityRecords); // callChargeRule = new LandPhoneInProvinceRule(); rent+=landPhoneInProvinceRule.calCost(callInProvinceRecords); // callChargeRule = new LandPhoneInlandRule(); rent+=landPhoneInLandRule.calCost(callInLandRecords); return rent; } @Override public double getMonthlyRent() {//月租 return monthlyRent; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for(int i=0;i<callRecords.size();i++) { long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;//转化时间 if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) min++; sum+=0.1*min; } return sum; } } class LandPhoneInlandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for(int i=0;i<callRecords.size();i++) { long min=( (callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000 )/60;//转化时间 if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) { min++; } sum+=0.6*min; } return sum; } } class LandPhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for(int i=0;i<callRecords.size();i++) { long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) / 60;//转化时间 if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) min++; sum+=0.3*min; } return sum; } } class MobilePhoneCharging extends ChargeMode{ private double monthlyRent=15;//月租 @Override public double calCost(UserRecords userRecords) {//话费 double rent = 0; CallChargeRule callChargeRule = new MobilePhoneInCityRule();//市内打市内电话 rent+=callChargeRule.calCost(userRecords.getCallingInCityRecords()); callChargeRule = new MobilePhoneInProvinceRule();//市内打省内电话 rent+=callChargeRule.calCost(userRecords.getCallingInProvinceRecords()); callChargeRule = new MobilePhoneInlandRule();//市内打国内电话 rent+=callChargeRule.calCost(userRecords.getCallingInLandRecords()); callChargeRule = new MobilePhoneRoamingAnswerOutProvince();//省外接电话 rent+=callChargeRule.calCost(userRecords.getAnswerInLandRecords()); callChargeRule = new MobilePhoneRoamingCallOutProvince();//省外打电话 rent+=callChargeRule.calCost(userRecords.getLcallingRecords()); callChargeRule = new MobilePhoneRoamingCallsInProvince();//省内打电话 rent+=callChargeRule.calCost(userRecords.getPcallingRecords()); return rent; } @Override public double getMonthlyRent() {//月租 return monthlyRent; } } class MobilePhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) {//市内打市内 double sum = 0; for(int i=0;i<callRecords.size();i++) { long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;//转化时间 if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) min++; sum+=0.1*min; } return sum; } } class MobilePhoneInlandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) {//市内打省外 double sum = 0; for(int i=0;i<callRecords.size();i++) { long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;//转化时间 if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) min++; sum+=0.3*min; } return sum; } } class MobilePhoneInProvinceRule extends CallChargeRule{//市内拨打省内 @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for(int i=0;i<callRecords.size();i++) { long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;//转化时间 if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) min++; sum+=0.2*min; } return sum; } } class MobilePhoneRoamingAnswerOutProvince extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) {//省外漫游接电话 double sum = 0; for(int i=0;i<callRecords.size();i++) { long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;//转化时间 if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) min++; sum+=0.3*min; } return sum; } } class MobilePhoneRoamingCallOutProvince extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) {//省外漫游打电话 double sum = 0; for(int i=0;i<callRecords.size();i++) { long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;//转化时间 if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) min++; sum+=0.6*min; } return sum; } } class MobilePhoneRoamingCallsInProvince extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) {//省内漫游打电话 double sum = 0; for(int i=0;i<callRecords.size();i++) { long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;//转化时间 if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) min++; sum+=0.3*min; } return sum; } } class User { private UserRecords userRecords;//用户记录 private double balance=100;//用户余额 private ChargeMode chargeMode;//计费方式 private String number;//号码 public double calCost() { double sum=chargeMode.calCost(userRecords); balance-=(sum+chargeMode.getMonthlyRent()); return sum; } 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; } public User(ChargeMode chargeMode,String number) { this.chargeMode=chargeMode; this.number=number; } } class UserRecords { ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();//市内打电话 ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();//省内打电话 ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();//国内打电话 ArrayList<CallRecord> PcallingRecords = new ArrayList<CallRecord>();//省内打漫游 ArrayList<CallRecord> LcallingRecords = new ArrayList<CallRecord>();//国内打漫游 ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();//市内接电话 ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();//省内接电话 ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();//国内接电话 public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public void addCallingInCityRecords(CallRecord callRecord) {//添加市内打电话记录 callingInCityRecords.add(callRecord); } public ArrayList<CallRecord> getCallingInProvinceRecords() { return callingInProvinceRecords; } public void addCallingInProvinceRecords(CallRecord callRecord) {//添加省内打电话记录 callingInProvinceRecords.add(callRecord); } public ArrayList<CallRecord> getCallingInLandRecords() { return callingInLandRecords; } public void addCallingInLandRecords(CallRecord callRecord) {//添加国内打电话记录 callingInLandRecords.add(callRecord); } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public void addAnswerInCityRecords(CallRecord answerRecord) {//添加市内接电话记录 answerInCityRecords.add(answerRecord); } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public void addAnswerInProvinceRecords(CallRecord answerRecord) {//添加省内接电话记录 answerInProvinceRecords.add(answerRecord); } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public void addAnswerInLandRecords(CallRecord answerRecord) {//添加国内接电话记录 answerInLandRecords.add(answerRecord); } public void addPcallingRecords (CallRecord callRecord) { PcallingRecords.add(callRecord); } public ArrayList<CallRecord> getPcallingRecords() { return PcallingRecords; } public void addLcallingRecords (CallRecord callRecord) { LcallingRecords.add(callRecord); } public ArrayList<CallRecord> getLcallingRecords() { return LcallingRecords; } }
按照按照提示的类图自己写就好,主要是在main函数里写下正确的代码。
第二次不会
第三次题目:
实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
1、接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。
2、如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。
只要看懂题目的意思就行,超出的部分另收费
三、踩坑心得:
这三周,我们写这个pta其中修复了很多bug,比如少写了添加的信息,导致有些东西传不进去或者报错,还有时候没有建立座机类导致一直会报错,有时候没有新建类导致有的信息没传,导致我会一直报错,就算我写完了都还有梳理很长时间的思路,当然这次的pta的作业让我知道了如何面向对象去设计实验,面向对象的好处,他的思路更清晰,修改起来更简单,代码耦合度小,代码复杂度低的优点。当我掌握这种方法后可以使代码复用度更高,可以使后面需要加什么代码直接可以加上去,不用再去另外写新的代码了。
四、改进建议:
这次的Main函数的代码太过于长了,导致很不好寻找,思路不清晰,耦合度有点高。
7-1 电信计费系列3-短信计费
本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码、自己给自己打电话等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。
此处可增加判断的要求。
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
题目所说是保留两位小数,但是实际上测试样例以及测试点都是保留的一位小数,此处可做改进。
五、总结:
浙公网安备 33010602011771号