6-8次PTA題目集總結
一,前言
1,第六次作業(針對電信計費)
本次作業主要是對類的操作,題目已經給出類圖,類圖裡面已經給了各種方法以及屬性。此次作業涉及了座機的計費方式,市內省內省外怎麼計費。難度偏難,主要是各類之間怎麼實現連線,類的編寫複雜,工程量巨大,需要弄清楚邏輯方可計算。
2,第七次作業(針對電信計費)
再上一次的基礎上增加了一個手機計費方式,座機對座機,座機對手機,手機對座機,手機對手機,需要考慮的方面還是很多的,很多的測試點。難度偏難,難度在於情況多,難以考慮到全部。
3,第八次作業(針對電信計費)
本次是最簡單的一次作業,電信計費只需要簡訊,在以前的類圖中增加簡訊的類,難度偏低。考察的還是類之間的連線。
二,設計與分析(程式碼部分已摺疊)
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
是計費規則的相關類,這些類的核心方法是:
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
設計:
先按照類圖寫出各個類,類的屬性方法。
計費方式分為三個方式,然後這三個方式歸屬於收費方式類,需要新增在記錄數組裡面。通訊記錄又分為電話記錄和簡訊記錄,電話記錄中有一些陣列,例如座機市內通話記錄,省內通話記錄,我們需要根據輸入的記錄放進不同的陣列,根據全部陣列在計算是呼叫不同的收費方式算錢。輸入使用者時我們需要在主函式建立user陣列,存放註冊的使用者,再在對應的使用者記錄數組裡面新增記錄,最後算出費用。這裡難度就在於剛開始的類的邏輯怎麼連起來,連起來之後就比較簡單了,只需要在主函式記錄。
剩下的只需要考慮的全面,拿分還是挺簡單的。
import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Objects; import java.util.Scanner; public class Main { public static void Print(double data) { //保留1位小數 System.out.print((float)(data)); } public static void main(String[] args) { String gre = "t-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s" + "([1-9][0-9]{3}\\.([1-9]|1[0-2])\\.([1-9]|(2[0-9]|3[0-1])) ([0|1]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ?){2}"; String gre1 = "u-0791[0-9]{7,8}\\s[0-2]"; ArrayList<User> user = new ArrayList<>(); Scanner in = new Scanner(System.in); while (true) { String str = in.nextLine(); if (str.equals("end")) break; if (str.matches(gre1)) { String[] array = str.split("-", 2); String[] array1 = array[1].split(" ", 2); String phone_number = array1[0]; boolean has_found = false; for (User value : user) { if (phone_number.equals(value.getNumber())) { has_found = true; break; } } if (has_found) continue; User u = new User(); u.setNumber(phone_number); if (Objects.equals(array1[1], "0")) { u.setChargeMode(new LandlinePhoneCharging()); } user.add(u); } else if (str.matches(gre)) { String[] array = str.split("-", 2); String[] array1 = array[1].split(" "); String phone_number = array1[0]; String phone_number1 = array1[1]; String start_time = array1[2] + " " + array1[3]; String end_time = array1[4] + " " + array1[5]; SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); Date date = null, date1 = null; try { date = sdf.parse(start_time); } catch (ParseException e) { e.printStackTrace(); } try { date1 = sdf.parse(end_time); } catch (ParseException e) { e.printStackTrace(); } for (int i = 0; i < user.size(); i++) { if (phone_number.equals(user.get(i).getNumber())) { CallRecord callRecord = new CallRecord(); callRecord.setStartTime(date); callRecord.setEndTime(date1); callRecord.setCallingAddressAreaCode(phone_number.substring(0, 4)); callRecord.setAnswerAddressAreaCode(phone_number1.substring(0, 4)); if (Objects.equals(callRecord.getAnswerAddressAreaCode(), callRecord.getCallingAddressAreaCode())) { user.get(i).userRecords.addCallingInCityRecords(callRecord); } else if (callRecord.getAnswerAddressAreaCode().matches("(079[0-9]|0701)")) { user.get(i).userRecords.addCallingInProvinceRecords(callRecord); } else { user.get(i).userRecords.addCallingInLandRecords(callRecord); } } } } } user.sort((user1,user2)->user1.getNumber().compareTo(user2.getNumber())); for (int i = 0; i < user.size(); i++) { System.out.print(user.get(i).getNumber() + " "); Print(user.get(i).calCost()); System.out.print(" "); Print(user.get(i).calBalance()); System.out.println(); } } } abstract class CallChargeRule extends ChargeRule{ } class CallRecord extends CommunicationRecord{ Date startTime; Date endTime; String callingAddressAreaCode; String answerAddressAreaCode; public Date getStartTime(){ return startTime; } public void setStartTime(Date startTime){ this.startTime=startTime; } public Date getEndTime(){ return endTime; } public void setEndTime(Date endTime){ this.endTime=endTime; } public String getCallingAddressAreaCode(){ return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode){ this.callingAddressAreaCode=callingAddressAreaCode; } public String getAnswerAddressAreaCode(){ return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode){ this.answerAddressAreaCode=answerAddressAreaCode; } } abstract class ChargeMode { 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 { protected String callingNumber; protected String answerNumber; public String getCallingNumber(){ return callingNumber; } public void setCallingNumber(String callingNumber){ this.callingNumber=callingNumber; } public String getAnswerNumber(){ return answerNumber; } public void setAnswerNumber(String answerNumber){ this.answerNumber=answerNumber; } } class LandlinePhoneCharging extends ChargeMode{ double monthlyRent=20; public LandlinePhoneCharging(){ ChargeRules.add(new LandPhoneInCityRule()); ChargeRules.add(new LandPhoneInProvinceRule()); ChargeRules.add(new LandPhoneInLandRule()); } @Override public double calCost(UserRecords userRecords){//三種收費方式加起來的錢 double sum_cost=0; sum_cost += ChargeRules.get(0).calCost(userRecords.callingInCityRecords); sum_cost += ChargeRules.get(1).calCost(userRecords.callingInProvinceRecords); sum_cost += ChargeRules.get(2).calCost(userRecords.callingInLandRecords); return sum_cost; } @Override public double getMonthlyRent(){ return monthlyRent; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return sum*0.1; } } class LandPhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return sum*0.6; } } class LandPhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return sum*0.3; } } class MessageRecord extends CommunicationRecord{ String message; public String getMessage(){ return null; } public void setMessage(String message){ }; } class User { UserRecords userRecords=new UserRecords(); private final double balance=100; private ChargeMode chargeMode; private String number; public double calBalance(){ return this.balance-this.calCost()-chargeMode.getMonthlyRent(); } public double calCost(){ return chargeMode.calCost(userRecords); } public UserRecords getUserRecords(){ return this.userRecords; } public void setUserRecord(UserRecords userRecords){ this.userRecords=userRecords; } public ChargeMode getChargeMode(){ return chargeMode; } public double getBalance(){ return this.balance; } public void setChargeMode(ChargeMode chargeMode){ this.chargeMode=chargeMode; } public String getNumber(){ return this.number; } public void setNumber(String number){ this.number=number; } } class UserRecords { ArrayList<CallRecord> callingInCityRecords=new ArrayList<CallRecord>(); ArrayList<CallRecord> callingInProvinceRecords=new ArrayList<CallRecord>(); ArrayList<CallRecord> callingInLandRecords=new ArrayList<CallRecord>(); ArrayList<CallRecord> answerInCityRecords=new ArrayList<CallRecord>(); ArrayList<CallRecord> answerInProvinceRecords=new ArrayList<CallRecord>(); ArrayList<CallRecord> answerInLandRecords=new ArrayList<CallRecord>(); ArrayList<MessageRecord> sendMessageRecords=new ArrayList<MessageRecord>(); 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 addSentMessageRecords(MessageRecord sendMessageRecords){} public void addReceiveMessageRecords(MessageRecord receiveMessageRecords){} public ArrayList<MessageRecord> getSendMessageRecords(){return sendMessageRecords;} public ArrayList<MessageRecord> getReceiveMessageRecords(){return receiveMessageRecords;} 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;} }View Code
大部分程式碼都是類圖裡面給出的,來看看類圖吧
程式碼質量:
293行
報表 220
百分比分支報表 8.6
方法呼叫語句 76
帶註釋的百分比行 0.7
類和介面 13
每個類的方法 3.77
每個方法的平均語句數 2.43
最複雜方法的行號 15
最複雜方法的名稱 main.main()
最大複雜度 17
最深塊的行號 69
最大區塊深度 7
平均區塊深度 2.05
平均複雜度 1.39
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)。
注意:以上圖中所定義的類不是限定要求,根據實際需要自行補充或修改。
設計:
這次作業增加了手機計費,可以為座機打手機,座機打座機,手機打座機,手機打手機。從判斷來看就需要考慮的異常全面,計費方式也增加了,手機增加了省內漫遊和省外漫遊,題目較複雜。從獲取使用者資訊方面來看,需要設計五個正則表示式,分別為使用者註冊的,座機打手機,座機打座機,手機打座機,手機打手機(好像這樣比較複雜,我看別人都是一部到位,通話記錄一步到位)。我這樣寫程式碼很長,不建議分五個步驟,因為每個步驟裡面有重複的東西,就是對在省內省外的判斷,以及計算,冗長複雜,容易出錯。對於類而言,我還增加了手機的計費規則,不用說也明白,這樣又更麻煩了一些,搞得又要新增陣列,又要新增規則,類圖錯綜複雜,還不如放在上次的計費計算裡面。
我這種複雜的方法經過漫長的編寫還是拿到了分數
import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Objects; import java.util.Scanner; public class Main { public static void Print(double data) { //保留1位小數 DecimalFormat df = new DecimalFormat("0.0#"); df.setRoundingMode(RoundingMode.HALF_UP); System.out.print(df.format(data)); } public static void main(String[] args) { String l_l = "t-0[0-9]{9,11}\\s" + "0[0-9]{9,11}\\s" + "[0-9]{4}[.](([1-9]{1})|([1]{1}[0-2]{1}))[.]([1-9]|([1-2]{1}[0-9]{1})|(3[0-1])) " + "(([0-1][0-9])|(2[0-3]))[:]([0-5][0-9])[:]([0-5][0-9]) " + "[0-9]{4}[.](([1-9]{1})|([1]{1}[0-2]{1}))[.]([1-9]|([1-2]{1}[0-9]{1})|3[0-1]) " + "(([0-1][0-9])|(2[0-3]))[:]([0-5][0-9])[:]([0-5][0-9])$"; String l_m ="t-0[0-9]{9,11}\\s" + "1[0-9]{10}\\s" +"0[0-9]{2,3}\\s"+ "[0-9]{4}[.](([1-9]{1})|([1]{1}[0-2]{1}))[.]([1-9]|([1-2]{1}[0-9]{1})|(3[0-1])) " + "(([0-1][0-9])|(2[0-3]))[:]([0-5][0-9])[:]([0-5][0-9]) " + "[0-9]{4}[.](([1-9]{1})|([1]{1}[0-2]{1}))[.]([1-9]|([1-2]{1}[0-9]{1})|3[0-1]) " + "(([0-1][0-9])|(2[0-3]))[:]([0-5][0-9])[:]([0-5][0-9])$"; String m_m ="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]{4}[.](([1-9]{1})|([1]{1}[0-2]{1}))[.]([1-9]|([1-2]{1}[0-9]{1})|(3[0-1])) " + "(([0-1][0-9])|(2[0-3]))[:]([0-5][0-9])[:]([0-5][0-9]) " + "[0-9]{4}[.](([1-9]{1})|([1]{1}[0-2]{1}))[.]([1-9]|([1-2]{1}[0-9]{1})|3[0-1]) " + "(([0-1][0-9])|(2[0-3]))[:]([0-5][0-9])[:]([0-5][0-9])$"; String m_l ="t-1[0-9]{10}\\s"+ "0[0-9]{2,3}\\s" + "0[0-9]{9,11}\\s"+ "[0-9]{4}[.](([1-9]{1})|([1]{1}[0-2]{1}))[.]([1-9]|([1-2]{1}[0-9]{1})|(3[0-1])) " + "(([0-1][0-9])|(2[0-3]))[:]([0-5][0-9])[:]([0-5][0-9]) " + "[0-9]{4}[.](([1-9]{1})|([1]{1}[0-2]{1}))[.]([1-9]|([1-2]{1}[0-9]{1})|3[0-1]) " + "(([0-1][0-9])|(2[0-3]))[:]([0-5][0-9])[:]([0-5][0-9])$"; String gre1 = "u-[0-9]{10,12}\\s[0-2]"; ArrayList<User> user = new ArrayList<>(); Scanner in = new Scanner(System.in); while (true) { String str = in.nextLine(); if (str.equals("end")) break; if (str.matches(gre1)) { String[] array = str.split("-", 2); String[] array1 = array[1].split(" ", 2); String phone_number = array1[0]; boolean has_found = false; for (User value : user) { if (phone_number.equals(value.getNumber())) { has_found = true; break; } } if (has_found) continue; User u = new User(); u.setNumber(phone_number); if (array1[1].equals("0")) { u.setChargeMode(new LandlinePhoneCharging()); } else if (array1[1].equals("1")) { u.setChargeMode(new MobilePhoneCharging()); } user.add(u); } else if (str.matches(l_l)) { String[] array = str.split("-", 2); String[] array1 = array[1].split(" "); String phone_number = array1[0]; String phone_number1 = array1[1]; String start_time = array1[2] + " " + array1[3]; String end_time = array1[4] + " " + array1[5]; SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); Date date = null, date1 = null; try { date = sdf.parse(start_time); } catch (ParseException e) { e.printStackTrace(); } try { date1 = sdf.parse(end_time); } catch (ParseException e) { e.printStackTrace(); } for (int i = 0; i < user.size(); i++) { if (phone_number.equals(user.get(i).getNumber())) { CallRecord callRecord = new CallRecord(); callRecord.setStartTime(date); callRecord.setEndTime(date1); callRecord.setCallingAddressAreaCode(phone_number.substring(0, 4)); callRecord.setAnswerAddressAreaCode(phone_number1.substring(0, 4)); if (callRecord.getAnswerAddressAreaCode().matches("0791")&& callRecord.getCallingAddressAreaCode().matches("0791")) { user.get(i).userRecords.addCallingInCityRecords(callRecord); } else if (callRecord.getCallingAddressAreaCode().matches("0791")&& callRecord.getAnswerAddressAreaCode().matches("(079[2-9]|(0701|0790))")) { user.get(i).userRecords.addCallingInProvinceRecords(callRecord); } else if(callRecord.getCallingAddressAreaCode().matches("0791")&& !callRecord.getAnswerAddressAreaCode().matches("(079[0-9]|0701)")){ user.get(i).userRecords.addCallingInLandRecords(callRecord); } } } }else if(str.matches(l_m)) { boolean flag=false; String[] array = str.split("-", 2); String[] array1 = array[1].split(" "); String phone_number = array1[0]; String phone_number1 = array1[1]; String Pickup_location_area_code = array1[2]; String start_time = array1[3] + " " + array1[4]; String end_time = array1[5] + " " + array1[6]; SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); Date date = null, date1 = null; try { date = sdf.parse(start_time); } catch (ParseException e) { e.printStackTrace(); } try { date1 = sdf.parse(end_time); } catch (ParseException e) { e.printStackTrace(); } CallRecord callRecord = new CallRecord(); callRecord.setStartTime(date); callRecord.setEndTime(date1); callRecord.setCallingAddressAreaCode(phone_number.substring(0, 4)); callRecord.setAnswerAddressAreaCode(Pickup_location_area_code); for (int i = 0; i < user.size(); i++) {//新增通話記錄 if (phone_number.equals(user.get(i).getNumber())) { if (callRecord.getAnswerAddressAreaCode().matches("0791")&& callRecord.getCallingAddressAreaCode().matches("0791")) { user.get(i).userRecords.addCallingInCityRecords(callRecord);flag=true; } else if (callRecord.getCallingAddressAreaCode().matches("0791")&& callRecord.getAnswerAddressAreaCode().matches("(079[2-9]|(0701|0790))")) { user.get(i).userRecords.addCallingInProvinceRecords(callRecord);flag=true; } else if(callRecord.getCallingAddressAreaCode().matches("0791")&& !callRecord.getAnswerAddressAreaCode().matches("(079[0-9]|0701)")){ for(int j=0;j<user.size();j++) if(user.get(j).getNumber().equals(phone_number1)) user.get(j).userRecords.addCallingInLandRoamingAnswerRecords(callRecord); user.get(i).userRecords.addCallingInLandRecords(callRecord);flag=true; } } } if(flag)continue; for (int j=0;j<user.size();j++) { if(phone_number1.equals(user.get(j).getNumber())) { if(!callRecord.getAnswerAddressAreaCode().matches("(079[0-9]|0701)")) { for(int k=0;k<user.size();k++) if(user.get(k).getNumber().equals(phone_number1)) user.get(k).userRecords.addCallingInLandRoamingAnswerRecords(callRecord); } } } } else if (str.matches(m_l)) { String[] array = str.split("-", 2); String[] array1 = array[1].split(" "); String phone_number = array1[0]; String Pickup_location_area_code= array1[1]; String phone_number1 = array1[2]; String start_time = array1[3] + " " + array1[4]; String end_time = array1[5] + " " + array1[6]; SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); Date date = null, date1 = null; try { date = sdf.parse(start_time); } catch (ParseException e) { e.printStackTrace(); } try { date1 = sdf.parse(end_time); } catch (ParseException e) { e.printStackTrace(); } CallRecord callRecord = new CallRecord(); callRecord.setStartTime(date); callRecord.setEndTime(date1); callRecord.setCallingAddressAreaCode(Pickup_location_area_code); callRecord.setAnswerAddressAreaCode(phone_number1.substring(0, 4)); for (int i = 0; i < user.size(); i++) {//新增通話記錄 if (phone_number.equals(user.get(i).getNumber())) { if (callRecord.getAnswerAddressAreaCode().matches("0791")&& callRecord.getCallingAddressAreaCode().matches("0791")) { user.get(i).userRecords.addCallingInCityRecords(callRecord); } else if (callRecord.getCallingAddressAreaCode().matches("0791")&& callRecord.getAnswerAddressAreaCode().matches("(079[2-9]|(0701|0790))")) { user.get(i).userRecords.addCallingInProvinceRecords(callRecord); } else if (callRecord.getCallingAddressAreaCode().matches("0791")&& !callRecord.getAnswerAddressAreaCode().matches("(079[0-9]|0701)")){ user.get(i).userRecords.addCallingInLandRecords(callRecord); } else if (callRecord.getCallingAddressAreaCode().matches("(079[2-9]|(0701|0790))")) { user.get(i).userRecords.addCallingInProvinceRoamingDialRecords(callRecord); }else if (!callRecord.getCallingAddressAreaCode().matches("(079[0-9]|0701)")) { user.get(i).userRecords.addCallingInLandRoamingDialRecords(callRecord); } } } } else if (str.matches(m_m)) { boolean flag=false; String[] array = str.split("-", 2); String[] array1 = array[1].split(" "); String phone_number = array1[0]; String Pickup_location_area_code =array1[1]; String phone_number1 = array1[2]; String Pickup_location_area_code1 =array1[3]; String start_time = array1[4] + " " + array1[5]; String end_time = array1[6] + " " + array1[7]; SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); Date date = null, date1 = null; try { date = sdf.parse(start_time); } catch (ParseException e) { e.printStackTrace(); } try { date1 = sdf.parse(end_time); } catch (ParseException e) { e.printStackTrace(); } CallRecord callRecord = new CallRecord(); callRecord.setStartTime(date); callRecord.setEndTime(date1); callRecord.setCallingAddressAreaCode(Pickup_location_area_code); callRecord.setAnswerAddressAreaCode(Pickup_location_area_code1); for (int i = 0; i < user.size(); i++) {//新增通話記錄 if (phone_number.equals(user.get(i).getNumber())) { if (callRecord.getAnswerAddressAreaCode().matches("0791")&& callRecord.getCallingAddressAreaCode().matches("0791")) { user.get(i).userRecords.addCallingInCityRecords(callRecord);flag=true; } else if (callRecord.getCallingAddressAreaCode().matches("0791")&& callRecord.getAnswerAddressAreaCode().matches("(079[2-9]|(0701|0790))")) { user.get(i).userRecords.addCallingInProvinceRecords(callRecord);flag=true; } else if(callRecord.getCallingAddressAreaCode().matches("0791")&& !callRecord.getAnswerAddressAreaCode().matches("(079[0-9]|0701)")){ for(int j=0;j<user.size();j++) if(user.get(j).getNumber().equals(phone_number1)) user.get(j).userRecords.addCallingInLandRoamingAnswerRecords(callRecord); user.get(i).userRecords.addCallingInLandRecords(callRecord);flag=true; } else if (callRecord.getCallingAddressAreaCode().matches("(079[2-9]|(0701|0790))")) { if(!callRecord.getAnswerAddressAreaCode().matches("(079[0-9]|0701)")) { for(int j=0;j<user.size();j++) if(user.get(j).getNumber().equals(phone_number1)) user.get(j).userRecords.addCallingInLandRoamingAnswerRecords(callRecord); } user.get(i).userRecords.addCallingInProvinceRoamingDialRecords(callRecord);flag=true; } else if (!callRecord.getCallingAddressAreaCode().matches("(079[0-9]|0701)")) { if(!callRecord.getAnswerAddressAreaCode().matches("(079[0-9]|0701)")) { for(int j=0;j<user.size();j++) if(user.get(j).getNumber().equals(phone_number1)) user.get(j).userRecords.addCallingInLandRoamingAnswerRecords(callRecord); } user.get(i).userRecords.addCallingInLandRoamingDialRecords(callRecord);flag=true; } } } if(flag)continue; for (int j=0;j<user.size();j++) { if(phone_number1.equals(user.get(j).getNumber())) { if(!callRecord.getAnswerAddressAreaCode().matches("(079[0-9]|0701)")) { for(int k=0;k<user.size();k++) if(user.get(k).getNumber().equals(phone_number1)) user.get(k).userRecords.addCallingInLandRoamingAnswerRecords(callRecord); } } } } } user.sort((user1,user2)->user1.getNumber().compareTo(user2.getNumber())); for (int i = 0; i < user.size(); i++) { System.out.print(user.get(i).getNumber() + " "); Print(user.get(i).calCost()); System.out.print(" "); Print(user.get(i).calBalance()); System.out.println(); } } } abstract class CallChargeRule extends ChargeRule{ } class CallRecord extends CommunicationRecord{ Date startTime; Date endTime; String callingAddressAreaCode; String answerAddressAreaCode; public Date getStartTime(){ return startTime; } public void setStartTime(Date startTime){ this.startTime=startTime; } public Date getEndTime(){ return endTime; } public void setEndTime(Date endTime){ this.endTime=endTime; } public String getCallingAddressAreaCode(){ return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode){ this.callingAddressAreaCode=callingAddressAreaCode; } public String getAnswerAddressAreaCode(){ return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode){ this.answerAddressAreaCode=answerAddressAreaCode; } } abstract class ChargeMode { 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 { protected String callingNumber; protected String answerNumber; public String getCallingNumber(){ return callingNumber; } public void setCallingNumber(String callingNumber){ this.callingNumber=callingNumber; } public String getAnswerNumber(){ return answerNumber; } public void setAnswerNumber(String answerNumber){ this.answerNumber=answerNumber; } } class LandlinePhoneCharging extends ChargeMode{ double monthlyRent=20; public LandlinePhoneCharging(){ ChargeRules.add(new LandPhoneInCityRule()); ChargeRules.add(new LandPhoneInProvinceRule()); ChargeRules.add(new LandPhoneInLandRule()); } @Override public double calCost(UserRecords userRecords){//三種收費方式加起來的錢 double sum_cost=0; sum_cost += ChargeRules.get(0).calCost(userRecords.callingInCityRecords); sum_cost += ChargeRules.get(1).calCost(userRecords.callingInProvinceRecords); sum_cost += ChargeRules.get(2).calCost(userRecords.callingInLandRecords); return sum_cost; } @Override public double getMonthlyRent(){ return monthlyRent; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.1; } } class LandPhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.6; } } class LandPhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } //System.out.println(Math.ceil(sum)*0.3); return sum*0.3; } } class MessageRecord extends CommunicationRecord{ String message; public String getMessage(){ return null; } public void setMessage(String message){ }; } class MobilePhoneCharging extends ChargeMode{ double monthlyRent=15; public MobilePhoneCharging(){ ChargeRules.add(new MobilePhoneInCityRule()); ChargeRules.add(new MobilePhoneInProvinceRule()); ChargeRules.add(new MobilePhoneInLandRule()); ChargeRules.add(new MobilePhoneInProvinceRoamingDials()); ChargeRules.add(new MobilePhoneInLandRoamingAnswering()); ChargeRules.add(new MobilePhoneInLandRoamingDials()); } @Override public double calCost(UserRecords userRecords) { double sum_cost=0; sum_cost += ChargeRules.get(0).calCost(userRecords.callingInCityRecords); sum_cost += ChargeRules.get(1).calCost(userRecords.callingInProvinceRecords); sum_cost += ChargeRules.get(2).calCost(userRecords.callingInLandRecords); sum_cost += ChargeRules.get(3).calCost(userRecords.callingInProvinceRoamingDialRecords); sum_cost += ChargeRules.get(4).calCost(userRecords.callingInLandRoamingAnswerRecords); sum_cost += ChargeRules.get(5).calCost(userRecords.callingInLandRoamingDialRecords); return sum_cost; } @Override public double getMonthlyRent() { return this.monthlyRent; } } class MobilePhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.1; } } class MobilePhoneInLandRoamingAnswering extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.3; } } class MobilePhoneInLandRoamingDials extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.6; } } class MobilePhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.3; } } class MobilePhoneInProvinceRoamingDials extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.3; } } class MobilePhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.2; } } class User { UserRecords userRecords=new UserRecords(); private final double balance=100; private ChargeMode chargeMode; private String number; public double calBalance(){ return this.balance-this.calCost()-chargeMode.getMonthlyRent(); } public double calCost(){ return chargeMode.calCost(userRecords); } public UserRecords getUserRecords(){ return this.userRecords; } public void setUserRecord(UserRecords userRecords){ this.userRecords=userRecords; } public ChargeMode getChargeMode(){ return chargeMode; } public double getBalance(){ return this.balance; } public void setChargeMode(ChargeMode chargeMode){ this.chargeMode=chargeMode; } public String getNumber(){ return this.number; } public void setNumber(String number){ this.number=number; } } class UserRecords { ArrayList<CallRecord> callingInCityRecords=new ArrayList<CallRecord>();//市對市記錄 ArrayList<CallRecord> callingInProvinceRecords=new ArrayList<CallRecord>();//市對省內記錄 ArrayList<CallRecord> callingInLandRecords=new ArrayList<CallRecord>();//市對省外記錄 ArrayList<CallRecord> answerInCityRecords=new ArrayList<CallRecord>(); ArrayList<CallRecord> answerInProvinceRecords=new ArrayList<CallRecord>(); ArrayList<CallRecord> answerInLandRecords=new ArrayList<CallRecord>(); ArrayList<MessageRecord> sendMessageRecords=new ArrayList<MessageRecord>(); ArrayList<MessageRecord> receiveMessageRecords=new ArrayList<MessageRecord>(); ArrayList<CallRecord> callingInProvinceRoamingDialRecords=new ArrayList<CallRecord>();//省內漫遊撥打記錄 ArrayList<CallRecord> callingInLandRoamingAnswerRecords=new ArrayList<CallRecord>();//省外漫遊接聽記錄 ArrayList<CallRecord> callingInLandRoamingDialRecords=new ArrayList<CallRecord>();//省外漫遊撥打記錄 public void addCallingInLandRoamingDialRecords(CallRecord callRecord){ callingInLandRoamingDialRecords.add(callRecord); } public void addCallingInLandRoamingAnswerRecords(CallRecord callRecord){ callingInLandRoamingAnswerRecords.add(callRecord); } public void addCallingInProvinceRoamingDialRecords(CallRecord callRecord){ callingInProvinceRoamingDialRecords.add(callRecord); } 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 addSentMessageRecords(MessageRecord sendMessageRecords){} public void addReceiveMessageRecords(MessageRecord receiveMessageRecords){} public ArrayList<MessageRecord> getSendMessageRecords(){return sendMessageRecords;} public ArrayList<MessageRecord> getReceiveMessageRecords(){return receiveMessageRecords;} 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;} }View Code
類圖:
程式碼質量:
595行
報表 447
分支報表百分比 17.0
方法呼叫語句 267
帶註釋的百分比行 1.8
類和介面 20
每個類的方法 3.05
每個方法的平均語句數 5.18
最複雜方法的行號 17
最複雜方法的名稱 main.main()
最大複雜度 80
最深塊線號 246
最大區塊深度 9+
平均區塊深度 3.01
平均複雜度 2.44
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)。
注意:以上圖中所定義的類不是限定要求,根據實際需要自行補充或修改。
設計:
這題比較簡單,只有簡訊計費,十個字記一次錢,傳送簡訊0.1元/條,超過3條0.2元/條,超過5條0.3元/條,如果一次傳送簡訊的字元數量超過10個,按每10個字元一條簡訊進行計算。加一個簡訊計費型別,在裡面算出字元的個數再進行算錢,思路大概就是這樣。然後在主函式裡面把之前的刪掉,改為一個簡訊計費的正則表示式即可。記錄為簡訊記錄。
相比於前兩題還是很簡單的
原始碼
import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Objects; import java.util.Scanner; public class Main { public static void Print(double data) { //保留1位小數 DecimalFormat df = new DecimalFormat("0.0#"); df.setRoundingMode(RoundingMode.HALF_UP); System.out.print(df.format(data)); } public static void main(String[] args) { String message ="m-1[0-9]{10}\\s"+"1[0-9]{10}\\s"+"[\\w\\s\\.,]+"; String gre1 = "u-1[0-9]{10}\\s3"; ArrayList<User> user = new ArrayList<>(); Scanner in = new Scanner(System.in); while (true) { String str = in.nextLine(); if (str.equals("end")) break; if (str.matches(gre1)) { String[] array = str.split("-", 2); String[] array1 = array[1].split(" ", 2); String phone_number = array1[0]; boolean has_found = false; for (User value : user) { if (phone_number.equals(value.getNumber())) { has_found = true; break; } } if (has_found) continue; User u = new User(); u.setNumber(phone_number); if (array1[1].equals("0")) { u.setChargeMode(new LandlinePhoneCharging()); } else if (array1[1].equals("1")) { u.setChargeMode(new MobilePhoneCharging()); }else if (array1[1].equals("3")) { u.setChargeMode(new SendMessageCharging()); } user.add(u); }else if (str.matches(message)){ String[] array = str.split("-", 2); String[] array1 = array[1].split(" ",3); String phone_number = array1[0]; String phone_number1 = array1[1]; String Message = array1[2]; MessageRecord messageRecord = new MessageRecord(); messageRecord.setMessage(Message); for (int i = 0; i < user.size(); i++) { if (phone_number.equals(user.get(i).getNumber())) { user.get(i).userRecords.addSentMessageRecords(messageRecord); } } } } user.sort((user1,user2)->user1.getNumber().compareTo(user2.getNumber())); for (int i = 0; i < user.size(); i++) { System.out.print(user.get(i).getNumber() + " "); Print(user.get(i).calCost()); System.out.print(" "); Print(user.get(i).calBalance()); System.out.println(); } } } abstract class CallChargeRule extends ChargeRule{ }class CallRecord extends CommunicationRecord{ Date startTime; Date endTime; String callingAddressAreaCode; String answerAddressAreaCode; public Date getStartTime(){ return startTime; } public void setStartTime(Date startTime){ this.startTime=startTime; } public Date getEndTime(){ return endTime; } public void setEndTime(Date endTime){ this.endTime=endTime; } public String getCallingAddressAreaCode(){ return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode){ this.callingAddressAreaCode=callingAddressAreaCode; } public String getAnswerAddressAreaCode(){ return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode){ this.answerAddressAreaCode=answerAddressAreaCode; } } abstract class ChargeMode { 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); public abstract double calCost1(ArrayList<MessageRecord> messageRecords); } abstract class CommunicationRecord { protected String callingNumber; protected String answerNumber; public String getCallingNumber(){ return callingNumber; } public void setCallingNumber(String callingNumber){ this.callingNumber=callingNumber; } public String getAnswerNumber(){ return answerNumber; } public void setAnswerNumber(String answerNumber){ this.answerNumber=answerNumber; } } class LandlinePhoneCharging extends ChargeMode{ double monthlyRent=20; public LandlinePhoneCharging(){ ChargeRules.add(new LandPhoneInCityRule()); ChargeRules.add(new LandPhoneInProvinceRule()); ChargeRules.add(new LandPhoneInLandRule()); } @Override public double calCost(UserRecords userRecords){//三種收費方式加起來的錢 double sum_cost=0; sum_cost += ChargeRules.get(0).calCost(userRecords.callingInCityRecords); sum_cost += ChargeRules.get(1).calCost(userRecords.callingInProvinceRecords); sum_cost += ChargeRules.get(2).calCost(userRecords.callingInLandRecords); return sum_cost; } @Override public double getMonthlyRent(){ return monthlyRent; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.1; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { return 0; } }class LandPhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.6; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { return 0; } } class LandPhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } //System.out.println(Math.ceil(sum)*0.3); return sum*0.3; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { return 0; } } abstract class MessageChargeRule extends ChargeRule{ } class MessageRecord extends CommunicationRecord{ String message; public String getMessage(){ return message; } public void setMessage(String message){ this.message=message; }; } class MobilePhoneCharging extends ChargeMode{ double monthlyRent=15; public MobilePhoneCharging(){ ChargeRules.add(new MobilePhoneInCityRule()); ChargeRules.add(new MobilePhoneInProvinceRule()); ChargeRules.add(new MobilePhoneInLandRule()); ChargeRules.add(new MobilePhoneInProvinceRoamingDials()); ChargeRules.add(new MobilePhoneInLandRoamingAnswering()); ChargeRules.add(new MobilePhoneInLandRoamingDials()); } @Override public double calCost(UserRecords userRecords) { double sum_cost=0; sum_cost += ChargeRules.get(0).calCost(userRecords.callingInCityRecords); sum_cost += ChargeRules.get(1).calCost(userRecords.callingInProvinceRecords); sum_cost += ChargeRules.get(2).calCost(userRecords.callingInLandRecords); sum_cost += ChargeRules.get(3).calCost(userRecords.callingInProvinceRoamingDialRecords); sum_cost += ChargeRules.get(4).calCost(userRecords.callingInLandRoamingAnswerRecords); sum_cost += ChargeRules.get(5).calCost(userRecords.callingInLandRoamingDialRecords); return sum_cost; } @Override public double getMonthlyRent() { return this.monthlyRent; } } class MobilePhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.1; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { return 0; } } class MobilePhoneInLandRoamingAnswering extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.3; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { return 0; } } class MobilePhoneInLandRoamingDials extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.6; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { return 0; } } class MobilePhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.3; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { return 0; } } class MobilePhoneInProvinceRoamingDials extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.3; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { return 0; } } class MobilePhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { double sum=0; for (int i=0;i<callRecords.size();i++) { sum+=((callRecords.get(i).endTime.getTime() - callRecords.get(i).startTime.getTime()) / 1000.0) / 60; sum=Math.ceil(sum); } return Math.ceil(sum)*0.2; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { return 0; } } class SendMessageCharging extends ChargeMode{ public SendMessageCharging() { ChargeRules.add(new SendMessageRule()); } @Override public double calCost(UserRecords userRecords) { double sum_cost=0; sum_cost += ChargeRules.get(0).calCost1(userRecords.sendMessageRecords); return sum_cost; } @Override public double getMonthlyRent() { return 0; } } class SendMessageRule extends MessageChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { return 0; } @Override public double calCost1(ArrayList<MessageRecord> messageRecords) { int messageNumber=0; for(int i=0;i<messageRecords.size();i++) messageNumber+=Math.ceil(messageRecords.get(i).getMessage().length()/10.0); if(messageNumber<=3) { return messageNumber*0.1; } else if (messageNumber<=5) { return 0.3+(messageNumber-3)*0.2; }else { return 0.3+2*0.2+(messageNumber-5)*0.3; } } } class User { UserRecords userRecords=new UserRecords(); private final double balance=100; private ChargeMode chargeMode; private String number; public double calBalance(){ return this.balance-this.calCost()-chargeMode.getMonthlyRent(); } public double calCost(){ return chargeMode.calCost(userRecords); } public UserRecords getUserRecords(){ return this.userRecords; } public void setUserRecord(UserRecords userRecords){ this.userRecords=userRecords; } public ChargeMode getChargeMode(){ return chargeMode; } public double getBalance(){ return this.balance; } public void setChargeMode(ChargeMode chargeMode){ this.chargeMode=chargeMode; } public String getNumber(){ return this.number; } public void setNumber(String number){ this.number=number; } } class UserRecords { ArrayList<CallRecord> callingInCityRecords=new ArrayList<CallRecord>();//市對市記錄 ArrayList<CallRecord> callingInProvinceRecords=new ArrayList<CallRecord>();//市對省內記錄 ArrayList<CallRecord> callingInLandRecords=new ArrayList<CallRecord>();//市對省外記錄 ArrayList<CallRecord> answerInCityRecords=new ArrayList<CallRecord>(); ArrayList<CallRecord> answerInProvinceRecords=new ArrayList<CallRecord>(); ArrayList<CallRecord> answerInLandRecords=new ArrayList<CallRecord>(); ArrayList<MessageRecord> sendMessageRecords=new ArrayList<MessageRecord>(); ArrayList<MessageRecord> receiveMessageRecords=new ArrayList<MessageRecord>(); ArrayList<CallRecord> callingInProvinceRoamingDialRecords=new ArrayList<CallRecord>();//省內漫遊撥打記錄 ArrayList<CallRecord> callingInLandRoamingAnswerRecords=new ArrayList<CallRecord>();//省外漫遊接聽記錄 ArrayList<CallRecord> callingInLandRoamingDialRecords=new ArrayList<CallRecord>();//省外漫遊撥打記錄 public void addCallingInLandRoamingDialRecords(CallRecord callRecord){ callingInLandRoamingDialRecords.add(callRecord); } public void addCallingInLandRoamingAnswerRecords(CallRecord callRecord){ callingInLandRoamingAnswerRecords.add(callRecord); } public void addCallingInProvinceRoamingDialRecords(CallRecord callRecord){ callingInProvinceRoamingDialRecords.add(callRecord); } 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 addSentMessageRecords(MessageRecord MessageRecords){ sendMessageRecords.add(MessageRecords); } public void addReceiveMessageRecords(MessageRecord receiveMessageRecords){} public ArrayList<MessageRecord> getSendMessageRecords(){return sendMessageRecords;} public ArrayList<MessageRecord> getReceiveMessageRecords(){return receiveMessageRecords;} 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;} }View Code
類圖:
程式碼質量:
449行
報表 342
分支報表百分比 7.6
方法呼叫語句 109
帶註釋的百分比行 1.8
類和介面 23
每個類的方法 3.26
每個方法的平均語句數 2.40
最複雜方法的行號 17
最複雜方法的名稱 main.main()
最大複雜度 14
最深塊線號 32
最大塊深度 6
平均區塊深度 1.70
平均複雜度 1.35
三,採坑心得
這三次作業裡面好像也沒有特別陰間的地方,只需要按照類圖來寫就可以
在我第二次電信計費的時候有一個點一直過不去,
就是這裡,這裡是省內漫遊的一個點,主要是我對省內漫遊理解錯了,省內漫遊就是省內打撥號者打給任意的地方即為省內漫遊,而我一來的是省內對省內的理解為漫遊,所以這個點一直過不去。後面發現錯誤改正過來了。
然後就是第三次作業,寫完程式碼之後有幾個點一直過不去,起初以為是在正則表示式沒有判斷全面
但是後來發現是自己算錯了,好離譜,計算超過5條的,沒有減去之前5條以內的,後面改正過來了。
四,改進建議
我覺得最需要改進的地方是這裡
採用大量正則表示式區分每一種情況,然後就是區分完每一種情況之後呢,又發現每一種情況判斷在省內省外有相同之處,所以說還是採用一步到位的正則表示式比較好
這些步驟真的有好多重複的地方,可以寫到一個方法裡面
五,總結
經過了一個一個學期的學習,Java的學習到這裡也就結束了,最後三次大作業讓我編寫類的思維更加清晰,更懂得如何把類直接連在一起
在學習Java的過程中我得出這樣的結論:1. 學習中,要養成良好的習慣(寫括號時要成對,字母大小寫要區分,單詞拼寫要準確)。
2. 在學習的過程中,最好不是僅僅停留在java表層,不是抄書上的例子執行出結果就可以。要注意,即便對一個簡單的例子也要有耐心去琢磨、除錯、改動。
3. 在學習的過程中一定要動手做、試著寫程式碼,而不是抱著老師的講義看看就行。很多東西和體會必須自己動手才能真正屬於自己。
4. 課程收穫。學習Java這一學期以來,最大的感受是痛苦並快樂著(以後可能更痛苦。。),痛苦是寫不出來啊!狂抓也沒用的那種!快樂是程式碼這種東西寫出來執行一下,結果正確,那種成就感真的沒法表達,還有一個意想不到收穫就是CSDN,自己敲出來的程式碼有那麼多的閱讀量,真的很開心(雖然是照著老師的講義敲的)
5. 在 Java 的學習過程中,可能會遇到形形色色的問題不容易解決,應多去專業論壇瞭解相關的知識,書本上的知識有限。要會從網上搜索有用的資訊 加以整理,促進學習的深入和知識水平的提高。
看了好多網上課程,說學到一定程度要嘗試著自己做東西,但覺得自己僅僅經過一學期的學習,還遠遠不夠,希望自己在以後學習中繼續努力,能夠真真正正擁有一門程式語言,對自己今後的發展起到作用。在學習java語言的同時,也讓我學會了如何來發現問題,如何解決問題,怎樣有效的學習等等,相信會對我一生都有幫助。