前言
最近作业不多,只有三次pta,主要就是座机的迭代和一些比较简单的附加题,主要考察对于继承与多态、封装、正则表达式、和类设计。
同时,这几次作业相比前几个星期的难度提升很大,需要投入更多的时间。
设计与分析
电信计费第一次作业
题目描述如下:

类图如下:

源码如下:
import java.util.ArrayList; import java.util.Date; import java.util.Scanner; import java.text.ParseException; import java.text.SimpleDateFormat; public class Main { public static void main(String[] args) throws ParseException{ Control control = new Control(); control.start(); } } abstract class CallChargeRule extends ChargeRule{ public abstract double calCost (ArrayList<CallRecord> callRecords); } class CallRecord extends CommunicationRecord{ private Date startTime; private Date endTime; private String callingAddressAreaCode; private String answerAddressAreaCode; public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { this.startTime = startTime; this.endTime = endTime; this.callingAddressAreaCode = callingAddressAreaCode; this.answerAddressAreaCode = answerAddressAreaCode; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } abstract class ChargeMode { private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); public ArrayList<ChargeRule> getChargeRules() { return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } public abstract double calCost(UserRecords userRecords); public abstract double getMonthlyRent(); } abstract class ChargeRule { public abstract double calCost (ArrayList<CallRecord> callRecords); } abstract class CommunicationRecord { private String callingNumber; private String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } class Control { Scanner in = new Scanner(System.in); private ArrayList<User> users = new ArrayList<>(); ArrayList<String> areaNums = new ArrayList<>(); public Control(){ areaNums.add("0790"); areaNums.add("0791"); areaNums.add("0792"); areaNums.add("0793"); areaNums.add("0794"); areaNums.add("0795"); areaNums.add("0796"); areaNums.add("0797"); areaNums.add("0798"); areaNums.add("0799"); areaNums.add("0701"); } public void classify() throws ParseException { String line; String type1 = "u-0791\\d{7,8}\\s[0-2]"; String part1 = "t-0791[0-9]{7,8}\\s0[0-9]{9,11}\\s"; String part2 = "(((\\d{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?"; String part3 = "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|1\\d|2[0-8]))))|((("; String part4 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"; String part5 = "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5][0-9])\\s"; String part6 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9]\\d|[0-9][1-9][0-9]{2}|[1-9]\\d{3})\\.((([13578]|1[02])\\.("; String part7 = "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((("; String part8 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"; String part9 = "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"; String type2 = part1 + part2 + part3+ part4+ part5+ part6+ part7+ part8+ part9; do{ line = in.nextLine(); if(line.matches(type1)){ boolean flag = true; String a[] = line.split("-"); String b[] = a[1].split("\\s"); User user = new User(); for(User i:users){ if(i.getNumber().equals(b[0])){ flag = false; } } if(flag){ user.setNumber(b[0]); user.setChargeMode(new LandlinePhoneCharging()); users.add(user); } } else if (line.matches(type2)) { String a[] = line.split("-"); String b[] = a[1].split("\\s"); for(int i = 0;i<users.size();i++){ if(users.get(i).getNumber().equals(b[0])){ String callingAddressAreaCode=""; String answerAddressAreaCode=""; for(int j = 0;j<4;j++){ callingAddressAreaCode += b[0].charAt(j); } for(int j = 0;j<4;j++){ answerAddressAreaCode += b[1].charAt(j); } if(callingAddressAreaCode.equals(answerAddressAreaCode)){ users.get(i).getUserRecords().addAnswerInCityRecords(getCallRecord(b)); } else if (areaNums.contains(callingAddressAreaCode)&&areaNums.contains(answerAddressAreaCode)) { users.get(i).getUserRecords().addAnswerInProvinceRecords(getCallRecord(b)); }else{ users.get(i).getUserRecords().addAnswerInLandRecords(getCallRecord(b)); } } } } }while(!line.equals("end")); } public CallRecord getCallRecord(String s[]) throws ParseException { String callingAddressAreaCode=""; String answerAddressAreaCode=""; for(int i = 0;i<4;i++){ callingAddressAreaCode += s[0].charAt(i); } for(int i = 0;i<4;i++){ answerAddressAreaCode += s[1].charAt(i); } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); Date startTime = simpleDateFormat.parse(s[2]+" "+s[3]); Date endTime = simpleDateFormat.parse(s[4]+" "+s[5]); return new CallRecord(startTime,endTime,callingAddressAreaCode,answerAddressAreaCode); } public void start() throws ParseException { classify(); for(int i=0;i<users.size()-1;i++) { for(int j=0;j<users.size()-1-i;j++) { if(users.get(j).getNumber().compareTo(users.get(j+1).getNumber()) > 0) { User temp=users.get(j); users.set(j,users.get(j+1)); users.set(j+1,temp); } } } for(User i:users){ System.out.printf("%s %.1f %.1f\n",i.getNumber(),i.calCost(),i.calBanlance()); } } } class LandlinePhoneCharging extends ChargeMode{//座机收费 public LandlinePhoneCharging(){ super(); super.getChargeRules().add(new LandPhoneInCityRule()); super.getChargeRules().add(new LandPhoneInProvinceRule()); super.getChargeRules().add(new LandPhoneInlandRule()); } @Override public double calCost(UserRecords userRecords){ return super.getChargeRules().get(0).calCost(userRecords.getAnswerInCityRecords()) + super.getChargeRules().get(1).calCost(userRecords.getAnswerInProvinceRecords()) + super.getChargeRules().get(2).calCost(userRecords.getAnswerInLandRecords()); } @Override public double getMonthlyRent (){ return 20; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; if(n==0){ cost+=0.1; } if(remainder==0){ cost+=n*0.1; }else{ cost += (n+1)*0.1; } } return cost; } } class LandPhoneInlandRule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for (CallRecord i : callRecords) { long remainder = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 % 60; long n = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 / 60; if (n == 0) { cost += 0.6; } if (remainder == 0) { cost += n * 0.6; } else { cost += (n + 1) * 0.6; } } return cost; } } class LandPhoneInProvinceRule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; if(n==0){ cost+=0.3; } if(remainder==0){ cost+=n*0.3; }else{ cost += (n+1)*0.3; } } return cost; } } class MessageRecord { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } class User { private UserRecords userRecords = new UserRecords(); private double balance = 100; private ChargeMode chargeMode; private String number; public User() { } public double calBanlance(){ return balance - calCost() - chargeMode.getMonthlyRent(); } public double calCost(){ return chargeMode.calCost(userRecords); } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } class UserRecords { private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); public void addCallingInCityRecords (CallRecord callRecord){ callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecords (CallRecord callRecord){ callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecords (CallRecord callRecord){ callingInLandRecords.add(callRecord); } public void addAnswerInCityRecords (CallRecord answerRecord){ answerInCityRecords.add(answerRecord); } public void addAnswerInProvinceRecords (CallRecord answerRecord){ answerInProvinceRecords.add(answerRecord); } public void addAnswerInLandRecords (CallRecord answerRecord){ answerInLandRecords.add(answerRecord); } public void addSendMessageRecords (MessageRecord sendMessageRecord){ sendMessageRecords.add(sendMessageRecord); } public void addReceiveMessageRecords (MessageRecord receiveMessageRecord){ receiveMessageRecords.add(receiveMessageRecord); } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public ArrayList<CallRecord> getCallingInProvinceRecords() { return callingInProvinceRecords; } public ArrayList<CallRecord> getCallingInLandRecords() { return callingInLandRecords; } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } }
分析如下:
本题难度不大,但需要耐心去参考题目所给类图和题意。比如说此处针对的是对于南昌市的座机进行开号,所以开户信息区号的正则只需要用“0791”即可,而不需要再判定其他区号。
对于非法输入,时间的合法性是做本题的关键。因为这要涉及到年月日的问题,比如说2月在平年只有28天,所以如果出现2月29日则是非法的。同时,除了二月外的每个月都有固定的天数,超过相应的天数,也是非法的。对于输出需要注意的是保留两位小数和需要排序后在输出。保留两位小数可以先用DecimalFormat,然后再输出,也可以直接在printf中用%.2f,此处我用的是后者。而对于排序,比较用compare to,因为此处是字符串,而遍历可以用for(int i; i < list.size(); i++),也可以用for(Object i:list),我倾向于后者因为更加简便。
电信计费第二次作业
题目描述如下:

