第三次博客作业
第三次博客作业
1.前言
2.设计与分析
3.踩坑心得
4.改进建议
5.总结
前言
这三次题目集的主要知识点是对于电信计费程序一个电信计费程序的迭代,考的内容主要
为对于类之间的使用与继承,然后在其之上加更多的内容还有对于正则表达式的熟悉运用。因为后期会需要加更多的内容,
我们应该在设计初期就将其设计的全面一点,主要就是降低类之间的耦合性以及一些抽象类
的设计。而至于难度而言,第一次反而是最难的,写到往后会发现都是在第一题设计的基础
上加内容,所以难度是逐步降低的。
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元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
源码:
public class Main { public static void main(String[] args) throws ParseException { // TODO Auto-generated method stub ArrayList<User> user = new ArrayList<User>(); Scanner input = new Scanner(System.in); boolean flag =false; for (;;) { String a = input.nextLine(); if (a.equals("end")) break; Check check = new Check(a); if(check.checkOut()) { //判断是否输入正确 if(a.length()<20) { //第一种输入 for(int i = 0; i < user.size(); i++) { if(check.getnumber1().equals(user.get(i).getNumber())) { flag = true; break; } } if(!flag) { User b = new User(check.getnumber1()); user.add(b); } } else if(a.length()>20){//第二种输入 int x = -5; for(int i = 0; i < user.size(); i++) { if(check.getnumber1().equals(user.get(i).getNumber())) x = i; } if(x>=0) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); simpleDateFormat.setLenient(false); ParsePosition parsePosition1 = new ParsePosition(0); ParsePosition parsePosition2 = new ParsePosition(0); CallRecord call=new CallRecord(); if(simpleDateFormat.parse(check.getTime1(),parsePosition1) != null && simpleDateFormat.parse(check.getTime1(),parsePosition2) != null ) { Date StartTime = simpleDateFormat.parse(check.getTime1()); Date EndTime = simpleDateFormat.parse(check.getTime2()); call.setStartTime(StartTime); call.setEndTime(EndTime); if (check.getnumber2().matches("0791[0-9]{7,8}")) { user.get(x).getUserRecords().addCallingInCityRecords(call); } else if(check.getnumber2().matches("079[0-9][0-9]{7,8}")||check.getnumber2().matches("0701[0-9]{7,8}")) { user.get(x).getUserRecords().addCallingInProvinceRecords(call); } else{ user.get(x).getUserRecords().addCallingInLandRecords(call); } } } } } } for(int i=1;i<=user.size()-1;i++){ for(int j=0;j<=user.size()-1-i;j++){ if(Double.parseDouble(user.get(j).getNumber())>Double.parseDouble(user.get(j+1).getNumber())){ Collections.swap(user,j,j+1); } } } for(int i=0;i<user.size();i++){ System.out.println(user.get(i).getNumber()+" "+String.format("%.1f",user.get(i).getChargeMode().calCost(user.get(i).getUserRecords())) +" "+String.format("%.1f",user.get(i).calBalance())); } } }abstract class ChargeMode { private 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; } } abstract class ChargeRule{ } class Check { private String a; public Check(String a) { super(); this.a = a; } String regex1 = "u-[0-9]{10,12} 0"; String regex2 = "t-[0-9]{10,12} [0-9]{10,12} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}.[0-9]{2}.[0-9]{2}"; public boolean checkOut() { if(a.matches(regex1)) { return true; } else if(a.matches(regex2)){ return true; } else return false; } public String getnumber1() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); return number1[1]; } public String getnumber2() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); return number[1]; } public String getTime1() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); String Time1 = number[2]+" "+number[3]; return Time1; } public String getTime2() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); String Time2 = number[4]+" "+number[5]; return Time2; } } 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 LandlinePhoneCharging extends ChargeMode{ LandPhoneInCityRule Rule1 = new LandPhoneInCityRule(); LandPhoneInProvinceRule Rule2 = new LandPhoneInProvinceRule(); LandPhoneInLandRule Rule3 = new LandPhoneInLandRule(); @Override public double calCost(UserRecords userRecords) { return Rule1.calCost(userRecords.getCallingInCityRecords()) + Rule2.calCost(userRecords.getCallingInProvinceRecords()) + Rule3.calCost(userRecords.getCallingInLandRecords()); } @Override public double getMonthlyRent() { double monthmoney=20; return monthmoney; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for(int i = 0;i < callRecords.size();i ++) { sum+= callRecords.get(i).getOfTime() * 0.1 ; } return sum; } } class LandPhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for(int i = 0;i < callRecords.size();i ++) { sum+= callRecords.get(i).getOfTime() * 0.6 ; } return sum; } } class LandPhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for(int i = 0;i < callRecords.size();i ++) { sum+= callRecords.get(i).getOfTime() * 0.3 ; } return sum; } } class MessageRecord extends CommunicationRecord{ private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } class User { private UserRecords userRecords = new UserRecords(); private double balance = 100; private LandlinePhoneCharging chargeMode = new LandlinePhoneCharging(); private String number; public User(String number) { this.number = number; } public double calBalance() { return getBalance() - calCost() - chargeMode.getMonthlyRent(); } public double calCost() { return chargeMode.calCost(getUserRecords()) ; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(LandlinePhoneCharging chargeMode) { this.chargeMode = chargeMode; } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public double getBalance() { return balance; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } class UserRecords { private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); public void addCallingInCityRecords(CallRecord callRecord) { callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecords(CallRecord callRecord) { callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecords(CallRecord callRecord) { callingInLandRecords.add(callRecord); } public void addAnswerInCityRecords(CallRecord callRecord) {answerInCityRecords.add(callRecord);} public void addAnswerInProvinceRecords(CallRecord callRecord) { answerInProvinceRecords.add(callRecord); } public void addAnswerInLandRecords(CallRecord callRecord) { answerInLandRecords.add(callRecord); } public void addSendMessageRecords(MessageRecord messageRecord) { sendMessageRecords.add(messageRecord); } public void addReceiveMessageRecords(MessageRecord messageRecord) { receiveMessageRecords.add(messageRecord); } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public ArrayList<CallRecord> getCallingInProvinceRecords() { return callingInProvinceRecords; } public ArrayList<CallRecord> getCallingInLandRecords() { return callingInLandRecords; } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } }

1.设计与分析:①该题目给了我们部分类图,就方便我们去设计与理解,我们就应该顺着题目的思路去设计。
②题目给了大部分的类图,但是我们还需要自己去设计一些所需的类。(例如此题的check类)
③对于正则表达式的运用必须熟悉。
④对于一些抽象类,也需要设计。
2.踩坑心得:此题需要计算两段时间之间的具体分钟,这里根据题目提示需要用到SimpleDateFormat类,
然后根据"yyyy.MM.dd HH:mm:ss"格式来计算。还有就是判断输入时,我们显然需要判断输入格式,以
及区分为是开户还是打电话,这个很多人是直接在main里头判断,这样后面换格式则需要大改。我们可以设计
一个check类来用于专门判断,方便后面修改。
3.改进建议:步骤过程太为繁琐,可适当简化,并且编译习惯不够好。
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元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
源码:
public class Main { public static void main(String[] args) throws ParseException { // TODO Auto-generated method stub ArrayList<User> user = new ArrayList<User>(); Scanner input = new Scanner(System.in); boolean flag = false; for (;;) { String a = input.nextLine(); if (a.equals("end")) break; Check check = new Check(a); if (check.checkOut()) { // 判断是否输入正确 if (check.checkOut1()) { // 第一种输入 for (int i = 0; i < user.size(); i++) { if (check.getnumber1().equals(user.get(i).getNumber())) { flag = true; break; } } if (!flag) { User b = new User(check.getnumber1(), 0); user.add(b); } } else if (check.checkOut2()) { for (int i = 0; i < user.size(); i++) { if (check.getnumber1().equals(user.get(i).getNumber())) { flag = true; break; } } if (!flag) { User b = new User(check.getnumber1(), 1); user.add(b); } } else if (check.checkOut3()) { int x = -5; for (int i = 0; i < user.size(); i++) { if (check.getnumber1().equals(user.get(i).getNumber())) x = i; } if (x >= 0) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); simpleDateFormat.setLenient(false); ParsePosition parsePosition1 = new ParsePosition(0); ParsePosition parsePosition2 = new ParsePosition(0); CallRecord call = new CallRecord(); if (simpleDateFormat.parse(check.getTime1(), parsePosition1) != null && simpleDateFormat.parse(check.getTime1(), parsePosition2) != null) { Date StartTime = simpleDateFormat.parse(check.getTime1()); Date EndTime = simpleDateFormat.parse(check.getTime2()); call.setStartTime(StartTime); call.setEndTime(EndTime); if (check.getnumber2().matches("0791[0-9]{7,8}")) { user.get(x).getUserRecords().addCallingInCityRecords(call); } else if (check.getnumber2().matches("079[0-9][0-9]{7,8}") || check.getnumber2().matches("0701[0-9]{7,8}")) { user.get(x).getUserRecords().addCallingInProvinceRecords(call); } else { user.get(x).getUserRecords().addCallingInLandRecords(call); } } } } else if (check.checkOut4()) { String[] a1 = a.split(" "); String[] a2 = a1[0].split("-"); int p = -1; int o = -1; for (int i = 0; i < user.size(); i++) { if (Objects.equals(a2[1], user.get(i).getNumber())) p = i; } for (int i = 0; i < user.size(); i++) { if (Objects.equals(a1[1], user.get(i).getNumber())) o = i; } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); simpleDateFormat.setLenient(false); String time1 = a1[3] + " " + a1[4]; String time2 = a1[5] + " " + a1[6]; ParsePosition parsePosition1 = new ParsePosition(0); ParsePosition parsePosition2 = new ParsePosition(0); CallRecord call = new CallRecord(); if (simpleDateFormat.parse(time1, parsePosition1) != null && simpleDateFormat.parse(time2, parsePosition2) != null) { Date StartTime = simpleDateFormat.parse(time1); Date EndTime = simpleDateFormat.parse(time2); call.setStartTime(StartTime); call.setEndTime(EndTime); if (p >= 0) { if (a1[2].matches("0791")) { user.get(p).getUserRecords().addCallingInCityRecords(call); } else if (a1[2].matches("079[0-9]") || a1[2].matches("0701")) { user.get(p).getUserRecords().addCallingInProvinceRecords(call); } else { user.get(p).getUserRecords().addCallingInLandRecords(call); } } if (o >= 0) { if (!a1[2].matches("079[0-9]") && !a1[2].matches("0701")) { user.get(o).getUserRecords().addconversation5(call); } } } } else if (check.checkOut5()) { String[] a1 = a.split(" "); String[] a2 = a1[0].split("-"); int p = -1; for (int i = 0; i < user.size(); i++) { if (Objects.equals(a2[1], user.get(i).getNumber())) p = i; } if (p >= 0) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); simpleDateFormat.setLenient(false); String time1 = a1[3] + " " + a1[4]; String time2 = a1[5] + " " + a1[6]; ParsePosition parsePosition1 = new ParsePosition(0); ParsePosition parsePosition2 = new ParsePosition(0); CallRecord call = new CallRecord(); if (simpleDateFormat.parse(time1, parsePosition1) != null && simpleDateFormat.parse(time2, parsePosition2) != null) { Date StartTime = simpleDateFormat.parse(time1); Date EndTime = simpleDateFormat.parse(time2); call.setStartTime(StartTime); call.setEndTime(EndTime); if (a1[1].matches("0791")) { if (a1[2].matches("0791[0-9]{7,8}")) user.get(p).getUserRecords().addconversation1(call); else if (a1[2].matches("079[0-9][0-9]{7,8}")) user.get(p).getUserRecords().addconversation2(call); else user.get(p).getUserRecords().addconversation3(call); } else if (a1[1].matches("079[0-9]") || a1[1].matches("0701")) { user.get(p).getUserRecords().addconversation4(call); } else { user.get(p).getUserRecords().addconversation6(call); } } } } else if (check.checkOut6()) { String[] a1 = a.split(" "); String[] a2 = a1[0].split("-"); int p = -1; int q = -1; for (int i = 0; i < user.size(); i++) { if (Objects.equals(a2[1], user.get(i).getNumber())) p = i; } for (int i = 0; i < user.size(); i++) { if (Objects.equals(a1[2], user.get(i).getNumber())) q = i; } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); simpleDateFormat.setLenient(false); String time1 = a1[4] + " " + a1[5]; String time2 = a1[6] + " " + a1[7]; ParsePosition parsePosition1 = new ParsePosition(0); ParsePosition parsePosition2 = new ParsePosition(0); CallRecord call = new CallRecord(); if (simpleDateFormat.parse(time1, parsePosition1) != null && simpleDateFormat.parse(time2, parsePosition2) != null) { Date StartTime = simpleDateFormat.parse(time1); Date EndTime = simpleDateFormat.parse(time2); call.setStartTime(StartTime); call.setEndTime(EndTime); if (p >= 0) { if (a1[1].matches("0791")) { if (a1[3].matches("0791")) user.get(p).getUserRecords().addconversation1(call); else if (a1[3].matches("079[0-9]") || a1[3].matches("0701")) user.get(p).getUserRecords().addconversation2(call); else user.get(p).getUserRecords().addconversation3(call); } else if (a1[1].matches("079[0-9]") || a1[1].matches("0701")) { user.get(p).getUserRecords().addconversation4(call); } else { user.get(p).getUserRecords().addconversation6(call); } } }if(q>=0){ if(!a1[3].matches("079[0-9]")&&!a1[3].matches("0701")){ user.get(q).getUserRecords().addconversation5(call); } } } } } for (int i = 1; i <= user.size() - 1; i++) { for (int j = 0; j <= user.size() - 1 - i; j++) { if (user.get(j).getNumber().compareTo(user.get(j + 1).getNumber()) > 0) { Collections.swap(user, j, j + 1); } } } for (int i = 0; i < user.size(); i++) { if (user.get(i).gettype() == 0) { System.out.println(user.get(i).getNumber() + " " + String.format("%.1f", user.get(i).getChargeMode().calCost(user.get(i).getUserRecords())) + " " + String.format("%.1f", user.get(i).calBalance())); } else { System.out.println(user.get(i).getNumber() + " " + String.format("%.1f", user.get(i).getChargeMode().calCost(user.get(i).getUserRecords())) + " " + String.format("%.1f", user.get(i).calBalance1())); } } } }class Check { private String a; public Check(String a) { super(); this.a = a; } // //市内拨打市内 // private ArrayList<CallRecord> conversation2 = new ArrayList<CallRecord>();//市内拨打省内 // private ArrayList<CallRecord> conversation3 = new ArrayList<CallRecord>();//市内拨打国内 // private ArrayList<CallRecord> conversation4 = new ArrayList<CallRecord>();//省内漫游拨打 // private ArrayList<CallRecord> conversation5 = new ArrayList<CallRecord>();//省外漫游接听 // private ArrayList<CallRecord> conversation6 = new ArrayList<CallRecord>();//省外漫游拨打 String regex1 = "u-0791[0-9]{7,8} 0"; String regex2 = "u-1[0-9]{10} 1"; String regex3 = "t-0[0-9]{9,11} 0[0-9]{9,11} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}:[0-9]{2}:[0-9]{2}"; String regex4 = "t-0791[0-9]{7,8} 1[0-9]{10} 0[0-9]{2,3} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}:[0-9]{2}:[0-9]{2}"; String regex5 = "t-1[0-9]{10} 0[0-9]{2,3} 0[0-9]{9,11} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4}.([1-9]||1[0-2]).([1-9]||[1-3][0-9]) [0-9]{2}:[0-9]{2}:[0-9]{2}"; String regex6 = "t-1[0-9]{10} 0[0-9]{2,3} 1[0-9]{10} 0[0-9]{2,3} ((([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?[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s((([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])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"; public boolean checkOut() { if (a.matches(regex1)) { return true; } else if (a.matches(regex2)) { return true; } else if (a.matches(regex3)) { return true; } else if (a.matches(regex4)) { return true; } else if (a.matches(regex5)) { return true; } else if (a.matches(regex6)) { return true; } else return false; } public boolean checkOut1() { if (a.matches(regex1)) { return true; } else { return false; } } public boolean checkOut2() { if (a.matches(regex2)) { return true; } else { return false; } } public boolean checkOut3() { if (a.matches(regex3)) { return true; } else { return false; } } public boolean checkOut4() { if (a.matches(regex4)) { return true; } else { return false; } } public boolean checkOut5() { if (a.matches(regex5)) { return true; } else { return false; } } public boolean checkOut6() { if (a.matches(regex6)) { return true; } else { return false; } } public String getnumber1() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); return number1[1]; } public String getnumber2() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); return number1[1]; } public String getTime1() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); String Time1 = number[2] + " " + number[3]; return Time1; } public String getTime2() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); String Time2 = number[4] + " " + number[5]; return Time2; } } class LandlinePhoneCharging extends ChargeMode { LandPhoneInCityRule Rule1 = new LandPhoneInCityRule(); LandPhoneInProvinceRule Rule2 = new LandPhoneInProvinceRule(); LandPhoneInLandRule Rule3 = new LandPhoneInLandRule(); conversation1Rule Rule4 = new conversation1Rule(); conversation2Rule Rule5 = new conversation2Rule(); conversation3Rule Rule6 = new conversation3Rule(); conversation4Rule Rule7 = new conversation4Rule(); conversation5Rule Rule8 = new conversation5Rule(); conversation6Rule Rule9 = new conversation6Rule(); @Override public double calCost(UserRecords userRecords) { return Rule1.calCost(userRecords.getCallingInCityRecords()) + Rule2.calCost(userRecords.getCallingInProvinceRecords()) + Rule3.calCost(userRecords.getCallingInLandRecords()) + Rule4.calCost(userRecords.getconversation1()) + Rule5.calCost(userRecords.getconversation2()) + Rule6.calCost(userRecords.getconversation3()) + Rule7.calCost(userRecords.getconversation4()) + Rule8.calCost(userRecords.getconversation5()) + Rule9.calCost(userRecords.getconversation6()); } @Override public double getMonthlyRent() { double monthmoney = 20; return monthmoney; } } class LandPhoneInCityRule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for (int i = 0; i < callRecords.size(); i++) { sum += callRecords.get(i).getOfTime() * 0.1; } return sum; } } class LandPhoneInLandRule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for (int i = 0; i < callRecords.size(); i++) { sum += callRecords.get(i).getOfTime() * 0.6; } return sum; } } class LandPhoneInProvinceRule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for (int i = 0; i < callRecords.size(); i++) { sum += callRecords.get(i).getOfTime() * 0.3; } return sum; } } class conversation1Rule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for (int i = 0; i < callRecords.size(); i++) { sum += callRecords.get(i).getOfTime() * 0.1; } return sum; } } class conversation2Rule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for (int i = 0; i < callRecords.size(); i++) { sum += callRecords.get(i).getOfTime() * 0.2; } return sum; } } class conversation3Rule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for (int i = 0; i < callRecords.size(); i++) { sum += callRecords.get(i).getOfTime() * 0.3; } return sum; } } class conversation4Rule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for (int i = 0; i < callRecords.size(); i++) { sum += callRecords.get(i).getOfTime() * 0.3; } return sum; } } class conversation5Rule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for (int i = 0; i < callRecords.size(); i++) { sum += callRecords.get(i).getOfTime() * 0.3; } return sum; } } class conversation6Rule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum = 0; for (int i = 0; i < callRecords.size(); i++) { sum += callRecords.get(i).getOfTime() * 0.6; } return sum; } }class UserRecords {private ArrayList<CallRecord> conversation1 = new ArrayList<CallRecord>();// 市内拨打市内 private ArrayList<CallRecord> conversation2 = new ArrayList<CallRecord>();// 市内拨打省内 private ArrayList<CallRecord> conversation3 = new ArrayList<CallRecord>();// 市内拨打国内 private ArrayList<CallRecord> conversation4 = new ArrayList<CallRecord>();// 省内漫游拨打 private ArrayList<CallRecord> conversation5 = new ArrayList<CallRecord>();// 省外漫游接听 private ArrayList<CallRecord> conversation6 = new ArrayList<CallRecord>();// 省外漫游拨打 public ArrayList<CallRecord> getconversation1() { return conversation1; } public ArrayList<CallRecord> getconversation2() { return conversation2; } public ArrayList<CallRecord> getconversation3() { return conversation3; } public ArrayList<CallRecord> getconversation4() { return conversation4; } public ArrayList<CallRecord> getconversation5() { return conversation5; } public ArrayList<CallRecord> getconversation6() { return conversation6; } }
1.设计与分析: ①该提目无需大改,只要把check类里的判断的正则修改,以及打电话的费用的计算。
②该题目给了我们部分类图,就方便我们去设计与理解,我们就应该顺着题目的思路去设计。
③题目给了大部分的类图,但是我们还需要自己去设计一些所需的类。(例如此题的check类)
④对于正则表达式的运用必须熟悉。
⑤对于一些抽象类,也需要设计。
2.踩坑心得:该提目无需大改,只要把check类里的判断的正则修改,以及打电话的费用的计算。
此题需要计算两段时间之间的具体分钟,这里根据题目提示需要用到SimpleDateFormat类,
然后根据"yyyy.MM.dd HH:mm:ss"格式来计算。还有就是判断输入时,我们显然需要判断输入格式,以
及区分为是开户还是打电话,这个很多人是直接在main里头判断,这样后面换格式则需要大改。我们可以设计
一个check类来用于专门判断,方便后面修改。
3.改进建议:步骤过程太为繁琐,可适当简化,并且编译习惯不够好。
7-1 电信计费系列3-短信计费
实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
1、接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。
2、如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。
本题只针对类型3-手机短信计费。
2、逐行输入本月某些用户的短信信息,短信的格式:
m-主叫号码,接收号码,短信内容 (短信内容只能由数字、字母、空格、英文逗号、英文句号组成)
m-18907910010 13305862264 welcome to jiangxi.
m-13305862264 18907910010 thank you.
假设每个用户初始余额是100元。
每条短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、
开户号码非南昌市的号码、自己给自己打电话等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。
本题只考虑短信计费,不考虑通信费用以及月租费。
public class Main { public static void main(String[] args) throws ParseException { // TODO Auto-generated method stub ArrayList<User> user = new ArrayList<User>(); Scanner input = new Scanner(System.in); boolean flag =false; for (;;) { String a = input.nextLine(); if (a.equals("end")) break; Check check = new Check(a); if(check.checkOut()) { //判断是否输入正确 if(a.length()<20) { //第一种输入 for(int i = 0; i < user.size(); i++) { if(check.getnumber1().equals(user.get(i).getNumber())) { flag = true; break; } } if(!flag) { User b = new User(check.getnumber1()); user.add(b); } } else if(a.length()>20){//第二种输入 int x = -5; for(int i = 0; i < user.size(); i++) { if(check.getnumber1().equals(user.get(i).getNumber())) x = i; } if(x>=0) { String[] s=a.split(" ",2); String []b = s[1].split(" ",2); // System.out.println(b[1]); // CallRecord call=new CallRecord(); MessageRecord message=new MessageRecord(); message.setMessage(b[1]); // call.setStartTime(StartTime); // call.setEndTime(EndTime); user.get(x).getUserRecords().addSendMessageRecords(message); } } } } for(int i=1;i<=user.size()-1;i++){ for(int j=0;j<=user.size()-1-i;j++){ if(Double.parseDouble(user.get(j).getNumber())>Double.parseDouble(user.get(j+1).getNumber())){ Collections.swap(user,j,j+1); } } } for(int i=0;i<user.size();i++){ System.out.println(user.get(i).getNumber()+" "+String.format("%.1f",user.get(i).getChargeMode().calCost(user.get(i).getUserRecords())) +" "+String.format("%.1f",user.get(i).calBalance())); } } } abstract class ChargeMode { private 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; } } abstract class ChargeRule{ } class Check { private String a; public Check(String a) { super(); this.a = a; } String regex1 = "u-1[0-9]{10} 3"; String regex2 = "m-[0-9]{11} [0-9]{11} [0-9|a-z|A-Z|\\s|\\.|\\,]+"; // System.out.println(b[1]); public boolean checkOut() { if(a.matches(regex1)) { return true; } else if(a.matches(regex2)){ return true; } else return false; } public String getnumber1() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); return number1[1]; } public String getnumber2() { String[] number = a.split(" "); String[] number1 = number[0].split("-"); return number[1]; } }class LandlinePhoneCharging extends ChargeMode{ SendMessageChargeRule Rule1 = new SendMessageChargeRule(); @Override public double calCost(UserRecords userRecords) { return Rule1.calCost(userRecords.getSendMessageRecords());} @Override public double getMonthlyRent() { double monthmoney=0; return monthmoney; } } class SendMessageChargeRule extends MessageChargeRule{ @Override public double calCost(ArrayList<MessageRecord> messageRecords) { double sum = 0; int t=0; for(int i = 0;i < messageRecords.size();i ++) { for(int n=messageRecords.get(i).getMessage() .length();n>0;n=n-10) { t++; } } if(t>=0&&t<=3) { sum+= t*0.1; }else if(t>3&&t<=5) { sum+= 0.3+(t-3)*0.2; }else { sum+= 0.7+(t-5)*0.3; } return sum; } } class MessageRecord extends CommunicationRecord{ private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } class User { private UserRecords userRecords = new UserRecords(); private double balance = 100; private LandlinePhoneCharging chargeMode = new LandlinePhoneCharging(); private String number; public User(String number) { this.number = number; } public double calBalance() { return getBalance() - calCost() - chargeMode.getMonthlyRent(); } public double calCost() { return chargeMode.calCost(getUserRecords()) ; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(LandlinePhoneCharging chargeMode) { this.chargeMode = chargeMode; } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public double getBalance() { return balance; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } class UserRecords {private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } }
1.设计与分析:①在前两题适当添加代码即可,增加message的计费方式。
②该题目给了我们部分类图,就方便我们去设计与理解,我们就应该顺着题目的思路去设计。
③题目给了大部分的类图,但是我们还需要自己去设计一些所需的类。(例如此题的check类)
④对于正则表达式的运用必须熟悉。
⑤对于一些抽象类,也需要设计。
2.踩坑心得:该提目无需大改,只要把check类里的判断的正则修改,以及发信息的费用的计算。
还有就是判断输入时,我们显然需要判断输入格式,以及区分为是开户还是打电话,这个很多人
是直接在main里头判断,这样后面换格式则需要大改。我们可以设计一个check类来用于专门判断,
方便后面修改。
3.改进建议:步骤过程太为繁琐,可适当简化,并且编译习惯不够好。
5.总结
总结:做一次这样的迭代作业之后,我的最大一个感悟还是,最好在第一次作业就把类设计的非常
完善与简洁,现在我想简洁这个东西大概是java的最大难题。而通过这几次的题目练习,你会发现
在写代码时初期的设计极为重要,这会影响这你后面的修改会增加代码,特别是在迭代。题目中的
有些问题很有意思,就例如第一题中的区号可能是三位或是四位数。还有就是正则表达式,极为重要,
这几题为数不多的不同点就是正则的判断。另外,那个时间类求时间的方法,也表明自我查询资料以及
学习的重要性。
总结bug原因:①对题面理解的疏忽②对自己代码架构细节出现问题(使用错误方法)③不小心写错。

浙公网安备 33010602011771号