BLOG-3
一、前言
1、题目集08~10都主要是电信计费系列知识点比较综合包含正则表达式,继承、多态等等之类,但是最主要的是考察设计能力和对类图的解读能力。
2、宾馆入住系统,主要要求对于系统设计,考察设计能力。
二、设计与分析
1、题目集08-01:电信计费系列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元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
难点:
如何设计类图,搞清楚类与类之间的关系。灵活运用SimpleDateFormat类Array list类,熟练使用正则表达式,熟悉继承、多态的应用。
对于用户如何对他进行排序如何输出,如何判断输入的用户通话记录是否符合要求,如何判断通话记录应该储存在哪一个用户中。
思路:
根据题目给出类图编写方法和类。使用while循环一行一行的读取输入内容。每有一条开户信息就新建一个User类,然后读取通话记录储存进User类中的userrecord中。
import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class Main { public static void main(String args[]) throws ParseException { Scanner input = new Scanner(System.in); User[] user = new User[20]; int x = -1,g = 0; String str3 = "([1-2]\\d{3}[.]([1-9]|1[0,1,2])[.]([1-9]|[1-2]\\d|30|31))\\s((20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d)"; while (true) { String arr = input.nextLine(); if (arr.equals("end")) { break; } String[] str = arr.split(" "); SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); if ((str[0].matches("u-0791\\d{7,8}") && str[1].equals("0"))|| (str[0].matches("u-1\\d{10}")&&str[1].equals("1"))) { if(user[0]==null){ x++; String[] arr1 = str[0].split("-"); user[x] = new User(); user[x].setNumber(arr1[1]); } else { g=0; for(int i = 0;user[i]!=null;i++) { String[] arr1 = str[0].split("-"); if(user[i].number.equals(arr1[1])) {g++;} } if(g==0){ x++; String[] arr1 = str[0].split("-"); user[x] = new User(); user[x].setNumber(arr1[1]); } } } else { for (int k = 0; k<=x; k++) { if (str[0].matches("t-0791\\d{7,8}")&&str[1].matches("0\\d{10,11}")&& str[2].concat(" ").concat(str[3]).matches(str3)&& str[4].concat(" ").concat(str[5]).matches(str3)&& str.length==6) { CallRecord CallRecord = new CallRecord(); CallRecord.setCallingAddressAreaCode(str[0].substring(2,6)); CallRecord.setAnswerAddressAreaCode(str[1].substring(0,4)); CallRecord.setStartTime(sdf.parse(str[2].concat(" ").concat(str[3]))); CallRecord.setEndTime(sdf.parse(str[4].concat(" ").concat(str[5]))); CallRecord.setCallingNumber(str[0].substring(2)); CallRecord.setAnswerNumber(str[1]); if(CallRecord.endTime.getTime()>CallRecord.startTime.getTime()){ if (str[0].substring(2).equals(user[k].number)) {user[k].userRecords.addCallingInCityRecords(CallRecord);} } } if(str[0].matches("t-0791\\d{7,8}")&&str[1].matches("1\\d{10}")&& str[2].matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")&&str[3].concat(" ").concat(str[4]).matches(str3)&& str[5].concat(" ").concat(str[6]).matches(str3)&& str.length==7){ CallRecord CallRecord = new CallRecord(); CallRecord.setCallingAddressAreaCode(str[0].substring(2,6)); CallRecord.setAnswerAddressAreaCode(str[2]); CallRecord.setStartTime(sdf.parse(str[3].concat(" ").concat(str[4]))); CallRecord.setEndTime(sdf.parse(str[5].concat(" ").concat(str[6]))); CallRecord.setCallingNumber(str[0].substring(2)); CallRecord.setAnswerNumber(str[1]); if(CallRecord.endTime.getTime()>CallRecord.startTime.getTime()){ if (str[0].substring(2).equals(user[k].number)) {user[k].userRecords.addCallingInCityRecords(CallRecord);} if (str[1].equals((user[k].number))) { if (str[2].matches("0791")) { CallRecord.setCallingAddressAreaCode(" "); CallRecord.setCallingNumber(" "); user[k].userRecords.addAnswerInCityRecords(CallRecord); } else if(str[2].matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")){ CallRecord.setCallingAddressAreaCode(" "); CallRecord.setCallingNumber(" "); user[k].userRecords.addAnswerInProvinceRecords(CallRecord); } else if(str[2].matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ CallRecord.setCallingAddressAreaCode(" "); CallRecord.setCallingNumber(" "); user[k].userRecords.addAnswerInLandRecords(CallRecord); } } } } if(str[0].matches("t-1\\d{10}")&&str[1].matches("0\\d{2,3}")&& str[2].matches("0\\d{10,11}")&& str[3].concat(" ").concat(str[4]).matches(str3)&& str[5].concat(" ").concat(str[6]).matches(str3)&& str.length==7){ CallRecord CallRecord = new CallRecord(); CallRecord.setCallingAddressAreaCode(str[1]); CallRecord.setAnswerAddressAreaCode(str[2].substring(0,4)); CallRecord.setStartTime(sdf.parse(str[3].concat(" ").concat(str[4]))); CallRecord.setEndTime(sdf.parse(str[5].concat(" ").concat(str[6]))); CallRecord.setCallingNumber(str[0].substring(2)); CallRecord.setAnswerNumber(str[2]); if(CallRecord.endTime.getTime()>CallRecord.startTime.getTime()){ if (str[0].substring(2).equals(user[k].number)&&str[1].matches("0791")) { user[k].userRecords.addCallingInCityRecords(CallRecord); } else if(str[0].substring(2).equals(user[k].number)&&str[1].matches("(079[0,,2,3,4,5,6,7,8,9])|(0701)")){ user[k].userRecords.addCallingInProvinceRecords(CallRecord); } else if(str[0].substring(2).equals(user[k].number)&&str[1].matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ user[k].userRecords.addCallingInLandRecords(CallRecord); } } } if(str[0].matches("t-1\\d{10}")&&str[1].matches("0\\d{2,3}")&& str[2].matches("1\\d{10}")&&str[3].matches("0\\d{2,3}")&& str[4].concat(" ").concat(str[5]).matches(str3)&& str[6].concat(" ").concat(str[7]).matches(str3)&& str.length==8){ CallRecord CallRecord = new CallRecord(); CallRecord.setCallingAddressAreaCode(str[1]); CallRecord.setAnswerAddressAreaCode(str[3]); CallRecord.setStartTime(sdf.parse(str[4].concat(" ").concat(str[5]))); CallRecord.setEndTime(sdf.parse(str[6].concat(" ").concat(str[7]))); CallRecord.setCallingNumber(str[0].substring(2)); CallRecord.setAnswerNumber(str[2]); if(CallRecord.endTime.getTime()>CallRecord.startTime.getTime()){ if (str[0].substring(2).equals(user[k].number)&&str[1].matches("0791")) { user[k].userRecords.addCallingInCityRecords(CallRecord); } else if(str[0].substring(2).equals(user[k].number)&&str[1].matches("(079[0,,2,3,4,5,6,7,8,9])|(0701)")){ user[k].userRecords.addCallingInProvinceRecords(CallRecord); } else if(str[0].substring(2).equals(user[k].number)&&str[1].matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ user[k].userRecords.addCallingInLandRecords(CallRecord); } if (str[2].equals(user[k].number)&&str[3].matches("0791")) { user[k].userRecords.addAnswerInCityRecords(CallRecord); } else if(str[2].equals(user[k].number)&&str[3].matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")){ user[k].userRecords.addAnswerInProvinceRecords(CallRecord); } else if(str[2].equals(user[k].number)&&str[3].matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ user[k].userRecords.addAnswerInLandRecords(CallRecord); } } } } } } String[] arr3 = new String [x+1]; for (int k = 0;k<=x;k++){ arr3[k] = user[k].number; } Arrays.sort(arr3, String::compareToIgnoreCase); for(int k = 0;k<=x;k++){ for(int j = 0;j<=x;j++){ if(user[j].number.equals(arr3[k])){ User az; az = user[k]; user[k] = user[j]; user[j] = az; } } } for(int k = 0;k<=x;k++){ for(int j = 0;j<=user[k].userRecords.callingInCityRecords.size()-1;j++){ for(int i = j+1;i<=user[k].userRecords.callingInCityRecords.size()-1;i++){ if(i==j){break;} if(user[k].userRecords.callingInCityRecords.get(i).answerNumber.equals(user[k].userRecords.callingInCityRecords.get(j).answerNumber)&& user[k].userRecords.callingInCityRecords.get(i).startTime.getTime()==user[k].userRecords.callingInCityRecords.get(j).startTime.getTime()&& user[k].userRecords.callingInCityRecords.get(i).endTime.getTime()==user[k].userRecords.callingInCityRecords.get(j).endTime.getTime()){ user[k].userRecords.callingInCityRecords.remove(j); } } } } LandlinePhoneCharging LandlinePhoneCharging = new LandlinePhoneCharging(); MobilePhoneCharges MobilePhoneCharges = new MobilePhoneCharges(); DecimalFormat df = new DecimalFormat("0.0"); for(int k = 0;k<=x;k++){ if(user[k].getNumber().matches("0\\d{10,11}")){ System.out.println(user[k].number+" "+Double.parseDouble(df.format(LandlinePhoneCharging.calCost(user[k].userRecords)))+" "+Double.parseDouble(df.format(LandlinePhoneCharging.getMonthlyRent()))); } else if (user[k].getNumber().matches("1\\d{10}")) { System.out.println(user[k].number + " " + Double.parseDouble(df.format(MobilePhoneCharges.calCost(user[k].userRecords))) + " " + Double.parseDouble(df.format(MobilePhoneCharges.getMonthlyRent()))); } } } } class User{ UserRecords userRecords = new UserRecords(); double balance = 100; ChargeMode chargeMode = new ChargeMode(); String number; public double calBalance(){ return 0; } public double calCost(){ return 0; } public UserRecords getUserRecords() { return userRecords; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public void setUserRecords(UserRecords userRecords) {this.userRecords = userRecords; } } class ChargeMode{ ArrayList<ChargeRule> chargeRule = new ArrayList<>(); public ArrayList<ChargeRule> getChargeRule() { return chargeRule; } public void setChargeRule(ArrayList<ChargeRule> chargeRule) {this.chargeRule = chargeRule;} public double calCost(UserRecords userRecords) {return 0;} public double getMonthlyRent() {return 0;} } 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<MessageRecords> sendMessageRecords = new ArrayList<MessageRecords>(); ArrayList<MessageRecords> receiveMessageRecords = new ArrayList<MessageRecords>(); public void addCallingInCityRecords(CallRecord callRecord) { callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecords(CallRecord callRecord) { callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecords(CallRecord callRecord) { callingInLandRecords.add(callRecord); } public void addAnswerInCityRecords(CallRecord callRecord) { answerInCityRecords.add(callRecord); } public void addAnswerInProvinceRecords(CallRecord callRecord) { answerInProvinceRecords.add(callRecord); } public void addAnswerInLandRecords(CallRecord callRecord) { answerInLandRecords.add(callRecord); } public void addSendMessageRecords(MessageRecords MessageRecords) { sendMessageRecords.add(MessageRecords); } public void addReceiveMessageRecords(MessageRecords MessageRecords) { receiveMessageRecords.add(MessageRecords); } 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<MessageRecords> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecords> getReceiveMessageRecords() { return receiveMessageRecords; } } class LandlinePhoneCharging extends ChargeMode{ double monthlyRent = 20; double cost,cost1,cost2,cost3; public double calCost(UserRecords userRecords) { cost = 0; cost1 = 0; cost2 = 0; cost3 = 0; LandPhoneInCityRule landPhoneInCityRule = new LandPhoneInCityRule(); LandPhoneInProvinceRule landPhoneInProvinceRule = new LandPhoneInProvinceRule(); LandPhoneInLandRule landPhoneInLandRule = new LandPhoneInLandRule(); for(CallRecord CallRecord : userRecords.callingInCityRecords){ if(CallRecord.answerAddressAreaCode.matches("0791")){ cost1 = landPhoneInCityRule.calCost(userRecords.callingInCityRecords); } else if (CallRecord.answerAddressAreaCode.matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")) { cost2 = landPhoneInProvinceRule.calCost(userRecords.callingInCityRecords); } else if (CallRecord.answerAddressAreaCode.matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")) { cost3 = landPhoneInLandRule.calCost(userRecords.callingInCityRecords); } } cost += cost1+cost2+cost3; return cost; } public double getMonthlyRent() { return 100-monthlyRent-cost; } } class MobilePhoneCharges{ double monthlyRent = 15; double cost; public double calCost(UserRecords userRecords) { cost = 0; LandPhoneInCityRule landPhoneInCityRule = new LandPhoneInCityRule(); LandPhoneInProvinceRule landPhoneInProvinceRule = new LandPhoneInProvinceRule(); LandPhoneInLandRule landPhoneInLandRule = new LandPhoneInLandRule(); cost += landPhoneInCityRule.calCost(userRecords.callingInCityRecords)+landPhoneInCityRule.calCost(userRecords.answerInCityRecords)+ landPhoneInCityRule.calCost(userRecords.callingInProvinceRecords)+landPhoneInCityRule.calCost(userRecords.answerInProvinceRecords)+ landPhoneInCityRule.calCost(userRecords.callingInLandRecords)+landPhoneInCityRule.calCost(userRecords.answerInLandRecords)+ landPhoneInProvinceRule.calCost(userRecords.callingInCityRecords)+landPhoneInProvinceRule.calCost(userRecords.answerInCityRecords)+ landPhoneInProvinceRule.calCost(userRecords.callingInProvinceRecords)+landPhoneInProvinceRule.calCost(userRecords.answerInProvinceRecords)+ landPhoneInProvinceRule.calCost(userRecords.callingInLandRecords)+landPhoneInProvinceRule.calCost(userRecords.answerInLandRecords)+ landPhoneInLandRule.calCost(userRecords.callingInCityRecords)+landPhoneInLandRule.calCost(userRecords.answerInCityRecords)+ landPhoneInLandRule.calCost(userRecords.callingInProvinceRecords)+landPhoneInLandRule.calCost(userRecords.answerInProvinceRecords)+ landPhoneInLandRule.calCost(userRecords.callingInLandRecords)+landPhoneInLandRule.calCost(userRecords.answerInLandRecords); return cost; } public double getMonthlyRent() { return 100-monthlyRent-cost; } } 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; } } class MessageRecords extends CommunicationRecord{ String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } abstract class ChargeRule{ } abstract class CommunicationRecord{ String callingNumber; 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;} } abstract class CallChargeRule extends ChargeRule{ public double calCost(ArrayList<CallRecord> callRecords) { return 0; } } class LandPhoneInCityRule extends CallChargeRule{ double cost; public double calCost(ArrayList<CallRecord> callRecords) { cost = 0; for (CallRecord callRecord : callRecords) { if(callRecord.getCallingNumber().matches("0\\d{10,11}")&&callRecord.getAnswerAddressAreaCode().matches("0791")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.1; } else { cost += ((int) minute * 0.1 + 0.1); } } else if(callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getAnswerAddressAreaCode().matches("0791")&&callRecord.getCallingAddressAreaCode().matches("0791")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.1; } else { cost += ((int) minute * 0.1 + 0.1); } } else if(callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getAnswerAddressAreaCode().matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")&&callRecord.getCallingAddressAreaCode().matches("0791")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.2; } else { cost += ((int) minute * 0.2 + 0.2); } } else if (callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getAnswerAddressAreaCode().matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")&&callRecord.getCallingAddressAreaCode().matches("0791")) { double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.3; } else { cost += ((int) minute * 0.3 + 0.3); } } } return cost; } } class LandPhoneInProvinceRule extends CallChargeRule{ double cost; public double calCost(ArrayList<CallRecord> callRecords) { cost = 0; for (CallRecord callRecord : callRecords) { if(callRecord.getCallingNumber().matches("0\\d{10,11}")&&callRecord.getAnswerAddressAreaCode().matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.3; } else { cost += ((int) minute * 0.3 + 0.3); } } else if (callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getCallingAddressAreaCode().matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")) { double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.3; } else { cost += ((int) minute * 0.3 + 0.3); } } } return cost; } } class LandPhoneInLandRule extends CallChargeRule{ double cost; public double calCost(ArrayList<CallRecord> callRecords) { cost = 0; for (CallRecord callRecord : callRecords) { if(callRecord.getCallingNumber().matches("0\\d{10,11}")&&callRecord.getAnswerAddressAreaCode().matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.6; } else { cost += ((int) minute * 0.6 + 0.6); } } else if (callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getCallingAddressAreaCode().matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")) { double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.6; } else { cost += ((int) minute * 0.6 + 0.6); } } else if (callRecord.getAnswerNumber().matches("1\\d{10}")&&callRecord.getAnswerAddressAreaCode().matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")) { double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.3; } else { cost += ((int) minute * 0.3 + 0.3); } } } return cost; } }