类图如下:

源码如下:
import java.util.ArrayList; import java.util.Date; import java.util.Scanner; import java.text.ParseException; import java.text.SimpleDateFormat; public class Main { public static void main(String[] args) throws ParseException{ Control control = new Control(); control.start(); } } class Control { Scanner in = new Scanner(System.in); private ArrayList<User> users = new ArrayList<>(); public Control(){ } public void classify() throws ParseException { String line; String LandPhone = "0\\d{2,3}[0-9]{7,8}\\s"; String MobilePhone = "1\\d{10}\\s0\\d{2,3}\\s"; String part1 = "(((\\d{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?"; String part2 = "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|1\\d|2[0-8]))))|((("; String part3 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"; String part4 = "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5][0-9])\\s"; String part5 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9]\\d|[0-9][1-9][0-9]{2}|[1-9]\\d{3})\\.((([13578]|1[02])\\.("; String part6 = "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((("; String part7 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"; String part8 = "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"; String time = part1 + part2 + part3+ part4+ part5+ part6+ part7+ part8; do{ line = in.nextLine(); if(line.matches("u-0791[0-9]{7,8}\\s0")){ boolean flag = true; String a[] = line.split("-"); String b[] = a[1].split("\\s"); User user = new User(); for(User i:users){ if(i.getNumber().equals(b[0])){ flag = false; break; } } if(flag){ user.setNumber(b[0]); user.setChargeMode(new LandlinePhoneCharging()); users.add(user); } } else if(line.matches("u-1\\d{10}\\s1")){ boolean flag = true; String a[] = line.split("-"); String b[] = a[1].split("\\s"); User user = new User(); for(User i:users){ if(i.getNumber().equals(b[0])){ flag = false; } } if(flag){ user.setNumber(b[0]); user.setChargeMode(new MobilePhoneCharging()); users.add(user); } } else if (line.matches("t-"+LandPhone+LandPhone+time)) {//座机打座机 String a[] = line.split("-"); String b[] = a[1].split("\\s"); String c[] = a[1].split(LandPhone+LandPhone); String d[] = c[1].split("\\s"); for(int i = 0;i<users.size();i++){ if(users.get(i).getNumber().equals(b[0])){ String callingAddressAreaCode=""; String answerAddressAreaCode=""; for(int j = 0;j<4;j++){ callingAddressAreaCode += b[0].charAt(j); } for(int j = 0;j<4;j++){ answerAddressAreaCode += b[1].charAt(j); } //座机拨打 if(callingAddressAreaCode.equals(answerAddressAreaCode)){ users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } else if (AreaNums.get().contains(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); }else{ users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } } } } else if (line.matches("t-"+LandPhone+MobilePhone+time)) {//座机打手机 String a[] = line.split("-"); String b[] = a[1].split("\\s"); String c[] = a[1].split(LandPhone+MobilePhone); String d[] = c[1].split("\\s"); String callingAddressAreaCode=""; String answerAddressAreaCode=b[2]; for(int j = 0;j<4;j++){ callingAddressAreaCode += b[0].charAt(j); } //记录手机省外接听 for(int k = 0;k<users.size();k++){ if(users.get(k).getNumber().equals(b[1])){ if(!AreaNums.get().contains(answerAddressAreaCode)){ users.get(k).getUserRecords().addAnswerInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } break; } } for(int i = 0;i<users.size();i++){ if(users.get(i).getNumber().equals(b[0])){ //记录座机拨打 if(callingAddressAreaCode.equals(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } else if (AreaNums.get().contains(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); }else{ users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } } } } else if (line.matches("t-"+MobilePhone+LandPhone+time)) {//手机打座机 String a[] = line.split("-"); String b[] = a[1].split("\\s"); String c[] = a[1].split(MobilePhone+LandPhone); String d[] = c[1].split("\\s"); String callingAddressAreaCode=b[1]; String answerAddressAreaCode = ""; for(int j = 0;j<4;j++){ answerAddressAreaCode += b[2].charAt(j); } for(int i = 0;i<users.size();i++){ if(users.get(i).getNumber().equals(b[0])){ //记录手机拨打 if(callingAddressAreaCode.equals(answerAddressAreaCode)){ users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } else if (AreaNums.get().contains(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); }else{ users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } } } } else if (line.matches("t-"+MobilePhone+MobilePhone+time)) {//手机打手机 String a[] = line.split("-"); String b[] = a[1].split("\\s"); String c[] = a[1].split(MobilePhone+MobilePhone); String d[] = c[1].split("\\s"); String callingAddressAreaCode=b[1]; String answerAddressAreaCode=b[3]; //记录手机省外接听 for(int k = 0;k<users.size();k++){ if(users.get(k).getNumber().equals(b[2])){ if(!AreaNums.get().contains(answerAddressAreaCode)){ users.get(k).getUserRecords().addAnswerInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } break; } } for(int i = 0;i<users.size();i++){ if(users.get(i).getNumber().equals(b[0])){ //记录手机拨打 if(callingAddressAreaCode.equals(answerAddressAreaCode)){ users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } else if (AreaNums.get().contains(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); }else{ users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } } } } }while(!line.equals("end")); } public CallRecord getCallRecord(String callingAddressAreaCode,String answerAddressAreaCode,String d[]) throws ParseException { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); Date startTime = simpleDateFormat.parse(d[0]+" "+d[1]); Date endTime = simpleDateFormat.parse(d[2]+" "+d[3]); return new CallRecord(startTime,endTime,callingAddressAreaCode,answerAddressAreaCode); } public void start() throws ParseException { classify(); for(int i=0;i<users.size()-1;i++) { for(int j=0;j<users.size()-1-i;j++) { if(users.get(j).getNumber().compareTo(users.get(j+1).getNumber()) > 0) { User temp=users.get(j); users.set(j,users.get(j+1)); users.set(j+1,temp); } } } for(User i:users){ System.out.printf("%s %.1f %.1f\n",i.getNumber(),i.calCost(),i.calBanlance()); } } } class AnswerChargeRule extends ChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; if(n==0){ cost+=0.3; } if(remainder==0){ cost+=n*0.3; }else{ cost += (n+1)*0.3; } } return cost; } } class AreaNums { static ArrayList<String> areaNums = new ArrayList<>(); public AreaNums(){ } public static ArrayList get(){ areaNums.add("0790"); areaNums.add("0791"); areaNums.add("0792"); areaNums.add("0793"); areaNums.add("0794"); areaNums.add("0795"); areaNums.add("0796"); areaNums.add("0797"); areaNums.add("0798"); areaNums.add("0799"); areaNums.add("0701"); return areaNums; } } abstract class CallChargeRule extends ChargeRule{ public abstract double calCost (ArrayList<CallRecord> callRecords); } class CallRecord extends CommunicationRecord{ private Date startTime; private Date endTime; private String callingAddressAreaCode; private String answerAddressAreaCode; public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { this.startTime = startTime; this.endTime = endTime; this.callingAddressAreaCode = callingAddressAreaCode; this.answerAddressAreaCode = answerAddressAreaCode; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } abstract class ChargeMode { private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); public ArrayList<ChargeRule> getChargeRules() { return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } public abstract double calCost(UserRecords userRecords); public abstract double getMonthlyRent(); } abstract class ChargeRule { public abstract double calCost (ArrayList<CallRecord> callRecords); } abstract class CommunicationRecord { private String callingNumber; private String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } class LandlinePhoneCharging extends ChargeMode{//座机收费 public LandlinePhoneCharging(){ super(); super.getChargeRules().add(new LandPhoneInCityRule()); super.getChargeRules().add(new LandPhoneInProvinceRule()); super.getChargeRules().add(new LandPhoneInLandRule()); } @Override public double calCost(UserRecords userRecords){ return super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) + super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords()) + super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords()); } @Override public double getMonthlyRent (){ return 20; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; if(n==0){ cost+=0.1; } if(remainder==0){ cost+=n*0.1; }else{ cost += (n+1)*0.1; } } return cost; } } class LandPhoneInLandRule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for (CallRecord i : callRecords) { long remainder = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 % 60; long n = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 / 60; if (n == 0) { cost += 0.6; } if (remainder == 0) { cost += n * 0.6; } else { cost += (n + 1) * 0.6; } } return cost; } } class LandPhoneInProvinceRule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; if(n==0){ cost+=0.3; } if(remainder==0){ cost+=n*0.3; }else{ cost += (n+1)*0.3; } } return cost; } } class MessageRecord { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } class MobilePhoneCharging extends ChargeMode{//手机收费 public MobilePhoneCharging(){ super(); super.getChargeRules().add(new MobilePhoneInCityRule()); super.getChargeRules().add(new MobilePhoneInProvinceRule()); super.getChargeRules().add(new MobilePhoneInLandRule()); super.getChargeRules().add(new AnswerChargeRule()); } @Override public double calCost(UserRecords userRecords){ return super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) + super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords()) + super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords()) + super.getChargeRules().get(3).calCost(userRecords.getAnswerInLandRecords()); } @Override public double getMonthlyRent (){ return 15; } } class MobilePhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; double charge; if(i.getCallingAddressAreaCode().equals("0791")){ charge = 0.1; } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) { charge = 0.3; }else{ charge = 0.6; } if(n==0){ cost+=charge; } if(remainder==0){ cost+=n*charge; }else{ cost += (n+1)*charge; } } return cost; } } class MobilePhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; double charge; if(i.getCallingAddressAreaCode().equals("0791")){ charge = 0.3; } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) { charge = 0.3; }else{ charge = 0.6; } if(n==0){ cost+=charge; } if(remainder==0){ cost+=n*charge; }else{ cost += (n+1)*charge; } } return cost; } } class MobilePhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; double charge; if(i.getCallingAddressAreaCode().equals("0791")){ charge = 0.2; } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) { charge = 0.3; }else{ charge = 0.6; } if(n==0){ cost+=charge; } if(remainder==0){ cost+=n*charge; }else{ cost += (n+1)*charge; } } return cost; } } class User { private UserRecords userRecords = new UserRecords(); private double balance = 100; private ChargeMode chargeMode; private String number; public User() { } public double calBanlance(){ return balance - calCost() - chargeMode.getMonthlyRent(); } public double calCost(){ return chargeMode.calCost(userRecords); } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } class UserRecords { private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); public void addCallingInCityRecords (CallRecord callRecord){ callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecords (CallRecord callRecord){ callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecords (CallRecord callRecord){ callingInLandRecords.add(callRecord); } public void addAnswerInCityRecords (CallRecord answerRecord){ answerInCityRecords.add(answerRecord); } public void addAnswerInProvinceRecords (CallRecord answerRecord){ answerInProvinceRecords.add(answerRecord); } public void addAnswerInLandRecords (CallRecord answerRecord){ answerInLandRecords.add(answerRecord); } public void addSendMessageRecords (MessageRecord sendMessageRecord){ sendMessageRecords.add(sendMessageRecord); } public void addReceiveMessageRecords (MessageRecord receiveMessageRecord){ receiveMessageRecords.add(receiveMessageRecord); } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public ArrayList<CallRecord> getCallingInProvinceRecords() { return callingInProvinceRecords; } public ArrayList<CallRecord> getCallingInLandRecords() { return callingInLandRecords; } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } }
分析如下:
本题是对于上一次作业的一次迭代,最大的变化是增加了手机这个与座机在机制上有很大区别的类型,所以需要为手机用户做一套与座机用户相似的系统,而这就需要用到继承,比如从类图中可以看出,座机收费机制的类和手机收费机制的类都继承于CalChargeRule,提高了的代码的复用性,也为后期的维护提供了便利。同时由于手机用户的收费机制有特殊的漫游机制(省内漫游和省外漫游),所以座机呼叫座机,座机呼叫手机,手机呼叫手机,需要不同的方式录入。对于拨打信息中时间部分的提取,我用split()通过前面部分的正则,将字符串分割为""和时间部分。据我所知,很多同学用的是text(),但我觉得用这个不便于下一次复用,因为时间部分是第几个字符开始是不确定的。
电信计费第三次作业
题目描述如下:

