前言
电信计费系列题目虽然难度相对于多边形系列有所下降,但涉及知识点很广,主要如下:
1、容器的使用
2、抛出异常
3、抽象类
4、继承与多态
5、正则表达式
6、类和对象
设计与分析
第一题
实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租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元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package 电信计费1; 2 import java.text.DecimalFormat; 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.ArrayList; 6 import java.util.Scanner; 7 import java.util.*; 8 public class Main { 9 public static void main(String[] args) { 10 Scanner input = new Scanner(System.in); 11 ArrayList<User> usersArrayList = new ArrayList<>(); 12 String str = input.nextLine(); 13 boolean repetition = false; 14 while (!str.equals("end")){ 15 if(str.matches("u\\-0791\\d{7,8}\\s0")){ 16 String str1[] = str.split("-"); 17 String str2[] = str1[1].split(" "); 18 //System.out.println(str2[0]); 19 for(int i = 0;i < usersArrayList.size();i++){ 20 if(usersArrayList.get(i).number.equals(str2[0])) { 21 repetition = true; 22 break; 23 } 24 } 25 if(repetition == false){ 26 usersArrayList.add(new User(str2[0])); 27 } 28 } 29 if(str.matches("t-(\\d){11,12}\\s(\\d){10,12}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d")){ 30 String str3[] = str.split("-"); 31 String str4[] = str3[1].split(" "); 32 //System.out.println(str4[0]); 33 // System.out.println(str4[1]); 34 for (int i = 0;i < usersArrayList.size();i++){ 35 if(usersArrayList.get(i).number.equals(str4[0])){ 36 //南昌市 37 if(str4[1].substring(0,4).matches("0791")){ 38 usersArrayList.get(i).getUserRecords().addgetCallingInCityRecords(new CallRecord(str4[2]+" "+str4[3],str4[4]+" "+str4[5])); 39 usersArrayList.get(i).setUserRecords(usersArrayList.get(i).getUserRecords()); 40 } 41 //江西各市区以及0701 42 else if(str4[1].substring(0,4).matches("079\\d|0701")){ 43 usersArrayList.get(i).getUserRecords().addgetCallingInProvinceRecords(new CallRecord(str4[2]+" "+str4[3],str4[4]+" "+str4[5])); 44 usersArrayList.get(i).setUserRecords(usersArrayList.get(i).getUserRecords()); 45 } 46 else 47 usersArrayList.get(i).getUserRecords().addgetCallingInLandRecords(new CallRecord(str4[2]+" "+str4[3],str4[4]+" "+str4[5])); 48 usersArrayList.get(i).setUserRecords(usersArrayList.get(i).getUserRecords()); 49 } 50 } 51 } 52 str = input.nextLine(); 53 } 54 55 Collections.sort(usersArrayList,new Comparator<User>() { 56 public int compare(User o1, User o2) { 57 return o1.getNumber().compareTo(o2.getNumber()); 58 } 59 }); 60 for(int i = 0;i<usersArrayList.size();i++){ 61 System.out.print(usersArrayList.get(i).number+" "); 62 System.out.print(new DecimalFormat("0.0#").format(usersArrayList.get(i).calCost())+" "); 63 System.out.print(new DecimalFormat("0.0#").format(usersArrayList.get(i).getBalance()-usersArrayList.get(i).calCost()-20)); 64 System.out.println(); 65 } 66 } 67 } 68 package 电信计费1; 69 70 class User { 71 private UserRecords userRecords = new UserRecords(); 72 double balance = 100;//用户初始余额77 73 String number; 74 ChargeMode chargeMode; 75 public User(String number) { 76 // TODO Auto-generated method stub 77 this.number = number; 78 } 79 public double CalBalance(){ 80 return 0; 81 } 82 public double calCost(){ 83 LandPhoneInCityRule landPhoneInCityRule = new LandPhoneInCityRule(); 84 LandPhoneInLandRule landPhoneInLandRule = new LandPhoneInLandRule(); 85 LandPhoneInProvinceRule landPhoneInProvinceRule = new LandPhoneInProvinceRule(); 86 return landPhoneInLandRule.calCost(userRecords.getCallingInLandRecords())+landPhoneInCityRule.calCost(userRecords.getCallingInCityRecords())+landPhoneInProvinceRule.calCost(userRecords.getCallingInProvinceRecords()); 87 } 88 public UserRecords getUserRecords() { 89 return userRecords; 90 } 91 public void setUserRecords(UserRecords userRecords) { 92 this.userRecords = userRecords; 93 } 94 public double getBalance() { 95 return balance; 96 } 97 public String getNumber() { 98 return number; 99 } 100 public void setNumber(String number) { 101 this.number = number; 102 } 103 public ChargeMode getChargeMode() { 104 return chargeMode; 105 } 106 public void setChargeMode(ChargeMode chargeMode) { 107 this.chargeMode = chargeMode; 108 } 109 } 110 package 电信计费1; 111 import java.util.ArrayList; 112 class UserRecords{ 113 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 114 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 115 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); 116 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); 117 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); 118 private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); 119 //private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); 120 //private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); 121 122 public ArrayList<CallRecord> getCallingInCityRecords() { 123 return callingInCityRecords; 124 } 125 126 public ArrayList<CallRecord> getCallingInProvinceRecords() { 127 return callingInProvinceRecords; 128 } 129 130 public ArrayList<CallRecord> getCallingInLandRecords() { 131 return callingInLandRecords; 132 } 133 134 public ArrayList<CallRecord> getAnswerInCityRecords() { 135 return answerInCityRecords; 136 } 137 138 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 139 return answerInProvinceRecords; 140 } 141 142 public ArrayList<CallRecord> getAnswerInLandRecords() { 143 return answerInLandRecords; 144 } 145 146 /*public ArrayList<MessageRecord> getSendMessageRecords() { 147 return sendMessageRecords; 148 } 149 150 public ArrayList<MessageRecord> getReceiveMessageRecords() { 151 return receiveMessageRecords; 152 }*/ 153 154 public void addgetCallingInCityRecords(CallRecord callRecord){ 155 getCallingInCityRecords().add(callRecord); 156 } 157 158 public void addgetCallingInProvinceRecords(CallRecord callRecord){ 159 getCallingInProvinceRecords().add(callRecord); 160 } 161 162 public void addgetCallingInLandRecords(CallRecord callRecord){ 163 getCallingInLandRecords().add(callRecord); 164 } 165 166 public void addAnswerInCityRecords(CallRecord answerRecord){ 167 answerInCityRecords.add(answerRecord); 168 } 169 170 public void addAnswerInProvinceRecords(CallRecord answerRecord){ 171 answerInProvinceRecords.add(answerRecord); 172 } 173 174 public void addAnswerInLandRecords(CallRecord answerRecord){ 175 answerInLandRecords.add(answerRecord); 176 } 177 178 /*public void addSendMessageRecords(MessageRecord sendMessageRecord){ 179 sendMessageRecords.add(sendMessageRecord); 180 } 181 182 public void addReceiveMessageRecords(MessageRecord receiveMessageRecord){ 183 receiveMessageRecords.add(receiveMessageRecord); 184 }*/ 185 } 186 package 电信计费1; 187 import java.text.ParseException; 188 import java.text.SimpleDateFormat; 189 import java.util.Date; 190 191 class CallRecord extends CommunicationRecord{ 192 private Date startTime; 193 private Date endTime; 194 private String callingAddressAreaCode; 195 private String answerAddressAreaCode; 196 197 public CallRecord(String startTime, String endTime) { 198 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 199 try { 200 this.startTime = simpleDateFormat.parse(startTime); 201 } catch (ParseException e) { 202 e.printStackTrace(); 203 } 204 try { 205 this.endTime = simpleDateFormat.parse(endTime); 206 } catch (ParseException e) { 207 e.printStackTrace(); 208 } 209 } 210 211 public Date getStartTime() { 212 return startTime; 213 } 214 215 public void setStartTime(Date startTime) { 216 this.startTime = startTime; 217 } 218 219 public String getCallingAddressAreaCode() { 220 return callingAddressAreaCode; 221 } 222 223 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 224 this.callingAddressAreaCode = callingAddressAreaCode; 225 } 226 227 public Date getEndTime() { 228 return endTime; 229 } 230 231 public void setEndTime(Date endTime) { 232 this.endTime = endTime; 233 } 234 235 public String getAnswerAddressAreaCode() { 236 return answerAddressAreaCode; 237 } 238 239 public void setAnswerAddressAreaCode(String answerAddressAreaCode) { 240 this.answerAddressAreaCode = answerAddressAreaCode; 241 } 242 } 243 package 电信计费1; 244 245 import java.util.ArrayList; 246 247 abstract class CallChargeRule extends ChargeRule{ 248 public double calCost(ArrayList<CallRecord> callRecords){ 249 250 return 0; 251 } 252 } 253 package 电信计费1; 254 import java.util.ArrayList; 255 abstract class ChargeMode{ 256 private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); 257 258 public ArrayList<ChargeRule> getChargeRules() { 259 return chargeRules; 260 } 261 262 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 263 this.chargeRules = chargeRules; 264 } 265 266 public double calCost(UserRecords userRecords){ 267 return 0; 268 } 269 270 public double getMonthlyRent(){ 271 272 return 20; 273 } 274 } 275 package 电信计费1; 276 277 abstract class ChargeRule { 278 279 } 280 package 电信计费1; 281 282 abstract class CommunicationRecord{ 283 protected String callingNumber; 284 protected String answerNumber; 285 286 public String getCallingNumber() { 287 return callingNumber; 288 } 289 290 public void setCallingNumber(String callingNumber) { 291 292 this.callingNumber = callingNumber; 293 } 294 295 public String getAnswerNumber() { 296 return answerNumber; 297 } 298 299 public void setAnswerNumber(String answerNumber) { 300 this.answerNumber = answerNumber; 301 } 302 } 303 package 电信计费1; 304 305 class LandlinePhoneCharging extends ChargeMode{ 306 private double monthlyRent = 20; 307 308 @Override 309 public double calCost(UserRecords userRecords) { 310 return 0; 311 } 312 313 @Override 314 public double getMonthlyRent() { 315 return monthlyRent; 316 } 317 } 318 package 电信计费1; 319 320 import java.util.ArrayList; 321 322 class LandPhoneInCityRule extends CallChargeRule{ 323 @Override 324 public double calCost(ArrayList<CallRecord> callRecords) { 325 double cost = 0; 326 double minutes; 327 for(CallRecord e:callRecords){ 328 long diff = e.getEndTime().getTime() - e.getStartTime().getTime(); 329 minutes = (int) Math.ceil((double) diff / (double) 60000); 330 cost += 0.1*minutes; 331 } 332 return cost; 333 } 334 } 335 package 电信计费1; 336 337 import java.util.ArrayList; 338 339 class LandPhoneInLandRule extends CallChargeRule{ 340 @Override 341 public double calCost(ArrayList<CallRecord> callRecords) { 342 double cost = 0; 343 double minutes; 344 for(CallRecord e:callRecords){ 345 long diff = e.getEndTime().getTime() - e.getStartTime().getTime(); 346 minutes = (int) Math.ceil((double) diff / (double) 60000); 347 cost += 0.6*minutes; 348 } 349 return cost; 350 } 351 } 352 package 电信计费1; 353 354 import java.util.ArrayList; 355 356 class LandPhoneInProvinceRule extends CallChargeRule{ 357 @Override 358 public double calCost(ArrayList<CallRecord> callRecords) { 359 double cost = 0; 360 double minutes; 361 for(CallRecord e:callRecords){ 362 long diff = e.getEndTime().getTime() - e.getStartTime().getTime(); 363 minutes = (int) Math.ceil((double) diff / (double) 60000); 364 cost += 0.3*minutes; 365 } 366 return cost; 367 } 368 } 369 package 电信计费1; 370 371 class MessageRecord extends CommunicationRecord{ 372 private String message; 373 374 public String getMessage() { 375 return message; 376 } 377 378 public void setMessage(String message) { 379 this.message = message; 380 } 381 }View Code
设计思路
1.本题的要点和难点就是读懂类图,根据已有类图合理设计一个电信计费程序,清楚每个类的用处,要有个整体的框架。
2.User类是用来储存用户的各类信息,包括电话号码、通话记录、计费方式等;
3.ChargeMode类是用来确定用户的计费类型;
4.UserRecords是用来储存用户的通讯记录,包括接电话与打电话在市内、省内、国内长途的记录和用户接发短信记录;
5.CommunicationRecord是抽象的通话记录类,记录通话与短信;
6.CallRecord用于记录通话起始时间和拨号、接听电话的区号;
7.ChargeRule类是计费的具体规则,通过LandPhoneInCityRule、LandPhoneInLandRule、LandPhoneInProvinceRule三个类分别进行市内、省外、省内的计费计算。
8.要实现计费流程,需要按照一定的步骤进行,先创建用户,再实现用户的通信计费。由于本次题目只需实现座机计费,因此不必考虑短信计费。但建议在设计时预留好短信计费的接口。
9.在主函数中,依次输入开户信息和通讯信息后,依靠正则表达式对输入信息进行判断。这也是难点之一。开户信息通过创建user类的容器ArrayList中,通讯信息通过匹配到储存到容器中的用户信息进行具体运算后得到话费与余额信息。
SourceMonitor的生成报表
PowerDesigner类图
题目已经给出类图,无需设计类图
第二题
实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
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元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package 电信计费2; 2 3 import java.text.DecimalFormat; 4 import java.text.ParseException; 5 import java.text.SimpleDateFormat; 6 import java.util.*; 7 8 public class Main { 9 public static void main(String[] args) { 10 Scanner input = new Scanner(System.in); 11 ArrayList<Users> usersArrayList = new ArrayList<>(); 12 String str = input.nextLine(); 13 boolean repetition = false; 14 while (!str.equals("end")){ 15 //座机开户 16 if(str.matches("u\\-0791\\d{7,8}\\s0")){ 17 String str1[] = str.split("-"); 18 String str2[] = str1[1].split(" "); 19 //判断是否录入完成 20 for(int i = 0;i < usersArrayList.size();i++){ 21 if(usersArrayList.get(i).number.equals(str2[0])) { 22 repetition = true; 23 break; 24 } 25 } 26 if(repetition == false){ 27 usersArrayList.add(new Users(str2[0])); 28 } 29 repetition = false; 30 } 31 //手机开户 32 else if (str.matches("u-1[0-9]{10}\\s1")){ 33 String str5[] = str.split("-"); 34 String str6[] = str5[1].split(" "); 35 for(int i = 0;i < usersArrayList.size();i++){ 36 if(usersArrayList.get(i).number.equals(str6[0])) { 37 repetition = true; 38 break; 39 } 40 } 41 if(repetition == false){ 42 usersArrayList.add(new Users(str6[0])); 43 } 44 repetition = false; 45 } 46 //座机打座机 47 if(str.matches("t-0791\\d{7,8}\\s\\d{11,12}\\s\\d{4}\\.\\d{1,2}\\.\\d{1,2}\\s\\d{1,2}\\:\\d{1,2}\\:\\d{1,2}\\s\\d{4}\\.\\d{1,2}\\.\\d{1,2}\\s\\d{1,2}\\:\\d{1,2}\\:\\d{1,2}")){ 48 String str3[] = str.split("-"); 49 String str4[] = str3[1].split(" "); 50 for (int i = 0;i < usersArrayList.size();i++){ 51 if(usersArrayList.get(i).number.equals(str4[0])){ 52 if(str4[1].substring(0,4).matches("0791")){ 53 usersArrayList.get(i).getUserRecords().addgetCallingInCityRecords(new CallRecord(str4[2]+" "+str4[3],str4[4]+" "+str4[5])); 54 // usersArrayList.get(i).setUserRecords(usersArrayList.get(i).getUserRecords()); 55 } 56 else if(str4[1].substring(0,4).matches("079\\d|0701")){ 57 usersArrayList.get(i).getUserRecords().addgetCallingInProvinceRecords(new CallRecord(str4[2]+" "+str4[3],str4[4]+" "+str4[5])); 58 // usersArrayList.get(i).setUserRecords(usersArrayList.get(i).getUserRecords()); 59 } 60 else 61 usersArrayList.get(i).getUserRecords().addgetCallingInLandRecords(new CallRecord(str4[2]+" "+str4[3],str4[4]+" "+str4[5])); 62 //usersArrayList.get(i).setUserRecords(usersArrayList.get(i).getUserRecords()); 63 } 64 } 65 } 66 //座机打手机 67 else if (str.matches("t-0\\d{9,11} 1\\d{10} 0\\d{2,3}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d")){ 68 String str7[] = str.substring(2,str.length()).split("\\s"); 69 for (int i=0;i< usersArrayList.size();i++){ 70 if (usersArrayList.get(i).number.equals(str7[0])){ 71 if (str7[2].startsWith("0791")){ 72 usersArrayList.get(i).getUserRecords().addgetCallingInCityRecords(new CallRecord(str7[3] + " " + str7[4], str7[5] + " " + str7[6])); 73 } 74 else if (str7[2].matches("(079\\d|0701)")){ 75 usersArrayList.get(i).getUserRecords().addgetCallingInProvinceRecords(new CallRecord(str7[3] + " " + str7[4], str7[5] + " " + str7[6])); 76 } 77 else { 78 usersArrayList.get(i).getUserRecords().addgetCallingInLandRecords(new CallRecord(str7[3] + " " + str7[4], str7[5] + " " + str7[6])); 79 } 80 } 81 if (usersArrayList.get(i).number.equals(str7[1])){ 82 if (!str7[2].matches("(079\\d|0701)")) 83 usersArrayList.get(i).getUserRecords().addAnswerInLandRecords(new CallRecord(str7[3] + " " + str7[4], str7[5] + " " + str7[6])); 84 } 85 } 86 87 } 88 //手机打座机 89 else if (str.matches( "t-1\\d{10} 0\\d{2,3} 0\\d{9,11}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d" )){ 90 String str9[] = str.substring(2,str.length()).split(" "); 91 for (int i=0;i< usersArrayList.size();i++){ 92 if (usersArrayList.get(i).number.equals(str9[0])){ 93 if (str9[1].equals("0791")){ 94 if (str9[2].matches("0791\\d{6,8}")) 95 usersArrayList.get(i).getUserRecords().addgetCallingInCityRecords(new CallRecord(str9[3] + " " + str9[4], str9[5] + " " + str9[6])); 96 else if (str9[2].matches("(079\\d|0701)\\d{6,8}")) 97 usersArrayList.get(i).getUserRecords().addgetCallingInProvinceRecords(new CallRecord(str9[3] + " " + str9[4], str9[5] + " " + str9[6])); 98 else 99 usersArrayList.get(i).getUserRecords().addgetCallingInLandRecords(new CallRecord(str9[3] + " " + str9[4], str9[5] + " " + str9[6])); 100 } 101 else if (str9[1].matches("(0701|0790|079[2-9])")){ 102 usersArrayList.get(i).getUserRecords().addgetCallingInProvinceRoamRecords(new CallRecord(str9[3] + " " + str9[4], str9[5] + " " + str9[6])); 103 } 104 else 105 usersArrayList.get(i).getUserRecords().addCallingInLandRoamRecords(new CallRecord(str9[3] + " " + str9[4], str9[5] + " " + str9[6])); 106 } 107 } 108 } 109 //手机打手机 110 else if (str.matches("t-1\\d{10} 0\\d{2,3} 1\\d{10} 0\\d{2,3}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d")){ 111 String str10[] = str.substring(2,str.length()).split(" "); 112 for (int i=0;i< usersArrayList.size();i++){ 113 if (usersArrayList.get(i).number.equals(str10[0])){ 114 if (str10[1].equals("0791")) { 115 if (str10[3].matches("0791")) 116 usersArrayList.get(i).getUserRecords().addgetCallingInCityRecords(new CallRecord(str10[4] + " " + str10[5], str10[6] + " " + str10[7])); 117 else if (str10[3].matches("(079\\d|0701)")) 118 usersArrayList.get(i).getUserRecords().addgetCallingInProvinceRecords(new CallRecord(str10[4] + " " + str10[5], str10[6] + " " + str10[7])); 119 else 120 usersArrayList.get(i).getUserRecords().addgetCallingInLandRecords(new CallRecord(str10[4] + " " + str10[5], str10[6] + " " + str10[7])); 121 } 122 else if (str10[1].matches("(0701|079\\d)")){ 123 usersArrayList.get(i).getUserRecords().addgetCallingInProvinceRoamRecords(new CallRecord(str10[4] + " " + str10[5], str10[6] + " " + str10[7])); 124 } 125 else 126 usersArrayList.get(i).getUserRecords().addCallingInLandRoamRecords(new CallRecord(str10[4] + " " + str10[5], str10[6] + " " + str10[7])); 127 } 128 if (usersArrayList.get(i).number.equals(str10[2])){ 129 if (!str10[3].matches("(079\\d|0701)")) 130 usersArrayList.get(i).getUserRecords().addAnswerInLandRecords(new CallRecord(str10[4] + " " + str10[5], str10[6] + " " + str10[7])); 131 } 132 } 133 } 134 str = input.nextLine(); 135 } 136 137 Collections.sort(usersArrayList,new Comparator<Users>() { 138 @Override 139 public int compare(Users o1, Users o2) { 140 return o1.getNumber().compareTo(o2.getNumber()); 141 } 142 }); 143 for(int i = 0;i<usersArrayList.size();i++){ 144 System.out.print(usersArrayList.get(i).number+" "); 145 System.out.print(new DecimalFormat("0.0#").format(usersArrayList.get(i).calCost())+" "); 146 System.out.print(new DecimalFormat("0.0#").format(usersArrayList.get(i).calBalance())); 147 System.out.println(); 148 } 149 150 } 151 } 152 153 class Users{ 154 private UserRecords userRecords = new UserRecords(); 155 double balance = 100; 156 String number; 157 ChargeMode chargeMode; 158 159 public Users(String number) { 160 this.number = number; 161 } 162 163 public double CalBalance(){ 164 return 0; 165 } 166 167 public double calCost(){ 168 LandPhoneInCityRule landPhoneInCityRule = new LandPhoneInCityRule(); 169 LandPhoneInLandRule landPhoneInLandRule = new LandPhoneInLandRule(); 170 LandPhoneInProvinceRule landPhoneInProvinceRule = new LandPhoneInProvinceRule(); 171 PhoneInCityRule phoneInCityRule = new PhoneInCityRule(); 172 PhoneInIandRule phoneInIandRule = new PhoneInIandRule(); 173 PhoneInProvinceRule phoneInProvinceRule = new PhoneInProvinceRule(); 174 PhoneInIandRoamRule phoneInIandRoamRule = new PhoneInIandRoamRule(); 175 PhoneInProvinceRoamRule phoneInProvinceRoamRule = new PhoneInProvinceRoamRule(); 176 ReceptionPhoneInLandRoamRule receptionPhoneInLandRoamRule = new ReceptionPhoneInLandRoamRule(); 177 if(number.matches("(0791)\\d{6,8}")) 178 return landPhoneInLandRule.calCost(userRecords.getCallingInLandRecords())+landPhoneInCityRule.calCost(userRecords.callingInCityRecords)+landPhoneInProvinceRule.calCost(userRecords.getCallingInProvinceRecords()); 179 return phoneInIandRule.calCost(userRecords.getCallingInLandRecords())+phoneInCityRule.calCost(userRecords.callingInCityRecords)+phoneInProvinceRule.calCost(userRecords.getCallingInProvinceRecords())+receptionPhoneInLandRoamRule.calCost(userRecords.getAnswerInLandRecords())+phoneInIandRoamRule.calCost(userRecords.getCallingInLandRoamRecords())+phoneInProvinceRoamRule.calCost(userRecords.getCallingInProvinceRoamRecords()); 180 } 181 182 public double calBalance(){ 183 if(number.matches("(0791)\\d{6,8}")) 184 return balance-calCost()-20; 185 return balance-calCost()-15; 186 } 187 188 public UserRecords getUserRecords() { 189 return userRecords; 190 } 191 192 public void setUserRecords(UserRecords userRecords) { 193 this.userRecords = userRecords; 194 } 195 196 public double getBalance() { 197 return balance; 198 } 199 200 public String getNumber() { 201 return number; 202 } 203 204 public void setNumber(String number) { 205 this.number = number; 206 } 207 208 public ChargeMode getChargeMode() { 209 return chargeMode; 210 } 211 212 public void setChargeMode(ChargeMode chargeMode) { 213 this.chargeMode = chargeMode; 214 } 215 216 } 217 218 class UserRecords{ 219 ArrayList<CallRecord> callingInProvinceRoamRecords = new ArrayList<CallRecord>(); 220 ArrayList<CallRecord> callingInLandRoamRecords = new ArrayList<CallRecord>(); 221 ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 222 ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 223 ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); 224 ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); 225 ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); 226 ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); 227 ArrayList<MessageRecord> sendMessageRecord = new ArrayList<MessageRecord>(); 228 229 public ArrayList<CallRecord> getCallingInProvinceRecords() { 230 return callingInProvinceRecords; 231 } 232 233 public ArrayList<CallRecord> getCallingInLandRecords() { 234 return callingInLandRecords; 235 } 236 237 public ArrayList<CallRecord> getAnswerInCityRecords() { 238 return answerInCityRecords; 239 } 240 241 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 242 return answerInProvinceRecords; 243 } 244 245 public ArrayList<CallRecord> getAnswerInLandRecords() { 246 return answerInLandRecords; 247 } 248 249 250 public ArrayList<CallRecord> getCallingInProvinceRoamRecords() { 251 return callingInProvinceRoamRecords; 252 } 253 254 public ArrayList<CallRecord> getCallingInLandRoamRecords() { 255 return callingInLandRoamRecords; 256 } 257 258 public void addgetCallingInCityRecords(CallRecord callRecord){ 259 callingInCityRecords.add(callRecord); 260 } 261 262 public void addgetCallingInProvinceRecords(CallRecord callRecord){ 263 getCallingInProvinceRecords().add(callRecord); 264 } 265 266 public void addgetCallingInLandRecords(CallRecord callRecord){ 267 getCallingInLandRecords().add(callRecord); 268 } 269 270 public void addAnswerInCityRecords(CallRecord answerRecord){ 271 answerInCityRecords.add(answerRecord); 272 } 273 274 public void addAnswerInProvinceRecords(CallRecord answerRecord){ 275 answerInProvinceRecords.add(answerRecord); 276 } 277 278 public void addAnswerInLandRecords(CallRecord answerRecord){ 279 answerInLandRecords.add(answerRecord); 280 } 281 282 283 284 285 public void addgetCallingInProvinceRoamRecords(CallRecord callRecord) { 286 callingInProvinceRoamRecords.add(callRecord); 287 } 288 289 public void addCallingInLandRoamRecords(CallRecord callRecord) { 290 callingInLandRoamRecords.add(callRecord); 291 } 292 293 } 294 295 abstract class ChargeMode{ 296 private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); 297 298 public ArrayList<ChargeRule> getChargeRules() { 299 return chargeRules; 300 } 301 302 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 303 this.chargeRules = chargeRules; 304 } 305 306 public double calCost(UserRecords userRecords){ 307 return 0; 308 } 309 310 public double getMonthlyRent(){ 311 312 return 20; 313 } 314 } 315 316 class LandlinePhoneCharging extends ChargeMode{ 317 private double monthlyRent = 20; 318 319 @Override 320 public double calCost(UserRecords userRecords) { 321 return 0; 322 } 323 324 @Override 325 public double getMonthlyRent() { 326 return monthlyRent; 327 } 328 } 329 330 abstract class CommunicationRecord{ 331 protected String callingNumber; 332 protected String answerNumber; 333 334 public String getCallingNumber() { 335 return callingNumber; 336 } 337 338 public void setCallingNumber(String callingNumber) { 339 340 this.callingNumber = callingNumber; 341 } 342 343 public String getAnswerNumber() { 344 return answerNumber; 345 } 346 347 public void setAnswerNumber(String answerNumber) { 348 this.answerNumber = answerNumber; 349 } 350 } 351 352 class CallRecord extends CommunicationRecord{ 353 private Date startTime; 354 private Date endTime; 355 private String callingAddressAreaCode; 356 private String answerAddressAreaCode; 357 358 public CallRecord(String startTime, String endTime) { 359 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 360 try { 361 this.startTime = simpleDateFormat.parse(startTime); 362 } catch (ParseException e) { 363 e.printStackTrace(); 364 } 365 try { 366 this.endTime = simpleDateFormat.parse(endTime); 367 } catch (ParseException e) { 368 e.printStackTrace(); 369 } 370 } 371 372 public Date getStartTime() { 373 return startTime; 374 } 375 376 public void setStartTime(Date startTime) { 377 this.startTime = startTime; 378 } 379 380 public String getCallingAddressAreaCode() { 381 return callingAddressAreaCode; 382 } 383 384 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 385 this.callingAddressAreaCode = callingAddressAreaCode; 386 } 387 388 public Date getEndTime() { 389 return endTime; 390 } 391 392 public void setEndTime(Date endTime) { 393 this.endTime = endTime; 394 } 395 396 public String getAnswerAddressAreaCode() { 397 return answerAddressAreaCode; 398 } 399 400 public void setAnswerAddressAreaCode(String answerAddressAreaCode) { 401 this.answerAddressAreaCode = answerAddressAreaCode; 402 } 403 } 404 405 class MessageRecord extends CommunicationRecord{ 406 private String message; 407 408 public String getMessage() { 409 return message; 410 } 411 412 public void setMessage(String message) { 413 this.message = message; 414 } 415 } 416 417 abstract class ChargeRule{ 418 419 } 420 421 abstract class CallChargeRule extends ChargeRule{ 422 public double calCost(ArrayList<CallRecord> callRecords){ 423 424 return 0; 425 } 426 } 427 428 class LandPhoneInCityRule extends CallChargeRule{ 429 @Override 430 public double calCost(ArrayList<CallRecord> callRecords) { 431 double cost = 0; 432 double minutes; 433 for(CallRecord e:callRecords){ 434 long diff = e.getEndTime().getTime() - e.getStartTime().getTime(); 435 minutes = (int) Math.ceil((double) diff / (double) 60000); 436 cost += 0.1*minutes; 437 } 438 return cost; 439 } 440 } 441 442 class LandPhoneInLandRule extends CallChargeRule{ 443 @Override 444 public double calCost(ArrayList<CallRecord> callRecords) { 445 double cost = 0; 446 double minutes; 447 for(CallRecord e:callRecords){ 448 long diff = e.getEndTime().getTime() - e.getStartTime().getTime(); 449 minutes = (int) Math.ceil((double) diff / (double) 60000); 450 cost += 0.6*minutes; 451 } 452 return cost; 453 } 454 } 455 456 class LandPhoneInProvinceRule extends CallChargeRule{ 457 @Override 458 public double calCost(ArrayList<CallRecord> callRecords) { 459 double cost = 0; 460 double minutes; 461 for(CallRecord e:callRecords){ 462 long diff = e.getEndTime().getTime() - e.getStartTime().getTime(); 463 minutes = (int) Math.ceil((double) diff / (double) 60000); 464 cost += 0.3*minutes; 465 } 466 return cost; 467 } 468 } 469 470 class PhoneInProvinceRule extends CallChargeRule{ 471 public double calCost(ArrayList<CallRecord> callRecords){ 472 double money = 0.2; 473 double cost = 0; 474 double minutes; 475 for (CallRecord e: callRecords){ 476 minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000); 477 cost += money*minutes;} 478 return cost; 479 } 480 } 481 482 class PhoneInCityRule extends CallChargeRule{ 483 public double calCost(ArrayList<CallRecord> callRecords){ 484 double money = 0.1; 485 double cost = 0; 486 double minutes; 487 for (CallRecord e: callRecords){ 488 minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000); 489 cost += money*minutes;} 490 return cost; 491 } 492 } 493 class PhoneInIandRule extends CallChargeRule{ 494 public double calCost(ArrayList<CallRecord> callRecords){ 495 double money = 0.3; 496 double cost = 0; 497 double minutes; 498 for (CallRecord e: callRecords){ 499 minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000); 500 cost += money*minutes;} 501 return cost; 502 } 503 } 504 class PhoneInIandRoamRule extends CallChargeRule{//国内漫游打电话 505 public double calCost(ArrayList<CallRecord> callRecords){ 506 double money = 0.6; 507 double cost = 0; 508 double minutes; 509 for (CallRecord e: callRecords){ 510 minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000); 511 cost += money*minutes;} 512 return cost; 513 } 514 } 515 class PhoneInProvinceRoamRule extends CallChargeRule{//省内漫游打电话 516 public double calCost(ArrayList<CallRecord> callRecords){ 517 518 double money = 0.3; 519 double cost = 0; 520 double minutes; 521 for (CallRecord e: callRecords){ 522 minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000); 523 cost += money*minutes;} 524 return cost; 525 } 526 } 527 class ReceptionPhoneInLandRoamRule extends CallChargeRule{//接电话 528 public double calCost(ArrayList<CallRecord> callRecords){ 529 double money = 0.3; 530 double cost = 0; 531 double minutes; 532 for (CallRecord e: callRecords){ 533 minutes = (int) Math.ceil((double) (e.getEndTime().getTime()-e.getStartTime().getTime())/ (double) 60000); 534 cost += money*minutes;} 535 return cost; 536 } 537 }View Code
设计思路
1.在第一题的基础上增加了手机计费,设计流程还是一样,通过所给的类图搞清楚用户、通讯记录、拨打记录、收费模式之间的关系,写之前先进行大体的架构,理清楚脉络。
2.代码复杂度又增加了,最好写完一个函数后要写上相应的注释并且及时测试其功能。
SourceMonitor的生成表
PowerDesigner类图
题目已经给出类图,无需设计类图
第三题
实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
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。
本题只考虑短信计费,不考虑通信费用以及月租费。
代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package 电信计费3; 2 3 import java.text.DecimalFormat; 4 import java.text.ParseException; 5 import java.text.SimpleDateFormat; 6 import java.util.*; 7 8 public class Main { 9 public static void main(String[] args) { 10 Scanner input = new Scanner(System.in); 11 ArrayList<Users> usersArrayList = new ArrayList<>(); 12 String str = input.nextLine(); 13 boolean repetition = false; 14 while (!str.equals("end")){ 15 //手机开户 16 if (str.matches("u-1[0-9]{10} [3]")){ 17 String str1[] = str.split("-"); 18 String str2[] = str1[1].split(" "); 19 for (Users users : usersArrayList) { 20 if (users.number.equals(str2[0])) { 21 repetition = true; 22 } 23 } 24 if(!repetition){ 25 usersArrayList.add(new Users(str2[0])); 26 } 27 repetition = false; 28 } 29 else if (str.matches("m-1\\d{10} 1\\d{10} (\\w|\\,|\\.| )+")||str.matches("m-1\\d{10} 1\\d{10}")){ 30 String[] s = str.substring(2).split(" "); 31 for (Users e:usersArrayList){ 32 if(s[0].equals(e.getNumber())){ 33 e.getUserRecords().addSendMessageRecord(new MessageRecord(str.substring(26))); 34 } 35 } 36 } 37 str = input.nextLine(); 38 } 39 40 usersArrayList.sort(Comparator.comparing(Users::getNumber)); 41 for (Users users : usersArrayList) { 42 System.out.print(users.number + " "); 43 System.out.print(new DecimalFormat("0.0#").format(users.calCost()) + " "); 44 System.out.print(new DecimalFormat("0.0#").format(users.calBalance())); 45 System.out.println(); 46 } 47 } 48 } 49 50 class Users{ 51 private UserRecords userRecords = new UserRecords(); 52 double balance = 100; 53 String number; 54 55 public Users(String number) { 56 this.number = number; 57 } 58 59 public double calCost(){ 60 MessageChargeRule messageChargeRule = new MessageChargeRule(); 61 return messageChargeRule.calCost(userRecords.sendMessageRecord); 62 } 63 64 public double calBalance(){ 65 return balance-calCost(); 66 } 67 68 public UserRecords getUserRecords() { 69 return userRecords; 70 } 71 72 public String getNumber() { 73 return number; 74 } 75 76 } 77 78 class UserRecords{ 79 ArrayList<MessageRecord> sendMessageRecord = new ArrayList<MessageRecord>(); 80 public void addSendMessageRecord(MessageRecord sendMessageRecord){ 81 this.sendMessageRecord.add(sendMessageRecord); 82 } 83 } 84 85 abstract class ChargeMode{ 86 private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); 87 88 89 90 public double calCost(UserRecords userRecords){ 91 return 0; 92 } 93 94 public double getMonthlyRent(){ 95 96 return 20; 97 } 98 } 99 100 abstract class CommunicationRecord{ 101 protected String callingNumber; 102 protected String answerNumber; 103 104 public String getCallingNumber() { 105 return callingNumber; 106 } 107 108 public void setCallingNumber(String callingNumber) { 109 110 this.callingNumber = callingNumber; 111 } 112 113 public String getAnswerNumber() { 114 return answerNumber; 115 } 116 117 public void setAnswerNumber(String answerNumber) { 118 this.answerNumber = answerNumber; 119 } 120 } 121 122 class CallRecord extends CommunicationRecord{ 123 private Date startTime; 124 private Date endTime; 125 private String callingAddressAreaCode; 126 private String answerAddressAreaCode; 127 128 public CallRecord(String startTime, String endTime) { 129 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 130 try { 131 this.startTime = simpleDateFormat.parse(startTime); 132 } catch (ParseException e) { 133 e.printStackTrace(); 134 } 135 try { 136 this.endTime = simpleDateFormat.parse(endTime); 137 } catch (ParseException e) { 138 e.printStackTrace(); 139 } 140 } 141 142 } 143 144 class MessageRecord extends CommunicationRecord{ 145 private String message; 146 147 public MessageRecord(String message) { 148 this.message = message; 149 } 150 151 public String getMessage() { 152 return message; 153 } 154 155 public void setMessage(String message) { 156 this.message = message; 157 } 158 } 159 160 abstract class ChargeRule{ 161 162 } 163 164 abstract class ChargeMessage{ 165 ArrayList<ChargeRule> list = new ArrayList<ChargeRule>(); 166 public ArrayList<ChargeRule> getChargeRule(){ 167 return list; 168 } 169 public void setChargeRule(ArrayList<ChargeRule> chargeRule){ 170 this.list = list; 171 } 172 public double calCost(UserRecords userRecords){ 173 return 0; 174 } 175 public double getMonthlyRent(){ 176 return 0; 177 } 178 } 179 180 abstract class ChargePhone{ 181 ArrayList<ChargeRule> list = new ArrayList<ChargeRule>(); 182 public ArrayList<ChargeRule> getChargeRule(){ 183 return list; 184 } 185 public void setChargeRule(ArrayList<ChargeRule> chargeRule){ 186 this.list = list; 187 } 188 public double calCost(UserRecords userRecords){ 189 return 0; 190 } 191 public double getMonthlyRent(){ 192 return 15; 193 } 194 } 195 196 abstract class CallChargeRule extends ChargeRule{ 197 public double calCost(ArrayList<CallRecord> callRecords){ 198 199 return 0; 200 } 201 } 202 203 class MessageChargeRule extends ChargeRule{ 204 public double calCost(ArrayList<MessageRecord> messageRecords) { 205 double cost = 0; 206 double f = 0; 207 for (MessageRecord messageRecord : messageRecords) { 208 double a = messageRecord.getMessage().length(); 209 while (a > 0) { 210 f++; 211 a = a - 10; 212 } 213 } 214 if(f<=3){ 215 cost = 0.1*f; 216 }else if(f>3&&f<=5){ 217 cost = 0.3+0.2*(f-3); 218 }else if(f>5){ 219 cost = 0.3*(f-5)+0.7; 220 } 221 return cost; 222 } 223 } 224 225 class MessageCharging extends ChargeMessage{ 226 double monthlyRent = 0; 227 228 public double calCost(UserRecords userRecords){ 229 return 0; 230 } 231 public double getMonthlyRent(){ 232 return monthlyRent; 233 } 234 } 235 236 class MobilePhoneCharging extends ChargePhone{ 237 double monthlyRent = 15; 238 239 public double calCost(UserRecords userRecords){ 240 return 0; 241 } 242 public double getMonthlyRent(){ 243 return monthlyRent; 244 } 245 } 246 247 class SendMessageRule extends MessageChargeRule{ 248 @Override 249 public double calCost(ArrayList<MessageRecord> messageRecords) { 250 return super.calCost(messageRecords); 251 } 252 }View Code
设计思路
1.用户的开户以及多用户的关系与前面一致,不同在于前面是电话记录,而这题是在此基础上加入短信记录;之前的代码不用动,只要添加新的即可。
2.短信对于电话来说相对的简单一些,需要判断的情况也没有电话那么复杂,需要注意的就是短信条数的统计,短信计费是通过发送短信的条数进行的,短信条数也包括一条短信内容中每8个字算一条短信,不足8个算成8个来计算。
SourceMonitor的生成表
PowerDesigner类图
题目已经给出类图,无需设计类图
踩坑心得
1.输入格式的正则表达式,要注意日期的合法性。
2.根据题目要求,忽略重复开户的操作。
3.创建一个可储存用户的容器,判断输入的信息,如果判断为开户信息,再判断容器中是否存在相同的账户号码,不存在则在容器中添加该用户,如果判断为通话信息,在判断拨打号码和收听号码是否是容器中的号码,若是则将拨打(收听)信息存入用户中的储存相应信息的容器中。
4.写本题时需要考虑好用户的重复输入、用户的非法输入、是用户打座机还是座机打用户、用户是拨打电话方还是接听电话方、用户拨打电话时的位置(市内、省内、省外)、用户在何时打电话以及何时打完电话等等一系类情况,否则会导致输出结果错误。
5.在储存数据方面花费了大量的时间,不应该这样盲目做题,而应该先仔细审题,知道我们应该怎么做之后再动手,这样效率会高很多
改进建议
1.最好用动态数组来存储不固定的数据,如:ArrayList<String> list=new ArrayList<>();并用其list.add(input.nextLine())来添加数据;用list.get(++i)来获取数据。。
2.通过不同的正则表达式可以简化代码长度,使其更好的维护和使用;可以通过写一个函数来实现公共的功能,减小冗杂程度,使其得到优化。
3.当类和对象非常多时,对之间关系的理解很混乱,需要熟练对类图的理解与复现。
4.每完成一个类的设计,要先单独测试所设计的类存不存在bug,而不是全部写完后才开始debug。
总结
这也是本学期最后一篇博客,从第一篇博客的不知所云到现在经过一学期的pta训练,更清楚的认识到了面向对象的重要性。在基础的语法下熟练使用继承、多态、抽象类、包装类进行编写代码,面向对象的程序设计的重点在于如何创建对象,对象完成相应功能,类图的设计很重要。吸取了多边形系列的教训,认识到了代码的合理设计的重要性。第一次代码如果能合理设计,那么第二第三次代码只需要基于第一次题目的基础上增加相应功能,功能拓展我不需要改变太多代码就能实现。也通过系列题目认识到了自己在算法上的不足,以及知识面拓展能力较差,以后要多阅读官方文档和大佬的博客文章学习知识点。老师的课堂上也灌输了很多开发过程中有用的经验和知识点,干货满满。
标签:题目,String,double,Blog3,ArrayList,new,计费,return,public From: https://www.cnblogs.com/lthliberty/p/16946340.html