2、题目集09-01:电信计费系列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元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
难点:
对于通话记录的判断,判断是否存入哪一个用户的通话记录中,还有就是如何通过地区判断收费模式。
对于通话计费的算法的判断也是一大难点。
思路:
对于每一条通话记录都进行判断是否是座机打座机还是座机打手机还是手机打手机然后for循环和user.number对比判断是否应该存入这个user类中然后判断是接电话还是打电话再判断地区在哪里是否是市内通话还是省内通话还是省外通话。
import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class Main { public static void main(String args[]) throws ParseException { Scanner input = new Scanner(System.in); User[] user = new User[20]; int x = -1,g = 0; String str3 = "([1-2]\\d{3}[.]([1-9]|1[0,1,2])[.]([1-9]|[1-2]\\d|30|31))\\s((20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d)"; while (true) { String arr = input.nextLine(); if (arr.equals("end")) { break; } String[] str = arr.split(" "); SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); if ((str[0].matches("u-0791\\d{7,8}") && str[1].equals("0"))|| (str[0].matches("u-1\\d{10}")&&str[1].equals("1"))) { if(user[0]==null){ x++; String[] arr1 = str[0].split("-"); user[x] = new User(); user[x].setNumber(arr1[1]); } else { g=0; for(int i = 0;user[i]!=null;i++) { String[] arr1 = str[0].split("-"); if(user[i].number.equals(arr1[1])) {g++;} } if(g==0){ x++; String[] arr1 = str[0].split("-"); user[x] = new User(); user[x].setNumber(arr1[1]); } } } else { for (int k = 0; k<=x; k++) { if (str[0].matches("t-0791\\d{7,8}")&&str[1].matches("0\\d{9,11}")&& str[2].concat(" ").concat(str[3]).matches(str3)&& str[4].concat(" ").concat(str[5]).matches(str3)&& str.length==6) { CallRecord CallRecord = new CallRecord(); CallRecord.setCallingAddressAreaCode(str[0].substring(2,6)); CallRecord.setAnswerAddressAreaCode(str[1].substring(0,4)); CallRecord.setStartTime(sdf.parse(str[2].concat(" ").concat(str[3]))); CallRecord.setEndTime(sdf.parse(str[4].concat(" ").concat(str[5]))); CallRecord.setCallingNumber(str[0].substring(2)); CallRecord.setAnswerNumber(str[1]); if(CallRecord.endTime.getTime()>CallRecord.startTime.getTime()){ String arr1 = str[0].substring(2); if (arr1.equals(user[k].number)) { user[k].userRecords.addCallingInCityRecords(CallRecord); } } } if(str[0].matches("t-0791\\d{7,8}")&&str[1].matches("1\\d{10}")&& str[2].matches("0\\d{2,3}")&&str[3].concat(" ").concat(str[4]).matches(str3)&& str[5].concat(" ").concat(str[6]).matches(str3)&& str.length==7){ CallRecord CallRecord = new CallRecord(); CallRecord.setCallingAddressAreaCode(str[0].substring(2,6)); CallRecord.setAnswerAddressAreaCode(str[2]); CallRecord.setStartTime(sdf.parse(str[3].concat(" ").concat(str[4]))); CallRecord.setEndTime(sdf.parse(str[5].concat(" ").concat(str[6]))); CallRecord.setCallingNumber(str[0].substring(2)); CallRecord.setAnswerNumber(str[1]); if(CallRecord.endTime.getTime()>CallRecord.startTime.getTime()){ if (str[0].substring(2).equals(user[k].number)) { user[k].userRecords.addCallingInCityRecords(CallRecord); } if (str[1].equals((user[k].number))) { if (str[2].matches("0791")) { CallRecord.setCallingAddressAreaCode(" "); CallRecord.setCallingNumber(" "); user[k].userRecords.addAnswerInCityRecords(CallRecord); } else if(str[2].matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")){ CallRecord.setCallingAddressAreaCode(" "); CallRecord.setCallingNumber(" "); user[k].userRecords.addAnswerInProvinceRecords(CallRecord); } else if(str[2].matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ CallRecord.setCallingAddressAreaCode(" "); CallRecord.setCallingNumber(" "); user[k].userRecords.addAnswerInLandRecords(CallRecord); } } } } if(str[0].matches("t-1\\d{10}")&&str[1].matches("0\\d{2,3}")&& str[2].matches("0\\d{10,11}")&& str[3].concat(" ").concat(str[4]).matches(str3)&& str[5].concat(" ").concat(str[6]).matches(str3)&& str.length==7){ CallRecord CallRecord = new CallRecord(); CallRecord.setCallingAddressAreaCode(str[1]); CallRecord.setAnswerAddressAreaCode(str[2].substring(0,4)); CallRecord.setStartTime(sdf.parse(str[3].concat(" ").concat(str[4]))); CallRecord.setEndTime(sdf.parse(str[5].concat(" ").concat(str[6]))); CallRecord.setCallingNumber(str[0].substring(2)); CallRecord.setAnswerNumber(str[2]); if(CallRecord.endTime.getTime()>CallRecord.startTime.getTime()){ if (str[0].substring(2).equals(user[k].number)&&str[1].matches("0791")) { user[k].userRecords.addCallingInCityRecords(CallRecord); } else if(str[0].substring(2).equals(user[k].number)&&str[1].matches("(079[0,,2,3,4,5,6,7,8,9])|(0701)")){ user[k].userRecords.addCallingInProvinceRecords(CallRecord); } else if(str[0].substring(2).equals(user[k].number)&&str[1].matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ user[k].userRecords.addCallingInLandRecords(CallRecord); } } } if(str[0].matches("t-1\\d{10}")&&str[1].matches("0\\d{2,3}")&& str[2].matches("1\\d{10}")&&str[3].matches("0\\d{2,3}")&& str[4].concat(" ").concat(str[5]).matches(str3)&& str[6].concat(" ").concat(str[7]).matches(str3)&& str.length==8){ CallRecord CallRecord = new CallRecord(); CallRecord.setCallingAddressAreaCode(str[1]); CallRecord.setAnswerAddressAreaCode(str[3]); CallRecord.setStartTime(sdf.parse(str[4].concat(" ").concat(str[5]))); CallRecord.setEndTime(sdf.parse(str[6].concat(" ").concat(str[7]))); CallRecord.setCallingNumber(str[0].substring(2)); CallRecord.setAnswerNumber(str[2]); if(CallRecord.endTime.getTime()>CallRecord.startTime.getTime()){ if (str[0].substring(2).equals(user[k].number)&&str[1].matches("0791")) { user[k].userRecords.addCallingInCityRecords(CallRecord); } else if(str[0].substring(2).equals(user[k].number)&&str[1].matches("(079[0,,2,3,4,5,6,7,8,9])|(0701)")){ user[k].userRecords.addCallingInProvinceRecords(CallRecord); } else if(str[0].substring(2).equals(user[k].number)&&str[1].matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ user[k].userRecords.addCallingInLandRecords(CallRecord); } if (str[2].equals(user[k].number)&&str[3].matches("0791")) { CallRecord.setCallingAddressAreaCode(" "); CallRecord.setCallingNumber(" "); user[k].userRecords.addAnswerInCityRecords(CallRecord); } else if(str[2].equals(user[k].number)&&str[3].matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")){ CallRecord.setCallingAddressAreaCode(" "); CallRecord.setCallingNumber(" "); user[k].userRecords.addAnswerInProvinceRecords(CallRecord); } else if(str[2].equals(user[k].number)&&str[3].matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ CallRecord.setCallingAddressAreaCode(" "); CallRecord.setCallingNumber(" "); user[k].userRecords.addAnswerInLandRecords(CallRecord); } } } } } } String[] arr3 = new String [x+1]; for (int k = 0;k<=x;k++){ arr3[k] = user[k].number; } Arrays.sort(arr3, String::compareToIgnoreCase); for(int k = 0;k<=x;k++){ for(int j = 0;j<=x;j++){ if(user[j].number.equals(arr3[k])){ User az; az = user[k]; user[k] = user[j]; user[j] = az; } } } LandlinePhoneCharging LandlinePhoneCharging = new LandlinePhoneCharging(); MobilePhoneCharges MobilePhoneCharges = new MobilePhoneCharges(); DecimalFormat df = new DecimalFormat("0.0"); for(int k = 0;k<=x;k++){ if(user[k].getNumber().matches("0\\d{10,11}")){ System.out.println(user[k].number+" "+Double.parseDouble(df.format(LandlinePhoneCharging.calCost(user[k].userRecords)))+" "+Double.parseDouble(df.format(LandlinePhoneCharging.getMonthlyRent()))); } else if (user[k].getNumber().matches("1\\d{10}")) { System.out.println(user[k].number + " " + Double.parseDouble(df.format(MobilePhoneCharges.calCost(user[k].userRecords))) + " " + Double.parseDouble(df.format(MobilePhoneCharges.getMonthlyRent()))); } } } } class User{ UserRecords userRecords = new UserRecords(); double balance = 100; ChargeMode chargeMode = new ChargeMode(); String number; public double calBalance(){ return 0; } public double calCost(){ return 0; } public UserRecords getUserRecords() { return userRecords; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public void setUserRecords(UserRecords userRecords) {this.userRecords = userRecords; } } class ChargeMode{ ArrayList<ChargeRule> chargeRule = new ArrayList<>(); public ArrayList<ChargeRule> getChargeRule() { return chargeRule; } public void setChargeRule(ArrayList<ChargeRule> chargeRule) {this.chargeRule = chargeRule;} public double calCost(UserRecords userRecords) {return 0;} public double getMonthlyRent() {return 0;} } 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<MessageRecords> sendMessageRecords = new ArrayList<MessageRecords>(); ArrayList<MessageRecords> receiveMessageRecords = new ArrayList<MessageRecords>(); public void addCallingInCityRecords(CallRecord callRecord) { callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecords(CallRecord callRecord) { callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecords(CallRecord callRecord) { callingInLandRecords.add(callRecord); } public void addAnswerInCityRecords(CallRecord callRecord) { answerInCityRecords.add(callRecord); } public void addAnswerInProvinceRecords(CallRecord callRecord) { answerInProvinceRecords.add(callRecord); } public void addAnswerInLandRecords(CallRecord callRecord) { answerInLandRecords.add(callRecord); } public void addSendMessageRecords(MessageRecords MessageRecords) { sendMessageRecords.add(MessageRecords); } public void addReceiveMessageRecords(MessageRecords MessageRecords) { receiveMessageRecords.add(MessageRecords); } 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<MessageRecords> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecords> getReceiveMessageRecords() { return receiveMessageRecords; } } class LandlinePhoneCharging extends ChargeMode{ double monthlyRent = 20; double cost,cost1,cost2,cost3; public double calCost(UserRecords userRecords) { cost = 0; cost1 = 0; cost2 = 0; cost3 = 0; LandPhoneInCityRule landPhoneInCityRule = new LandPhoneInCityRule(); LandPhoneInProvinceRule landPhoneInProvinceRule = new LandPhoneInProvinceRule(); LandPhoneInLandRule landPhoneInLandRule = new LandPhoneInLandRule(); for(CallRecord CallRecord : userRecords.callingInCityRecords){ if(CallRecord.answerAddressAreaCode.matches("0791")){ cost1 = landPhoneInCityRule.calCost(userRecords.callingInCityRecords); } else if (CallRecord.answerAddressAreaCode.matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")) { cost2 = landPhoneInProvinceRule.calCost(userRecords.callingInCityRecords); } else if (CallRecord.answerAddressAreaCode.matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")) { cost3 = landPhoneInLandRule.calCost(userRecords.callingInCityRecords); } } cost += cost1+cost2+cost3; return cost; } public double getMonthlyRent() { return 100-monthlyRent-cost; } } class MobilePhoneCharges{ double monthlyRent = 15; double cost,c1,c2,c3,c4,c5,c6; public double calCost(UserRecords userRecords) { cost = 0; LandPhoneInCityRule landPhoneInCityRule = new LandPhoneInCityRule(); LandPhoneInProvinceRule landPhoneInProvinceRule = new LandPhoneInProvinceRule(); LandPhoneInLandRule landPhoneInLandRule = new LandPhoneInLandRule(); c1 = landPhoneInCityRule.calCost(userRecords.callingInCityRecords); c2 = landPhoneInCityRule.calCost(userRecords.answerInCityRecords); c3 =landPhoneInProvinceRule.calCost(userRecords.callingInProvinceRecords); c4 = landPhoneInProvinceRule.calCost(userRecords.answerInProvinceRecords); c5 = landPhoneInLandRule.calCost(userRecords.callingInLandRecords); c6 = landPhoneInLandRule.calCost(userRecords.answerInLandRecords); cost = c1+c2+c3+c4+c5+c6; return cost; } public double getMonthlyRent() { return 100-monthlyRent-cost; } } 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; } } class MessageRecords extends CommunicationRecord{ String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } abstract class ChargeRule{ } abstract class CommunicationRecord{ String callingNumber; 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;} } abstract class CallChargeRule extends ChargeRule{ public double calCost(ArrayList<CallRecord> callRecords) { return 0; } } class LandPhoneInCityRule extends CallChargeRule{ double cost; public double calCost(ArrayList<CallRecord> callRecords) { cost = 0; for (CallRecord callRecord : callRecords) { if(callRecord.getCallingNumber().matches("0\\d{10,11}")&&callRecord.getAnswerAddressAreaCode().matches("0791")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.1; } else { cost += ((int) minute * 0.1 + 0.1); } } else if(callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getAnswerAddressAreaCode().matches("0791")&&callRecord.getCallingAddressAreaCode().matches("0791")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.1; } else { cost += ((int) minute * 0.1 + 0.1); } } else if(callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getAnswerAddressAreaCode().matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")&&callRecord.getCallingAddressAreaCode().matches("0791")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.2; } else { cost += ((int) minute * 0.2 + 0.2); } } else if (callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getAnswerAddressAreaCode().matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")&&callRecord.getCallingAddressAreaCode().matches("0791")) { double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.3; } else { cost += ((int) minute * 0.3 + 0.3); } } } return cost; } } class LandPhoneInProvinceRule extends CallChargeRule{ double cost; public double calCost(ArrayList<CallRecord> callRecords) { cost = 0; for (CallRecord callRecord : callRecords) { if(callRecord.getCallingNumber().matches("0\\d{10,11}")&&callRecord.getAnswerAddressAreaCode().matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.3; } else { cost += ((int) minute * 0.3 + 0.3); } } else if (callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getCallingAddressAreaCode().matches("(079[0,2,3,4,5,6,7,8,9])|(0701)")) { double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.3; } else { cost += ((int) minute * 0.3 + 0.3); } } } return cost; } } class LandPhoneInLandRule extends CallChargeRule{ double cost; public double calCost(ArrayList<CallRecord> callRecords) { cost = 0; for (CallRecord callRecord : callRecords) { if(callRecord.getCallingNumber().matches("0\\d{10,11}")&&callRecord.getAnswerAddressAreaCode().matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")){ double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.6; } else { cost += ((int) minute * 0.6 + 0.6); } } else if (callRecord.getCallingNumber().matches("1\\d{10}")&&callRecord.getCallingAddressAreaCode().matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")) { double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.6; } else { cost += ((int) minute * 0.6 + 0.6); } } else if (callRecord.getAnswerNumber().matches("1\\d{10}")&&callRecord.getAnswerAddressAreaCode().matches("0(([0-6]\\d{1,2})|(7[0-8]\\d)|([8-9](\\d)?))")) { double x = callRecord.endTime.getTime() - callRecord.startTime.getTime(); double second = (x / 1000); double minute = second / 60; if (second % 60 == 0) { cost += minute * 0.3; } else { cost += ((int) minute * 0.3 + 0.3); } } } return cost; } }