类图如下:

源码如下:
import java.util.ArrayList; import java.util.Date; import java.util.Scanner; import java.text.ParseException; import java.text.SimpleDateFormat; public class Main { public static void main(String[] args) throws ParseException{ Control control = new Control(); control.start(); } } class Control { Scanner in = new Scanner(System.in); private ArrayList<User> users = new ArrayList<>(); public Control(){ } public void classify() throws ParseException { String line; String LandPhone = "0\\d{2,3}[0-9]{7,8}\\s"; String MobilePhone = "1\\d{10}\\s0\\d{2,3}\\s"; String part1 = "(((\\d{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?"; String part2 = "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|1\\d|2[0-8]))))|((("; String part3 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"; String part4 = "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5][0-9])\\s"; String part5 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9]\\d|[0-9][1-9][0-9]{2}|[1-9]\\d{3})\\.((([13578]|1[02])\\.("; String part6 = "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((("; String part7 = "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"; String part8 = "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"; String time = part1 + part2 + part3+ part4+ part5+ part6+ part7+ part8; do{ line = in.nextLine(); if(line.matches("u-0791[0-9]{7,8}\\s0")){ boolean flag = true; String a[] = line.split("-"); String b[] = a[1].split("\\s"); User user = new User(); for(User i:users){ if(i.getNumber().equals(b[0])){ flag = false; break; } } if(flag){ user.setNumber(b[0]); user.setChargeMode(new LandlinePhoneCharging()); users.add(user); } } else if(line.matches("u-1\\d{10}\\s1")){ boolean flag = true; String a[] = line.split("-"); String b[] = a[1].split("\\s"); User user = new User(); for(User i:users){ if(i.getNumber().equals(b[0])){ flag = false; } } if(flag){ user.setNumber(b[0]); user.setChargeMode(new MobilePhoneCharging()); users.add(user); } } else if (line.matches("t-"+LandPhone+LandPhone+time)) {//座机打座机 String a[] = line.split("-"); String b[] = a[1].split("\\s"); String c[] = a[1].split(LandPhone+LandPhone); String d[] = c[1].split("\\s"); for(int i = 0;i<users.size();i++){ if(users.get(i).getNumber().equals(b[0])){ String callingAddressAreaCode=""; String answerAddressAreaCode=""; for(int j = 0;j<4;j++){ callingAddressAreaCode += b[0].charAt(j); } for(int j = 0;j<4;j++){ answerAddressAreaCode += b[1].charAt(j); } //座机拨打 if(callingAddressAreaCode.equals(answerAddressAreaCode)){ users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } else if (AreaNums.get().contains(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); }else{ users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } } } } else if (line.matches("t-"+LandPhone+MobilePhone+time)) {//座机打手机 String a[] = line.split("-"); String b[] = a[1].split("\\s"); String c[] = a[1].split(LandPhone+MobilePhone); String d[] = c[1].split("\\s"); String callingAddressAreaCode=""; String answerAddressAreaCode=b[2]; for(int j = 0;j<4;j++){ callingAddressAreaCode += b[0].charAt(j); } //记录手机省外接听 for(int k = 0;k<users.size();k++){ if(users.get(k).getNumber().equals(b[1])){ if(!AreaNums.get().contains(answerAddressAreaCode)){ users.get(k).getUserRecords().addAnswerInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } break; } } for(int i = 0;i<users.size();i++){ if(users.get(i).getNumber().equals(b[0])){ //记录座机拨打 if(callingAddressAreaCode.equals(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } else if (AreaNums.get().contains(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); }else{ users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } } } } else if (line.matches("t-"+MobilePhone+LandPhone+time)) {//手机打座机 String a[] = line.split("-"); String b[] = a[1].split("\\s"); String c[] = a[1].split(MobilePhone+LandPhone); String d[] = c[1].split("\\s"); String callingAddressAreaCode=b[1]; String answerAddressAreaCode = ""; for(int j = 0;j<4;j++){ answerAddressAreaCode += b[2].charAt(j); } for(int i = 0;i<users.size();i++){ if(users.get(i).getNumber().equals(b[0])){ //记录手机拨打 if(callingAddressAreaCode.equals(answerAddressAreaCode)){ users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } else if (AreaNums.get().contains(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); }else{ users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } } } } else if (line.matches("t-"+MobilePhone+MobilePhone+time)) {//手机打手机 String a[] = line.split("-"); String b[] = a[1].split("\\s"); String c[] = a[1].split(MobilePhone+MobilePhone); String d[] = c[1].split("\\s"); String callingAddressAreaCode=b[1]; String answerAddressAreaCode=b[3]; //记录手机省外接听 for(int k = 0;k<users.size();k++){ if(users.get(k).getNumber().equals(b[2])){ if(!AreaNums.get().contains(answerAddressAreaCode)){ users.get(k).getUserRecords().addAnswerInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } break; } } for(int i = 0;i<users.size();i++){ if(users.get(i).getNumber().equals(b[0])){ //记录手机拨打 if(callingAddressAreaCode.equals(answerAddressAreaCode)){ users.get(i).getUserRecords().addCallingInCityRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } else if (AreaNums.get().contains(answerAddressAreaCode)) { users.get(i).getUserRecords().addCallingInProvinceRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); }else{ users.get(i).getUserRecords().addCallingInLandRecords(getCallRecord(callingAddressAreaCode,answerAddressAreaCode,d)); } } } } }while(!line.equals("end")); } public CallRecord getCallRecord(String callingAddressAreaCode,String answerAddressAreaCode,String d[]) throws ParseException { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); Date startTime = simpleDateFormat.parse(d[0]+" "+d[1]); Date endTime = simpleDateFormat.parse(d[2]+" "+d[3]); return new CallRecord(startTime,endTime,callingAddressAreaCode,answerAddressAreaCode); } public void start() throws ParseException { classify(); for(int i=0;i<users.size()-1;i++) { for(int j=0;j<users.size()-1-i;j++) { if(users.get(j).getNumber().compareTo(users.get(j+1).getNumber()) > 0) { User temp=users.get(j); users.set(j,users.get(j+1)); users.set(j+1,temp); } } } for(User i:users){ System.out.printf("%s %.1f %.1f\n",i.getNumber(),i.calCost(),i.calBanlance()); } } } class AnswerChargeRule extends ChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; if(n==0){ cost+=0.3; } if(remainder==0){ cost+=n*0.3; }else{ cost += (n+1)*0.3; } } return cost; } } class AreaNums { static ArrayList<String> areaNums = new ArrayList<>(); public AreaNums(){ } public static ArrayList get(){ areaNums.add("0790"); areaNums.add("0791"); areaNums.add("0792"); areaNums.add("0793"); areaNums.add("0794"); areaNums.add("0795"); areaNums.add("0796"); areaNums.add("0797"); areaNums.add("0798"); areaNums.add("0799"); areaNums.add("0701"); return areaNums; } } abstract class CallChargeRule extends ChargeRule{ public abstract double calCost (ArrayList<CallRecord> callRecords); } class CallRecord extends CommunicationRecord{ private Date startTime; private Date endTime; private String callingAddressAreaCode; private String answerAddressAreaCode; public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { this.startTime = startTime; this.endTime = endTime; this.callingAddressAreaCode = callingAddressAreaCode; this.answerAddressAreaCode = answerAddressAreaCode; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } abstract class ChargeMode { private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); public ArrayList<ChargeRule> getChargeRules() { return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } public abstract double calCost(UserRecords userRecords); public abstract double getMonthlyRent(); } abstract class ChargeRule { public abstract double calCost (ArrayList<CallRecord> callRecords); } abstract class CommunicationRecord { private String callingNumber; private String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } class LandlinePhoneCharging extends ChargeMode{//座机收费 public LandlinePhoneCharging(){ super(); super.getChargeRules().add(new LandPhoneInCityRule()); super.getChargeRules().add(new LandPhoneInProvinceRule()); super.getChargeRules().add(new LandPhoneInLandRule()); } @Override public double calCost(UserRecords userRecords){ return super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) + super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords()) + super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords()); } @Override public double getMonthlyRent (){ return 20; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; if(n==0){ cost+=0.1; } if(remainder==0){ cost+=n*0.1; }else{ cost += (n+1)*0.1; } } return cost; } } class LandPhoneInLandRule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for (CallRecord i : callRecords) { long remainder = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 % 60; long n = (i.getEndTime().getTime() - i.getStartTime().getTime()) / 1000 / 60; if (n == 0) { cost += 0.6; } if (remainder == 0) { cost += n * 0.6; } else { cost += (n + 1) * 0.6; } } return cost; } } class LandPhoneInProvinceRule extends CallChargeRule { @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; if(n==0){ cost+=0.3; } if(remainder==0){ cost+=n*0.3; }else{ cost += (n+1)*0.3; } } return cost; } } class MessageRecord { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } class MobilePhoneCharging extends ChargeMode{//手机收费 public MobilePhoneCharging(){ super(); super.getChargeRules().add(new MobilePhoneInCityRule()); super.getChargeRules().add(new MobilePhoneInProvinceRule()); super.getChargeRules().add(new MobilePhoneInLandRule()); super.getChargeRules().add(new AnswerChargeRule()); } @Override public double calCost(UserRecords userRecords){ return super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) + super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords()) + super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords()) + super.getChargeRules().get(3).calCost(userRecords.getAnswerInLandRecords()); } @Override public double getMonthlyRent (){ return 15; } } class MobilePhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; double charge; if(i.getCallingAddressAreaCode().equals("0791")){ charge = 0.1; } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) { charge = 0.3; }else{ charge = 0.6; } if(n==0){ cost+=charge; } if(remainder==0){ cost+=n*charge; }else{ cost += (n+1)*charge; } } return cost; } } class MobilePhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; double charge; if(i.getCallingAddressAreaCode().equals("0791")){ charge = 0.3; } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) { charge = 0.3; }else{ charge = 0.6; } if(n==0){ cost+=charge; } if(remainder==0){ cost+=n*charge; }else{ cost += (n+1)*charge; } } return cost; } } class MobilePhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double cost=0; for(CallRecord i:callRecords){ long remainder = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000%60; long n = (i.getEndTime().getTime()-i.getStartTime().getTime())/1000/60; double charge; if(i.getCallingAddressAreaCode().equals("0791")){ charge = 0.2; } else if (AreaNums.get().contains(i.getCallingAddressAreaCode())) { charge = 0.3; }else{ charge = 0.6; } if(n==0){ cost+=charge; } if(remainder==0){ cost+=n*charge; }else{ cost += (n+1)*charge; } } return cost; } } class User { private UserRecords userRecords = new UserRecords(); private double balance = 100; private ChargeMode chargeMode; private String number; public User() { } public double calBanlance(){ return balance - calCost() - chargeMode.getMonthlyRent(); } public double calCost(){ return chargeMode.calCost(userRecords); } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } class UserRecords { private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); public void addCallingInCityRecords (CallRecord callRecord){ callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecords (CallRecord callRecord){ callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecords (CallRecord callRecord){ callingInLandRecords.add(callRecord); } public void addAnswerInCityRecords (CallRecord answerRecord){ answerInCityRecords.add(answerRecord); } public void addAnswerInProvinceRecords (CallRecord answerRecord){ answerInProvinceRecords.add(answerRecord); } public void addAnswerInLandRecords (CallRecord answerRecord){ answerInLandRecords.add(answerRecord); } public void addSendMessageRecords (MessageRecord sendMessageRecord){ sendMessageRecords.add(sendMessageRecord); } public void addReceiveMessageRecords (MessageRecord receiveMessageRecord){ receiveMessageRecords.add(receiveMessageRecord); } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public ArrayList<CallRecord> getCallingInProvinceRecords() { return callingInProvinceRecords; } public ArrayList<CallRecord> getCallingInLandRecords() { return callingInLandRecords; } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } }
分析如下:
本题虽然是对于上一次的迭代,但上一次的电话收费根本没有用到,只需要单独设计短信收费机制即可。虽然看起来比上一次简单,但还是有很多点需要注意,首先最为重要的是要理解短信的收费机制。我一开始并没有理解,误认为收费的叠加只针对每一次短信的发送,而不是总体。当我理解收费叠加机制是针对与总体时,我尝试将每一次发送的内容加起来成为一条长短信,如何根据每十个字符一条短信来计算短信条数,最后根据收费叠加机制计算,但这也是错误的。因为在一条短信发送中,可以有多条短信,同时在一次短信发送中,小于十个字符要算一条短信。所以需要根据每次短信的发送来单独计算条数。所以最终的方案是先单独算出每次发送的条数,然后累加得到短信总条数,然后再根据收费叠加机制计算总费用。
踩坑心得
相比之前一看到题目就动手,在这几次作业中,我先进行大致的类设计再进行具体的完善和实现。这样的思路让我相比之前效率提升了很多,也让认识类设计的重要性。
内容总结
最近期末将近,考试繁多,故题量有所下降,难度也没之前高了,但我还是从中收获了很多。对于继承与多态、封装、正则表达式的理解和运用更加深入,对于错误原因的分析能力也得到了增长。
浙公网安备 33010602011771号