Java題目集6~8總結Blog
一、前言
題目集六:
知識點:Java基本語法,對類的繼承、抽象以及多型和容器的應用。
題量:較少。
難度:難。
題目集七:
知識點:Java基本語法,類的設計、繼承和容器及其容器中排序;迭代器的有關用法。
題量:適中。
難度:較難。
題目集八:
知識點:類的繼承以及容器的相關用法;內部類的使用;多型的使用。
題量:適中。
難度:較難。
二、設計與分析
題目集六:
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元。
每條通訊資訊單獨計費後累加,不是將所有時間累計後統一計費。
格式:號碼+英文空格符+總的話費+英文空格符+餘額
每個使用者一行,使用者之間按號碼字元從小到大排序。
錯誤處理:
輸入資料中出現的不符合格式要求的行一律忽略。
建議類圖:
參見圖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
程式碼思路:首先根據老師給的類圖建立相關的類,以及引用容器。再新增相關的方法完成此次作業。
主要程式碼:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Comparator; import java.util.Scanner; import java.util.Date; 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 CommunicationRecord { protected String callingNumber; protected String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } class CallRecord extends CommunicationRecord{ private Date startTime; private Date endTime; private String callingAddressAreaCode; private String answerAddressAreaCode; public 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 ChargeRule { } abstract class CallChargeRule extends ChargeRule{ public abstract double calCost(ArrayList<CallRecord> callRecords); } class LandPhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long interval;//通話時長 double cost = 0; for(int i = 0; i < callRecords.size(); i++){ interval = callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime();//得出的時間是毫秒 if(interval % 60000 == 0){ interval = interval / 60000; } else { interval = interval / 60000 +1; } cost = cost + interval*0.6; } return cost; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long interval; double cost = 0; for(int i = 0; i < callRecords.size(); i++){ interval = callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime(); if(interval % 60000 == 0){ interval = interval / 60000; } else { interval = interval / 60000 +1; } cost = cost + interval*0.1; } return cost; } } class LandPhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long interval; double cost = 0; for(int i = 0; i < callRecords.size(); i++){ interval = callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime(); if(interval % 60000 == 0){ interval = interval / 60000; } else { interval = interval / 60000 +1; } cost = cost + interval*0.3; } return cost; } } //固定電話繳費 class LandlinePhoneCharging extends ChargeMode{ double monthlyRent = 20; public LandlinePhoneCharging(){ getChargeRules().add(new LandPhoneInCityRule()); getChargeRules().add(new LandPhoneInProvinceRule()); getChargeRules().add(new LandPhoneInLandRule()); } @Override public double calCost(UserRecords userRecords) { double cost = 0; cost = cost + ((LandPhoneInCityRule)getChargeRules().get(0)).calCost(userRecords.getCallingInCityRecords()); cost = cost + ((LandPhoneInProvinceRule)getChargeRules().get(1)).calCost(userRecords.getCallingInProvinceRecords()); cost = cost + ((LandPhoneInLandRule)getChargeRules().get(2)).calCost(userRecords.getCallingInLandRecords()); return cost; } @Override public double getMonthlyRent() { return monthlyRent; } } class UserRecords { private ArrayList<CallRecord> callingInCityRecords = new ArrayList<>(); private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<>(); private ArrayList<CallRecord> callingInLandRecords = new ArrayList<>(); private ArrayList<CallRecord> answerInCityRecords = new ArrayList<>(); private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<>(); private ArrayList<CallRecord> answerInLandRecords = new ArrayList<>(); private ArrayList<MessageRecord> sendMessageRecord = new ArrayList<>(); private ArrayList<MessageRecord> receiveMessageRecord = new ArrayList<>(); public void addCallingCityRecords(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 addReceiveMessageRecords(MessageRecord messageRecord){ receiveMessageRecord.add(messageRecord); } public void addSendMessageRecords(MessageRecord messageRecord){ sendMessageRecord.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> getSendMessageRecord() { return sendMessageRecord; } public ArrayList<MessageRecord> getReceiveMessageRecord() { return receiveMessageRecord; } } 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 ChargeMode chargeMode; private String number; public void calBalance() { balance = 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 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 Run { ArrayList<User> users = new ArrayList<>(); public void play() { Scanner sc = new Scanner(System.in); String s=null; String[] a; User user= new User(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); int pUserCoincide = 0; while (true) { s = sc.nextLine(); if (s.equals("end")) break; //if(s.length() < 5) continue;//判斷撥號是否符合格式 // if(s.charAt(1) != '-'){ // continue; // } if (s.charAt(0) == 'u') {//使用者增加 if(!s.matches("^u-(1[0-9]{10} 1|0[0-9]{9,11} 0)$")) continue; a = s.substring(2).split(" "); // 判斷號碼位數 if(a[0].length() != 11 && a[0].length() != 12) continue; //判斷撥號使用者是否為同一個 for(int i = 0; i < users.size(); i++){ if(a[0].equals(users.get(i).getNumber())){ pUserCoincide = 1; continue; } } if(pUserCoincide == 1){ pUserCoincide = 0 ; continue; } user.setNumber(a[0]);//設定號碼 //設定收費模式 if (a[1].equals("0")) { user.setChargeMode(new LandlinePhoneCharging()); } users.add(user); } else if (s.charAt(0) == 't') { //String regex5 = "^t-0[0-9]{9,11} 0[0-9]{9,11} [0-9]{4}.[0-9]{1,2}.[0-9]{1,2} [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4}.[0-9]{1,2}.[0-9]{1,2} [0-9]{2}:[0-9]{2}:[0-9]{2}$";//座機打座機 if(!s.matches("^t-0[0-9]{9,11} 0[0-9]{9,11} [0-9]{4}.[0-9]{1,2}.[0-9]{1,2} [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4}.[0-9]{1,2}.[0-9]{1,2} [0-9]{2}:[0-9]{2}:[0-9]{2}$")) continue; a = s.substring(2).split(" "); if(a.length != 6){ continue; } if((a[1].length() != 11 && a[1].length() != 12 && a[1].length() != 10) ||( a[0].length() != 11 && a[0].length() != 12 && a[0].length() != 10)){ continue; } CallRecord callRecord = new CallRecord(); String tempS1 = a[2].concat(" ").concat(a[3]); String tempS2 = a[4].concat(" ").concat(a[5]); if(!isWrongFormat(tempS1) || !isWrongFormat(tempS2)){ continue; } try { callRecord.setStartTime(simpleDateFormat.parse(tempS1)); callRecord.setEndTime(simpleDateFormat.parse(tempS2)); } catch (ParseException e) { continue; } callRecord.setCallingAddressAreaCode(a[0].substring(0, 4)); callRecord.setAnswerAddressAreaCode(a[1].substring(0, 4)); callRecord.setCallingNumber(a[0]); callRecord.setAnswerNumber(a[1]); if(callRecord.getStartTime().compareTo(callRecord.getEndTime()) >= 0){ continue; } for (int i = 0; i < users.size(); i++) { if (callRecord.callingNumber.equals(users.get(i).getNumber())) { if (callRecord.getAnswerAddressAreaCode().equals(callRecord.getCallingNumber().substring(0,4))) { users.get(i).getUserRecords().addCallingCityRecords(callRecord);//區內 } else if (callRecord.getAnswerAddressAreaCode().matches("(079\\d)|(0701)")) { users.get(i).getUserRecords().addCallingInProvinceRecords(callRecord);//省內 } else { users.get(i).getUserRecords().addCallingInLandRecords(callRecord);//內地 } } if (callRecord.answerNumber.equals(users.get(i).getNumber())) { if (callRecord.getAnswerAddressAreaCode().equals("0791")) { users.get(i).getUserRecords().addAnswerInCityRecords(callRecord); } else if (callRecord.getAnswerAddressAreaCode().matches("(079\\d)|(0701)")) { users.get(i).getUserRecords().addAnswerInProvinceRecords(callRecord); } else { users.get(i).getUserRecords().addAnswerInLandRecords(callRecord); } } } } } users.sort(new Comparator<User>() { @Override public int compare(User o1, User o2) { return o1.getNumber().compareTo(o2.getNumber()); } }); for(int i = 0; i < users.size(); i++){ users.get(i).calBalance(); System.out.printf("%s %.1f %.1f\n",users.get(i).getNumber(),users.get(i).calCost(),users.get(i).getBalance()); } } public boolean isWrongFormat(String s){ return s.matches("((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[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 class Main { public static void main(String[] args) { Run run = new Run(); run.play(); } }View Code
圈複雜度分析:
分析:
1.根據題目的類圖,自己建立類的時候有些輕鬆,建立了很多的類,減少了程式碼的冗餘;
2.像相關的ArrayList容器類的使用,通過查詢資料知道其用法。
3.在具體的實現方法中沒有想仔細,導致出現註冊同一使用者的時候出現混亂;
4.在年份的考慮上沒有考慮閏年的計算,導致測試點沒通過。
題目集七:
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元。
每條通訊、簡訊資訊均單獨計費後累加,不是將所有資訊累計後統一計費。
格式:號碼+英文空格符+總的話費+英文空格符+餘額
每個使用者一行,使用者之間按號碼字元從小到大排序。
錯誤處理:
輸入資料中出現的不符合格式要求的行一律忽略。
本題只做格式的錯誤判斷,無需做內容上不合理的判斷,比如同一個電話兩條通訊記錄的時間有重合、開戶號碼非南昌市的號碼等,此類情況都當成正確的輸入計算。但時間的輸入必須符合要求,比如不能輸入2022.13.61 28:72:65。
建議類圖:
參見圖1、2、3:
圖1
圖1中User是使用者類,包括屬性:
userRecords (使用者記錄)、balance(餘額)、chargeMode(計費方式)、number(號碼)。
ChargeMode是計費方式的抽象類:
chargeRules是計費方式所包含的各種計費規則的集合,ChargeRule類的定義見圖3。
getMonthlyRent()方法用於返回月租(monthlyRent)。
UserRecords是使用者記錄類,儲存使用者各種通話、簡訊的記錄,
各種計費規則將使用其中的部分或者全部記錄。
其屬性從上到下依次是:
市內撥打電話、省內(不含市內)撥打電話、省外撥打電話、
市內接聽電話、省內(不含市內)接聽電話、省外接聽電話的記錄
以及傳送簡訊、接收簡訊的記錄。
圖2
圖2中CommunicationRecord是抽象的通訊記錄類:
包含callingNumber撥打號碼、answerNumber接聽號碼兩個屬性。
CallRecord(通話記錄)、MessageRecord(簡訊記錄)是它的子類。CallRecord(通話記錄類)包含屬性:
通話的起始、結束時間以及
撥號地點的區號(callingAddressAreaCode)、接聽地點的區號(answerAddressAreaCode)。
區號用於記錄在哪個地點撥打和接聽的電話。座機無法移動,就是本機區號,如果是手機號,則會有差異。
圖3
圖3是計費規則的相關類,這些類的核心方法是:
calCost(ArrayList<CallRecord> callRecords)。
該方法針根據輸入引數callRecords中的所有記錄計算某使用者的某一項費用;如市話費。
輸入引數callRecords的約束條件:必須是某一個使用者的符合計費規則要求的所有記錄。
SendMessageRule是傳送簡訊的計費規則類,用於計算髮送簡訊的費用。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三個類分別是座機撥打市內、省內、省外電話的計費規則類,用於實現這三種情況的費用計算。
(提示:可以從UserRecords類中獲取各種型別的callRecords)。
注意:以上圖中所定義的類不是限定要求,根據實際需要自行補充或修改。
程式碼思路:這次和上次的差不多,就是增加了移動手機的相關操作,還是根據類圖寫出相關的類,自己也寫了一些自己的類,更方便自己寫程式碼;也更改了同一使用者註冊的問題。
CallChargeRule類:
abstract class CallChargeRule extends ChargeRule { }CallChargeRule
CallRecord類:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; class CallRecord extends CommunicationRecord { private Date startTime; private Date endTime; private String callingAddressAreaCode; private String answerAddressAreaCode; public String getCallType() { String type = ""; if (callingAddressAreaCode.equals("0791")) { type = type.concat("1"); } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) { type = type.concat("2"); } else { type = type.concat("3"); } if (answerAddressAreaCode.equals("0791")) { type = type.concat("1"); } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) { type = type.concat("2"); } else { type = type.concat("3"); } return type; } public CallRecord(String[] inputs) { super(); char type = inputs[0].charAt(0); inputs[0] = inputs[0].substring(2); String sd = null, st = null, ed = null, et = null; if (type == 't') { if (inputs.length == 6) { sd = inputs[2]; st = inputs[3]; ed = inputs[4]; et = inputs[5]; callingAddressAreaCode = inputs[0].substring(0, 4); answerAddressAreaCode = inputs[1].substring(0, 4); } else if (inputs.length == 7) { sd = inputs[3]; st = inputs[4]; ed = inputs[5]; et = inputs[6]; if (inputs[0].charAt(0) != '0') { if (inputs[2].length() == 10) { answerAddressAreaCode = inputs[2].substring(0, 3); } else { answerAddressAreaCode = inputs[2].substring(0, 4); } callingAddressAreaCode = inputs[1]; } else { if (inputs[0].length() == 10) { callingAddressAreaCode = inputs[0].substring(0, 3); } else { callingAddressAreaCode = inputs[0].substring(0, 4); } answerAddressAreaCode = inputs[2]; } } else if (inputs.length == 8) { sd = inputs[4]; st = inputs[5]; ed = inputs[6]; et = inputs[7]; callingAddressAreaCode = inputs[1]; answerAddressAreaCode = inputs[3]; } } else if (type == 'm') { } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault()); try { startTime = simpleDateFormat.parse(sd + " " + st); endTime = simpleDateFormat.parse(ed + " " + et); } catch (ParseException e) { } } public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { super(); 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; } }CallRecord
圈複雜度分析:
chargeMode類:
import java.util.ArrayList; abstract class ChargeMode { protected ArrayList<ChargeRule> chargeRules = new ArrayList<>(); public abstract double calCost(UserRecords userRecords); public abstract double getMonthlyRent(); public ArrayList<ChargeRule> getChargeRules() { return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } }ChargeMode
圈複雜度分析:
ChargeRule類:
abstract class ChargeRule { abstract public double calCost(UserRecords userRecords); }ChargeRule
CommunicationRecord類:
abstract class CommunicationRecord { protected String callingNumber; protected String answerNumbe; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumbe() { return answerNumbe; } public void setAnswerNumbe(String answerNumbe) { this.answerNumbe = answerNumbe; } }CommunicationRecord
圈複雜度分析:
Inputdeal類:
import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; class Inputdeal { public int check(String input) { if (input.matches("[u]-0791[0-9]{7,8}\\s[0]") || input.matches("[u]-1[0-9]{10}\\s[1]")) { return 1; // } else if (input.charAt(0) == 'm') { // return 2; } else if (input.matches("(([t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s)|" + "([t]-0791[0-9]{7,8}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s)|" + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "0[0-9]{9,11}\\s)|" + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\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})\\.(((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])")) { return 2; } return 0; } @SuppressWarnings("unused") private boolean validatet(String string) { if (!string.matches("^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$")) { return false; } return true; } public static boolean validate(String dateString) { // 使用正則表示式 測試 字元 符合 dddd.dd.dd 的格式(d表示數字) Pattern p = Pattern.compile("\\d{4}+[\\.]\\d{1,2}+[\\.]\\d{1,2}+"); Matcher m = p.matcher(dateString); if (!m.matches()) { return false; } // 得到年月日 String[] array = dateString.split("\\."); int year = Integer.valueOf(array[0]); int month = Integer.valueOf(array[1]); int day = Integer.valueOf(array[2]); if (month < 1 || month > 12) { return false; } int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (isLeapYear(year)) { monthLengths[2] = 29; } else { monthLengths[2] = 28; } int monthLength = monthLengths[month]; if (day < 1 || day > monthLength) { return false; } return true; } /** 是否是閏年 */ private static boolean isLeapYear(int year) { return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); } public boolean judge(String input) { return false; } public void writeUser(ArrayList<User> users, String input) { User usernew = new User(); String[] inputs = input.split(" "); String num = inputs[0].substring(2); for (User i : users) { if (i.getNumber().equals(num)) { return; } } usernew.setNumber(num); int mode = Integer.parseInt(inputs[1]); if (mode == 0) { usernew.setChargeMode(new LandlinePhoneCharging()); } else if (mode == 1) { usernew.setChargeMode(new MobilePhoneCharging()); } users.add(usernew); } public void writeRecord(ArrayList<User> users, String input) { String[] inputs = input.split(" "); User callu = null, answeru = null; CallRecord callrecord = new CallRecord(inputs); if (input.charAt(0) == 't') { String out = inputs[0]; String in = ""; if (inputs.length == 6) { in = inputs[1]; } else if (inputs.length == 7) { in = inputs[1]; } else if (inputs.length == 8) { in = inputs[2]; } for (User i : users) { if (i.getNumber().equals(out)) { callu = i; } if (i.getNumber().equals(in)) { answeru = i; } if (callu != null && answeru != null) { break; } } if (callu != null) { if (callrecord.getCallType().matches("^1[1-3]$")) { callu.getUserRecords().addCallingInCityRecords(callrecord); } else if (callrecord.getCallType().matches("^2[1-3]$")) { callu.getUserRecords().addCallingInProvinceRecords(callrecord); } else { callu.getUserRecords().addCallingInLandRecords(callrecord); } } if (answeru != null) { if (callrecord.getCallType().matches("^[1-3]1$")) { answeru.getUserRecords().addAnswerInCityRecords(callrecord); } else if (callrecord.getCallType().matches("^[1-3]2$")) { answeru.getUserRecords().aaddAnswerInProvinceRecords(callrecord); } else { answeru.getUserRecords().addAnswerInLandRecords(callrecord); } } } else if (input.charAt(0) == 'm') { } } }Inputdeal
圈複雜度分析:
LandlinePhoneCharging類:
class LandlinePhoneCharging extends ChargeMode { private double monthlyRent = 20; public LandlinePhoneCharging() { super(); chargeRules.add(new LandPhoneInCityRule()); chargeRules.add(new LandPhoneInProvinceRule()); chargeRules.add(new LandPhoneInlandRule()); } @Override public double calCost(UserRecords userRecords) { double sumCost = 0; for (ChargeRule rule : chargeRules) { sumCost += rule.calCost(userRecords); } return sumCost; } @Override public double getMonthlyRent() { return monthlyRent; } }LandlinePhoneCharging
圈複雜度分析:
LandPhoneInCityRule類:
class LandPhoneInCityRule extends CallChargeRule { @Override public double calCost(UserRecords userRecords) { double sumCost = 0; for (CallRecord call : userRecords.getCallingInCityRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } if (call.getCallType().equals("11")) { sumCost += distanceM * 0.1; } else if (call.getCallType().equals("12")) { sumCost += distanceM * 0.3; } else if (call.getCallType().equals("13")) { sumCost += distanceM * 0.6; } } return sumCost; } }LandPhoneInCityRule
圈複雜度分析:
LandPhoneInlandRule類:
class LandPhoneInlandRule extends CallChargeRule { @Override public double calCost(UserRecords userRecords) { double sumCost = 0; for (CallRecord call : userRecords.getCallingInLandRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } sumCost += distanceM * 0.6; } return sumCost; } }LandPhoneInlandRule
圈複雜度分析:
LandPhoneInProvinceRule類:
class LandPhoneInProvinceRule extends CallChargeRule { @Override public double calCost(UserRecords userRecords) { double sumCost = 0; for (CallRecord call : userRecords.getCallingInProvinceRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } sumCost += distanceM * 0.3; } return sumCost; } }LandPhoneInProvinceRule
圈複雜度分析:
Main 類:
import java.util.ArrayList; import java.util.Comparator; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.text.ParseException; public class Main { public static void main(String[] args) { Outputtool outputtool = new Outputtool(); Inputdeal inputdeal = new Inputdeal(); ArrayList<User> users = new ArrayList<>(); Scanner in = new Scanner(System.in); String input = in.nextLine(); while (!input.equals("end")) { if (1 == inputdeal.check(input)) { inputdeal.writeUser(users, input); } else if (2 == inputdeal.check(input)) { inputdeal.writeRecord(users, input); } input = in.nextLine(); } users.sort(new Comparator<User>() { @Override public int compare(User u1, User u2) { if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') { return -1; } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') { return 1; } if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) { return 1; } else { return -1; } } }); for (User u : users) { System.out.print(u.getNumber() + " "); outputtool.output(u.calCost()); System.out.print(" "); outputtool.output(u.calBalance()); System.out.println(); } } }Main
圈複雜度分析:
MessageRecord類:
class MessageRecord extends CommunicationRecord { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }MessageRecord
圈複雜度分析:
MobilePhoneCharging類:
class MobilePhoneCharging extends ChargeMode { private double monthlyRent = 15; public MobilePhoneCharging() { super(); chargeRules.add(new MobilePhoneInCityRule()); chargeRules.add(new MobilePhoneInProvinceRule()); chargeRules.add(new MobilePhoneInlandRule()); } @Override public double calCost(UserRecords userRecords) { double sumCost = 0; for (ChargeRule rule : chargeRules) { sumCost += rule.calCost(userRecords); } return sumCost; } @Override public double getMonthlyRent() { return monthlyRent; } }MobilePhoneCharging
MobilePhoneInCityRule類:
class MobilePhoneInCityRule extends CallChargeRule { @Override public double calCost(UserRecords userRecords) { double sumCost = 0; for (CallRecord call : userRecords.getCallingInCityRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } if (call.getCallType().equals("11")) { sumCost += distanceM * 0.1; } else if (call.getCallType().equals("12")) { sumCost += distanceM * 0.2; } else if (call.getCallType().equals("13")) { sumCost += distanceM * 0.3; } } return sumCost; } }MobilePhoneInCityRule
圈複雜度分析:
MobilePhoneInlandRule類:
class MobilePhoneInlandRule extends CallChargeRule { @Override public double calCost(UserRecords userRecords) { double sumCost = 0; for (CallRecord call : userRecords.getCallingInLandRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } sumCost += distanceM * 0.6; } for (CallRecord call : userRecords.getAnswerInLandRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } sumCost += distanceM * 0.3; } return sumCost; } }MobilePhoneInlandRule
圈複雜度分析:
MobilePhoneInProvinceRule類:
class MobilePhoneInProvinceRule extends CallChargeRule { @Override public double calCost(UserRecords userRecords) { double sumCost = 0; for (CallRecord call : userRecords.getCallingInProvinceRecords()) { double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000; if (distanceS < 0) { continue; } double distanceM = (int) distanceS / 60; if (distanceS % 60 != 0) { distanceM += 1; } if (call.getCallType().equals("21")) { sumCost += distanceM * 0.3; } else if (call.getCallType().equals("22")) { sumCost += distanceM * 0.3; } else if (call.getCallType().equals("23")) { sumCost += distanceM * 0.3; } } return sumCost; } }MobilePhoneInProvinceRule
圈複雜度分析:
Outputtool類:
import java.math.BigDecimal; class Outputtool { @SuppressWarnings("deprecation") public void output(double out) { BigDecimal numb = new BigDecimal(out); out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); System.out.print(out); } }Outputtool
圈複雜度分析:
User類:
class User { private UserRecords userRecords = new UserRecords(); private double balance = 100; private ChargeMode chargeMode; private String number; public double calCost() { return chargeMode.calCost(userRecords); } public double calBalance() { return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords); } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } }User
圈複雜度分析:
UserRecords類:
import java.util.ArrayList; 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 aaddAnswerInProvinceRecords(CallRecord callRecord) { answerInProvinceRecords.add(callRecord); } public void addAnswerInLandRecords(CallRecord callRecord) { answerInLandRecords.add(callRecord); } public void addSendMessageRecords(MessageRecord callRecord) { sendMessageRecords.add(callRecord); } public void addReceiveMessageRecords(MessageRecord callRecord) { receiveMessageRecords.add(callRecord); } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) { this.callingInCityRecords = callingInCityRecords; } public ArrayList<CallRecord> getCallingInProvinceRecords() { return callingInProvinceRecords; } public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) { this.callingInProvinceRecords = callingInProvinceRecords; } public ArrayList<CallRecord> getCallingInLandRecords() { return callingInLandRecords; } public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) { this.callingInLandRecords = callingInLandRecords; } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) { this.answerInCityRecords = answerInCityRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) { this.answerInProvinceRecords = answerInProvinceRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) { this.answerInLandRecords = answerInLandRecords; } public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) { this.sendMessageRecords = sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) { this.receiveMessageRecords = receiveMessageRecords; } }UserRecords
圈複雜度分析:
分析:
1.這次的作業是在上次的基礎上增加了針對手機使用者的實時計費,增加了一些方法,難度也不大,按照之前的思路寫;
2.在具體的實現方法中改了之前程式碼中一些錯誤於不足,像爭對同一使用者的註冊時解決策略,這次也要考慮手機使用者在不同的地區是可以用的,所以要創造不同的方法;
3.在年份上添加了閏年的計算,順利完成此次程式碼。
7-2 sdut-Collection-sort--C~K的班級(II)
經過不懈的努力,C~K終於當上了班主任。
現在他要統計班裡學生的名單,但是C~K在教務系統中匯出班級名單時出了問題,發現會有同學的資訊重複,現在他想把重複的同學資訊刪掉,只保留一個,
但是工作量太大了,所以找到了會程式設計的你,你能幫他解決這個問題嗎?
輸入格式:
第一行輸入一個N,代表C~K匯出的名單共有N行(N<100000).
接下來的N行,每一行包括一個同學的資訊,學號 姓名 年齡 性別。
輸出格式:
第一行輸出一個n,代表刪除重複名字後C~K的班級共有幾人。
接下來的n行,輸出每一個同學的資訊,輸出按照學號從小到大的順序。
主要思路:理解題意,使用ArrayList容器類,進行資料的儲存,還要用到排序的演算法。
主要程式碼:
import java.util.Scanner; import java.util.ArrayList; import java.util.Comparator; public class Main { public static void main(String []args) { Scanner in = new Scanner(System.in); int n = Integer.parseInt(in.nextLine()); ArrayList<String> a = new ArrayList<String>(); while(n!=0){ String s = in.nextLine(); if(!a.contains(s)){ a.add(s); } n--; } a.sort(new Comparator<String>() { @Override public int compare(String s1, String s2) { return Integer.parseInt(s1.substring(0, 4))-Integer.parseInt(s2.substring(0, 4)); } }); System.out.println(a.size()); for(int i = 0; i < a.size(); i++) { System.out.println(a.get(i)); } } }View Code
圈複雜度:
分析:
在這次的題目中自己想著用陣列來存取這些資料,但是寫的效果不理想。後來改寫成用ArrayList容器類,剛開始自己沒有使用Comparable介面,結果提交的時候答案總是錯的,在測試樣例中才發現結果沒有排序,後來增加了介面Comparable,順利通過。
題目集八:
7-1 電信計費系列3-簡訊計費
實現一個簡單的電信計費程式,針對手機的簡訊採用如下計費方式:
1、接收簡訊免費,傳送簡訊0.1元/條,超過3條0.2元/條,超過5條0.3元/條。
2、如果一次傳送簡訊的字元數量超過10個,按每10個字元一條簡訊進行計算。
輸入:
輸入資訊包括兩種型別
1、逐行輸入南昌市手機使用者開戶的資訊,每行一個使用者。
格式:u-號碼 計費型別 (計費型別包括:0-座機 1-手機實時計費 2-手機A套餐 3-手機簡訊計費)
例如:u-13305862264 3
座機號碼由區號和電話號碼拼接而成,電話號碼包含7-8位數字,區號最高位是0。
手機號碼由11位數字構成,最高位是1。
本題只針對型別3-手機簡訊計費。
2、逐行輸入本月某些使用者的簡訊資訊,簡訊的格式:
m-主叫號碼,接收號碼,簡訊內容 (簡訊內容只能由數字、字母、空格、英文逗號、英文句號組成)
m-18907910010 13305862264 welcome to jiangxi.
m-13305862264 18907910010 thank you.
注意:以上兩類資訊,先輸入所有開戶資訊,再輸入所有通訊資訊,最後一行以“end”結束。
輸出:
根據輸入的詳細簡訊資訊,計算所有已開戶的使用者的當月簡訊費用(精確到小數點後2位,單位元)。假設每個使用者初始餘額是100元。
每條簡訊資訊均單獨計費後累加,不是將所有資訊累計後統一計費。
格式:號碼+英文空格符+總的話費+英文空格符+餘額
每個使用者一行,使用者之間按號碼字元從小到大排序。
錯誤處理:
輸入資料中出現的不符合格式要求的行一律忽略。
本題只做格式的錯誤判斷,無需做內容上不合理的判斷,比如同一個電話兩條通訊記錄的時間有重合、開戶號碼非南昌市的號碼、自己給自己打電話等,此類情況都當成正確的輸入計算。但時間的輸入必須符合要求,比如不能輸入2022.13.61 28:72:65。
本題只考慮簡訊計費,不考慮通訊費用以及月租費。
建議類圖:
參見圖1、2、3:
圖1
圖1中User是使用者類,包括屬性:
userRecords (使用者記錄)、balance(餘額)、chargeMode(計費方式)、number(號碼)。
ChargeMode是計費方式的抽象類:
chargeRules是計費方式所包含的各種計費規則的集合,ChargeRule類的定義見圖3。
getMonthlyRent()方法用於返回月租(monthlyRent)。
UserRecords是使用者記錄類,儲存使用者各種通話、簡訊的記錄,
各種計費規則將使用其中的部分或者全部記錄。
其屬性從上到下依次是:
市內撥打電話、省內(不含市內)撥打電話、省外撥打電話、
市內接聽電話、省內(不含市內)接聽電話、省外接聽電話的記錄
以及傳送簡訊、接收簡訊的記錄。
圖2
圖2中CommunicationRecord是抽象的通訊記錄類:
包含callingNumber撥打號碼、answerNumber接聽號碼兩個屬性。
CallRecord(通話記錄)、MessageRecord(簡訊記錄)是它的子類。
圖3
圖3是計費規則的相關類,這些類的核心方法是:
calCost(ArrayList callRecords)。
該方法針根據輸入引數callRecords中的所有記錄計算某使用者的某一項費用;如市話費。
輸入引數callRecords的約束條件:必須是某一個使用者的符合計費規則要求的所有記錄。
SendMessageRule是傳送簡訊的計費規則類,用於計算髮送簡訊的費用。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三個類分別是座機撥打市內、省內、省外電話的計費規則類,用於實現這三種情況的費用計算。
(提示:可以從UserRecords類中獲取各種型別的callRecords)。
注意:以上圖中所定義的類不是限定要求,根據實際需要自行補充或修改。
主要思路:這次的題目有前面的基礎寫起來困難還是少,這次根據題目設計了自己所想的簡單類圖,主要寫了main類和user類就可以滿足這次的題目要求,在前面所用到的類上增加了Collections類的使用實現集合元素的排序、查詢替換和複製等操作。
主要程式碼:
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class Main { public static ArrayList<User> users = new ArrayList<User>(); public static void main(String[] args) { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); // String ss = in.nextLine(); while(true) { String str = in.nextLine(); if(!str.equals("end")) { if(str.matches("[u]-1[0-9]{10}\\s[3]")) { String[] s = str.split(" "); User user = new User(s[0].substring(2,s[0].length())); users.add(user); } else if(str.matches("[m]-1[0-9]{10}\\s"+"1[0-9]{10}\\s"+"[a-zA-Z-z0-9-,\\.\\ ]+$" )){ String[] s = str.split(" ",3); users.get(getUser(s[0].substring(2,s[0].length()))).messageRecord.add(s[2]); } } else break; } Collections.sort(users, new Comparator<User>() { public int compare(User user1, User user2) { return user1.getNumber().compareTo(user2.getNumber()); } }); for(int i = 0;i<users.size();i++) { System.out.println(users.get(i).getNumber()+" "+String.format("%.1f", users.get(i).getCalCost())+" "+String.format("%.1f", users.get(i).getCalBalance())); } } //根據號碼找到對應的使用者 public static int getUser(String s) { int n = 0; for(int i = 0;i<users.size();i++) { if(s.equals(users.get(i).getNumber())) { n=i; } } return n; } } class User{ private String number; private double balance = 100; private double calBalance; private double calCost = 0; ArrayList<String> messageRecord = new ArrayList<String>(); public String getNumber() { return this.number; } public User(String number) { super(); this.number = number; } //計算用了多少話費 public double getCalCost() { int n = 0; for(int i = 0;i<this.messageRecord.size();i++){ if(Count(messageRecord.get(i))+n<=3) { this.calCost = this.calCost + 0.1*Count(messageRecord.get(i)); n = n + Count(messageRecord.get(i)); } else if(Count(messageRecord.get(i))+n>3&&Count(messageRecord.get(i))+n<=5) { if(n == 0) { this.calCost = this.calCost + 0.1*3 + (Count(messageRecord.get(i))-3)*0.2; } else if(n==1) { this.calCost = this.calCost + 0.1*2 + (Count(messageRecord.get(i))-2)*0.2; } else if(n==2) { this.calCost = this.calCost + 0.1*1 + (Count(messageRecord.get(i))-1)*0.2; } else if(n>=3) { this.calCost = this.calCost + Count(messageRecord.get(i))*0.2; } n = n + Count(messageRecord.get(i)); } else if(Count(messageRecord.get(i))+n>5) { if(n<=3) this.calCost = this.calCost + (3-n)*0.1+2*0.2+(Count(messageRecord.get(i))-5+n)*0.3; else if(n==4) { this.calCost = this.calCost +0.2+(Count(messageRecord.get(i))-1)*0.3; } else if(n>=5) { this.calCost = this.calCost + Count(messageRecord.get(i))*0.3; } n = n + Count(messageRecord.get(i)); } } return this.calCost; } public double getCalBalance(){ this.calBalance = this.balance - this.calCost; return this.calBalance; } //計算一次話費條數 public int Count(String string) { int n = 0; if(string.length()%10==0) { n = string.length()/10; } else n = string.length()/10 + 1; return n; } }View Code
圈複雜度分析:
分析:
這次的題目在新使用者和舊的使用者的比較上用Collections類來實現,再在號碼的比較上用了介面Comparable來實現,根據號碼找到使用者,計算所花費的費用。
7-3 動物發聲模擬器(多型)
設計一個動物發生模擬器,用於模擬不同動物的叫聲。比如獅吼、虎嘯、狗旺旺、貓喵喵……。
定義抽象類Animal,包含兩個抽象方法:獲取動物類別getAnimalClass()、動物叫shout();
然後基於抽象類Animal定義狗類Dog、貓類Cat和山羊Goat,用getAnimalClass()方法返回不同的動物類別(比如貓,狗,山羊),用shout()方法分別輸出不同的叫聲(比如喵喵、汪汪、咩咩)。
最後編寫AnimalShoutTest類測試,輸出:
貓的叫聲:喵喵
狗的叫聲:汪汪
山羊的叫聲:咩咩
其中,在AnimalShoutTestMain類中,用speak(Animal animal){}方法輸出動物animal的叫聲,在main()方法中呼叫speak()方法,分別輸出貓、狗和山羊物件的叫聲。
請在下面的【】處新增程式碼。
//動物發生模擬器. 請在下面的【】處新增程式碼。
public class AnimalShoutTest2 {
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
Goat goat = new Goat();
speak(cat);
speak(dog);
speak(goat);
}
//定義靜態方法speak()
【】
}
//定義抽象類Animal
【】class Animal{
【】
}
//基於Animal類,定義貓類Cat,並重寫兩個抽象方法
class Cat 【】{
【】
【】
}
//基於Animal類,定義狗類Dog,並重寫兩個抽象方法
class Dog 【】{
【】
【】
}
//基於Animal類,定義山羊類Goat,並重寫兩個抽象方法
class Goat 【】{
【】
【】
}
主要程式碼:
public class Main { public static void main(String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); Goat goat = new Goat(); speak(cat); speak(dog); speak(goat); } // 定義靜態方法speak() private static void speak(Animal animal) { System.out.println(animal.getAnimalClass() + "的叫聲:" + animal.shout()); } } abstract class Animal { public abstract String getAnimalClass(); abstract public String shout(); } class Cat extends Animal{ @Override public String getAnimalClass() { return "貓"; } @Override public String shout() { return "喵喵"; } } class Dog extends Animal { @Override public String getAnimalClass() { return "狗"; } @Override public String shout() { return "汪汪"; } } class Goat extends Animal{ @Override public String getAnimalClass() { return "山羊"; } @Override public String shout() { return "咩咩"; } }View Code
圈複雜度分析:
分析:
這道題目比較簡單,但是對我來說也是比較重要,以前的掌握多型的技術在做這道題目時盡然做錯了,我還沒有掌握真正的精髓,我當時寫動物的叫聲及其名字的方法時,寫在了抽象類,大失誤,要寫在各個子類中去實現,讓我牢固的記住了多型的用法和更多的知識。
三、踩坑心得:
1.在題目集六中的電信系列的計算中,也由於是第一次寫這類題目。對日期這類的時間不是很理解怎麼處理和判斷,時間必須符合"yyyy.MM.dd HH:mm:ss"格式,使用SimpleDateFormat類中的方法會自動檢查。還有Data類中計算不熟悉,第一次直接呼叫了方法,但是結果不對,最後查詢資料getTime()函式得到的是毫秒數,轉化為秒的話需要除以1000。還有在開戶方面需要考慮到是否已經存在,當時沒有考慮導致測試點沒有通過。還有在年份時間的考慮上,我沒有考慮閏年,測試點沒有通過,一定要增加閏年的情況。
2.這幾次的題目集中還有一個自己經常錯誤的一個點就是排序,要熟悉.Comparator介面和ArrayList容器類在排序方面的聯絡和使用。也可以直接用Collections去呼叫sort方法。
四、改進建議:
這幾次的大作業基本都是按照老師給的類圖去寫,自己的思考也不是很多,主要集中在了方法的實現,通過這幾次大作業,給我的感覺就是考慮的總是不夠,考慮的不全面,不仔細。還有對一些類裡面的方法瞭解的不夠,使用起來捉襟見肘,總是要參考他人的,自己才會知道用法是怎麼用的。還有自己的基礎還是很薄弱,繼承自己掌握的差不多了,但是通過做題在多型上自己掌握的不夠,很簡單但是自己小看了,一定要踏踏實實去理解每一個知識點。
五、總結:
Java的最後一次部落格,也意味著這學期的Java課也就結束了。通過這學期的學習,整體上看,收穫還是很多,從最開始學習Java中的迷茫,到後來的不斷認識,慢慢的對Java這門程式設計課有了見解,慢慢的對Java的程式設計也熟悉了,後面做題的時候比較容易。
在後半段(10~16周)中的學習中,自己可以來說掌握了自己能掌握的,對一些軟體建模,設計思路有了一定的基礎,還有在設計過程中應該遵循的規則也瞭解到了。在這後半段也主要交了javaFX的一些基本的常識,還有程式設計方法,思想都有了基本的掌握,每次安排的作業自己也是按照老師的模仿能做出,理解了程式碼的含義。但自己還是要在各個方面都要加強,自己的短板還是明顯,需要不斷地,多次的去寫程式碼來增強自己能力。
學習是一個漫長的過程,需要持之以恆,縱然有困難,但也要學會去克服;雖然Java課結束,但是學習生涯還是繼續,仍需繼續努力奮鬥,開拓自己的一片天地。