类图与题目集08-01一样不过我添加了一个MobilePhoneCharges类用于计算手机的通话费用。

3、题目集10-01:电信计费系列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。
本题只考虑短信计费,不考虑通信费用以及月租费。
难点:
本次作业难度变小,主要在于不考虑通信费用以及月租费。
主要考察的是正则表达式的运用和对于前两次作业中类图的掌握能力和理解能力。
还有就是看写代码时是否考虑充分,有大量的测试点,测试点测试各种细节。
思路:
使用while循环一行行读取,然后对每一行利用split按空格分开对于短信不放再连接起来然后用正则表达式判断输入的格式是否正确。
import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class Main { public static void main(String args[]) throws ParseException { Scanner input = new Scanner(System.in); User[] user = new User[20]; int x = -1,g = 0; String str3 = "([1-2]\\d{3}[.]([1-9]|1[0,1,2])[.]([1-9]|[1-2]\\d|30|31))\\s((20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d)"; while (true) { String arr = input.nextLine(); if (arr.equals("end")) { break; } String[] str = arr.split(" "); SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); if ((str[0].matches("u-0791\\d{7,8}") && str[1].equals("0"))|| (str[0].matches("u-1\\d{10}")&&str[1].equals("1"))|| (str[0].matches("u-1\\d{10}")&&str[1].equals("3"))) { if(user[0]==null){ x++; String[] arr1 = str[0].split("-"); user[x] = new User(); user[x].setNumber(arr1[1]); } else { g=0; for(int i = 0;user[i]!=null;i++) { String[] arr1 = str[0].split("-"); if(user[i].number.equals(arr1[1])) {g++;} } if(g==0){ x++; String[] arr1 = str[0].split("-"); user[x] = new User(); user[x].setNumber(arr1[1]); } } } else { for (int k = 0; k<=x; k++) { if(str[0].matches("m-1\\d{10}")&&str[1].matches("1\\d{10}")){ MessageRecords MessageRecords = new MessageRecords(); for (int i = 2;i<str.length;i++){ if(i==2){ MessageRecords.setMessage(str[i]); }else { MessageRecords.setMessage(MessageRecords.getMessage().concat(" ")); MessageRecords.setMessage(MessageRecords.getMessage().concat(str[i])); } } if(!MessageRecords.getMessage().matches("^[A-Za-z\\d.,\\s]+$")){ MessageRecords.setMessage(null); } if(MessageRecords.getMessage()!=null){ String arr1 = str[0].substring(2); if (arr1.equals(user[k].number)) { user[k].userRecords.addSendMessageRecords(MessageRecords); } else if (str[1].equals(user[k].number)){ user[k].userRecords.addReceiveMessageRecords(MessageRecords); } } } } } } String[] arr3 = new String [x+1]; for (int k = 0;k<=x;k++){ arr3[k] = user[k].number; } Arrays.sort(arr3, String::compareToIgnoreCase); for(int k = 0;k<=x;k++){ for(int j = 0;j<=x;j++){ if(user[j].number.equals(arr3[k])){ User az; az = user[k]; user[k] = user[j]; user[j] = az; } } } DecimalFormat df = new DecimalFormat("0.0"); MobilePhoneMessageCharges MobilePhoneMessageCharges = new MobilePhoneMessageCharges(); for(int k = 0;k<=x;k++){ System.out.println(user[k].number + " " + Double.parseDouble(df.format(MobilePhoneMessageCharges.calCost(user[k].userRecords)))+" "+Double.parseDouble(df.format(MobilePhoneMessageCharges.getMonthlyRent()))); } } } class User{ UserRecords userRecords = new UserRecords(); double balance = 100; String number; public double calBalance(){ return 0; } public double calCost(){ return 0; } public UserRecords getUserRecords() { return userRecords; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public void setUserRecords(UserRecords userRecords) {this.userRecords = userRecords; } } class UserRecords{ ArrayList<MessageRecords> sendMessageRecords = new ArrayList<MessageRecords>(); ArrayList<MessageRecords> receiveMessageRecords = new ArrayList<MessageRecords>(); public void addSendMessageRecords(MessageRecords MessageRecords) { sendMessageRecords.add(MessageRecords); } public void addReceiveMessageRecords(MessageRecords MessageRecords) { receiveMessageRecords.add(MessageRecords); } public ArrayList<MessageRecords> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecords> getReceiveMessageRecords() { return receiveMessageRecords; } } class MobilePhoneMessageCharges{ double cost; public double calCost(UserRecords userRecords){ SendMessageRule SendMessageRule = new SendMessageRule(); cost = SendMessageRule.calCost(userRecords.sendMessageRecords); return cost; } public double getMonthlyRent() { return 100-cost; } } class MessageRecords extends CommunicationRecord{ String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } abstract class CommunicationRecord{ String callingNumber; 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;} } abstract class MessageChargeRule extends MessageRecords{ } class SendMessageRule extends MessageRecords{ double cost; int num = 0; public double calCost(ArrayList<MessageRecords> messageRecords){ for(MessageRecords messageRecords1:messageRecords){ if(messageRecords1.getMessage().length()%10==0){ num += messageRecords1.getMessage().length()/10; num--; }else { num += messageRecords1.getMessage().length()/10+1; num--; } num++; } if(num<=3){ cost += num*0.1; } else if (num>3&&num<=5) { cost += (num-3)*0.2+0.3; } else if ((num>5)) { cost += (num-5)*0.3+0.7; } return cost; } }


4、宾馆入住系统
要求:
要求按照老师发的类图来写代码,要求有支付方式的选择等等之类还有两个小时要求。
难点:
不能很好的使用继承与多态,对于抽象类也不是很清楚,也不能很好的看懂老师发的类图。
思路:


对于老师的要求完成的不是很好,也不知道怎么解决。
三.采坑心得:
电信计费系列:
对于类的设计还不行,不能很好的搞懂类与类之间的关系,还有就是在写代码时用的是数组而没有用Arraylist类,对于多态、继承掌握不够熟练不能对他们进行调用。
宾馆入住系统:
看不懂类图不能很好理解类图,遇见问题也没有去问问,也没有和别人去讨论问题。
四.改进建议:
以后遇见问题不能自己一个人死磕多去问问多和别人讨论问题,多看看菜鸟上的继承和多态。

浙公网安备 33010602011771号