针对最近三次PTA有关移动业务资费问题总结
一.前言
- 知识点
1.数组的运用
2.正则表达式的运用
3.对象和类
4.多态与继承
- 题量
PTA练习3题,虽然题数较少,但是总体较复杂,但是三个题的主体是一样的
- 难度
整体较难,类与类之间的调用很复杂,但是只要一开始的整体框架写好了后面两次会轻松很多
二.设计与分析
- 题目集08 7-1 电信计费系列1-座机计费
实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
输入格式:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码除区号外由是7-8位数字组成。
本题只考虑计费类型0-座机计费,电信系列2、3题会逐步增加计费类型。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。



题目源码:
1 import java.text.DecimalFormat; 2 import java.text.ParseException; 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 import java.util.Map; 6 import java.util.Scanner; 7 import java.util.TreeMap; 8 import java.util.ArrayList; 9 10 public class Main { 11 12 public static void main(String[] args) throws ParseException { 13 // TODO Auto-generated method stub 14 Scanner in = new Scanner(System.in); 15 String s = in.nextLine(); 16 TreeMap<String,User> set = new TreeMap<>(); 17 String number; 18 User user; 19 while(!s.equals("end")) { 20 String str1 = "u-0791\\d{7,8}\\s[0-2]"; 21 String str2 = "t-0791([0-9]{7,8})\\s([0-9]{10,12})\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])"; 22 String str3 = "07(9[0-9]|01)"; 23 if(s.matches(str1)) { 24 String ss[] = s.split(" "); 25 user = new User(); 26 number = ss[0].substring(ss[0].indexOf("-")+1); 27 user.setNumber(number); 28 set.put(number,user); 29 } 30 else if(s.matches(str2)) { 31 String ss1 = s.substring(s.indexOf("-")+1,s.indexOf(" ")); 32 String s2 = s.substring(s.indexOf("-")+1,s.indexOf(" ")); 33 CallRecord record = new CallRecord(); 34 record.setCallingAdressAreaCode(ss1); 35 ss1 = s.substring(s.indexOf(" ")+1); 36 String s3 = ss1.substring(0,ss1.indexOf(" ")); 37 record.setAnswerAdressAreaCode(ss1.substring(0,ss1.indexOf(" "))); 38 ss1 = ss1.substring(ss1.indexOf(" ")+1); 39 String[] ss2 = ss1.split(" "); 40 SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss"); 41 Date startTime = m.parse(ss2[0]+" "+ss2[1]); 42 Date endTime = m.parse(ss2[2]+" "+ss2[3]); 43 record.setStartTime(startTime); 44 record.setEndTime(endTime); 45 for (Map.Entry<String, User> e : set.entrySet()) { 46 if(e.getKey().equals(s2)) { 47 if(s3.substring(0, 4).matches(str3)) { 48 if(s3.substring(0, 4).equals("0791")) { 49 e.getValue().getUserRecords().addAnswerInCityRecords(record); 50 } 51 else { 52 e.getValue().getUserRecords().addAnswerInProvinceRecords(record); 53 } 54 } 55 else { 56 e.getValue().getUserRecords().addAnswerInLandRecords(record); 57 } 58 } 59 } 60 } 61 s = in.nextLine(); 62 } 63 DecimalFormat d = new DecimalFormat("###0.0#"); 64 for (Map.Entry<String, User> e : set.entrySet()) { 65 System.out.println(e.getValue().getNumber()+" "+d.format(e.getValue().callCost())+" "+d.format(e.getValue().callBalance())); 66 } 67 } 68 69 } 70 71 abstract class CallChargeRule{ 72 public abstract double callCost (ArrayList<CallRecord> callRecords); 73 } 74 75 class CallRecord { 76 private String callingAdressAreaCode; 77 private String AnswerAdressAreaCode; 78 private Date startTime; 79 private Date endTime; 80 81 public String getCallingAdressAreaCode() { 82 return callingAdressAreaCode; 83 } 84 85 public void setCallingAdressAreaCode(String callingAdressAreaCode) { 86 this.callingAdressAreaCode = callingAdressAreaCode; 87 } 88 89 public String getAnswerAdressAreaCode() { 90 return AnswerAdressAreaCode; 91 } 92 93 public void setAnswerAdressAreaCode(String answerAdressAreaCode) { 94 AnswerAdressAreaCode = answerAdressAreaCode; 95 } 96 97 public Date getStartTime() { 98 return startTime; 99 } 100 101 public void setStartTime(Date startTime) { 102 this.startTime = startTime; 103 } 104 105 public Date getEndTime() { 106 return endTime; 107 } 108 109 public void setEndTime(Date endTime) { 110 this.endTime = endTime; 111 } 112 } 113 114 abstract class ChargeMode { 115 private ArrayList<CallChargeRule> chargeRules = new ArrayList<>(); 116 117 public ArrayList<CallChargeRule> getChargeRules() { 118 return chargeRules; 119 } 120 121 public void setChargeRules(ArrayList<CallChargeRule> chargeRules) { 122 this.chargeRules = chargeRules; 123 } 124 125 public abstract double callCost(UserRecords userRecords); 126 127 public abstract double getMonthlyRent (); 128 } 129 130 class CommunicateRecord { 131 protected String callingNumber; 132 protected String answerNumber; 133 134 public String getCallingNumber() { 135 return callingNumber; 136 } 137 138 public void setCallingNumber(String callingNumber) { 139 this.callingNumber = callingNumber; 140 } 141 142 public String getAnswerNumber() { 143 return answerNumber; 144 } 145 146 public void setAnswerNumber(String answerNumber) { 147 this.answerNumber = answerNumber; 148 } 149 } 150 151 class LandlinePhoneCharging extends ChargeMode{ 152 private double monthlyRent = 20; 153 @Override 154 public double callCost(UserRecords userRecords) { 155 // TODO Auto-generated method stub 156 CallChargeRule a = new LandPhoneInCityRule(); 157 CallChargeRule b = new LandPhoneInProvinceRule(); 158 CallChargeRule c = new LandPhoneInlandRule(); 159 double callcost = a.callCost(userRecords.getAnswerInCityRecords()) + b.callCost(userRecords.getAnswerInProvinceRecords()) + c.callCost(userRecords.getAnswerInLandRecords()); 160 return callcost; 161 } 162 163 @Override 164 public double getMonthlyRent() { 165 // TODO Auto-generated method stub 166 return monthlyRent; 167 } 168 169 } 170 171 class LandPhoneInCityRule extends CallChargeRule{ 172 173 @Override 174 public double callCost(ArrayList<CallRecord> callRecords) { 175 // TODO Auto-generated method stub 176 double cost = 0; 177 double m; 178 for(CallRecord a : callRecords) { 179 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 180 int n = (int)m; 181 if(m-n>0.000001) { 182 n = n+1; 183 } 184 cost += 0.1 * n; 185 } 186 return cost; 187 } 188 189 } 190 191 class LandPhoneInlandRule extends CallChargeRule{ 192 193 @Override 194 public double callCost(ArrayList<CallRecord> callRecords) { 195 // TODO Auto-generated method stub 196 double cost = 0; 197 double m; 198 for(CallRecord a : callRecords) { 199 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 200 int n = (int)m; 201 if(m-n>0.000001) { 202 n = n+1; 203 } 204 cost += 0.6 * n; 205 } 206 return cost; 207 } 208 209 } 210 211 class LandPhoneInProvinceRule extends CallChargeRule{ 212 213 @Override 214 public double callCost(ArrayList<CallRecord> callRecords) { 215 // TODO Auto-generated method stub 216 double cost = 0; 217 double m; 218 for(CallRecord a : callRecords) { 219 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 220 int n = (int)m; 221 if(m-n>0.000001) { 222 n = n+1; 223 } 224 cost += 0.3 * n; 225 } 226 return cost; 227 } 228 229 } 230 231 class User { 232 private UserRecords userRecords = new UserRecords(); 233 private double balance = 100; 234 private ChargeMode chargemode = new LandlinePhoneCharging(); 235 private String number; 236 237 public double callBalance() { 238 balance = balance - (this.callCost() + chargemode.getMonthlyRent()); 239 return balance; 240 } 241 242 public double callCost() { 243 return chargemode.callCost(userRecords); 244 } 245 246 public UserRecords getUserRecords() { 247 return userRecords; 248 } 249 250 public void setUserRecords(UserRecords userRecords) { 251 this.userRecords = userRecords; 252 } 253 254 public double getBalance() { 255 return balance; 256 } 257 258 public ChargeMode getChargemode() { 259 return chargemode; 260 } 261 262 public void setChargemode(ChargeMode chargemode) { 263 this.chargemode = chargemode; 264 } 265 266 public String getNumber() { 267 return number; 268 } 269 270 public void setNumber(String number) { 271 this.number = number; 272 } 273 274 } 275 276 class UserRecords { 277 278 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 279 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 280 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); 281 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); 282 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); 283 private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); 284 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); 285 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); 286 287 public void addCallingInCityRecords (CallRecord callRecord) { 288 callingInCityRecords.add(callRecord); 289 } 290 291 public void addCallingInProvinceRecords (CallRecord callRecord) { 292 callingInProvinceRecords.add(callRecord); 293 } 294 295 public void addCallingInLandRecords (CallRecord callRecord) { 296 callingInLandRecords.add(callRecord); 297 } 298 299 public void addAnswerInCityRecords (CallRecord answerRecord) { 300 answerInCityRecords.add(answerRecord); 301 } 302 public void addAnswerInProvinceRecords (CallRecord answerRecord) { 303 answerInProvinceRecords.add(answerRecord); 304 } 305 306 public void addAnswerInLandRecords (CallRecord answerRecord) { 307 answerInLandRecords.add(answerRecord); 308 } 309 310 public void addSendMessageRecords (MessageRecord sendMessageRecord) { 311 sendMessageRecords.add(sendMessageRecord); 312 } 313 314 public void addReceiveMessageRecords (MessageRecord receiveMessageRecord) { 315 receiveMessageRecords.add(receiveMessageRecord); 316 } 317 318 public ArrayList<CallRecord> getCallingInCityRecords() { 319 return callingInCityRecords; 320 } 321 322 public ArrayList<CallRecord> getCallingInProvinceRecords() { 323 return callingInProvinceRecords; 324 } 325 326 public ArrayList<CallRecord> getCallingInLandRecords() { 327 return callingInLandRecords; 328 } 329 330 public ArrayList<CallRecord> getAnswerInCityRecords() { 331 return answerInCityRecords; 332 } 333 334 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 335 return answerInProvinceRecords; 336 } 337 338 public ArrayList<CallRecord> getAnswerInLandRecords() { 339 return answerInLandRecords; 340 } 341 342 343 public ArrayList<MessageRecord> getReceiveMessageRecords() { 344 return receiveMessageRecords; 345 } 346 347 348 public ArrayList<MessageRecord> getSendMessageRecords() { 349 return sendMessageRecords; 350 } 351 352 } 353 354 class MessageRecord extends CommunicateRecord{ 355 private String message; 356 357 public String getMessage() { 358 return message; 359 } 360 361 public void setMessage(String message) { 362 this.message = message; 363 } 364 }
分析:首先是针对基本框架的构建,题目给了基本的类图,按照类图进行代码的书写就可以了,主要问题是需要理清楚每个类图之间的关系,包括多态的运用,在判断不同地区的电话拨打情况中话费的计算有所体现,其次就是输入格式的问题,刚开始没有注意日期时间的格式,导致在格式的测试点卡了很久,还是要多注意细节。
心得:这种题很考验自己对于每个类图的关系的梳理,如果题目没有给基本的类图的话,难度就大大的增加了,需要自己去思考对于不同的功能需要什么样的类去实现,对于不同的类之间继承多态也很难弄清,根据类图写的话就轻松很多了,输入格式运用正则去判断的话会舒心很多。
- 题目集09 7-1 电信计费系列2-手机+座机计费
实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
1、针对市内座机用户采用的计费方式(与电信计费系列1内容相同):
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
假设本市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
2、针对手机用户采用实时计费方式:
月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟;
注:被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
输入:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,含手机和座机用户
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题在电信计费系列1基础上增加类型1-手机实时计费。
手机设置0或者座机设置成1,此种错误可不做判断。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
输入格式增加手机接打电话以及收发短信的格式,手机接打电话的信息除了号码之外需要额外记录拨打/接听的地点的区号,比如:
座机打手机:
t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:
t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
题目源码:
1 import java.text.DecimalFormat; 2 import java.text.ParseException; 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 import java.util.Map; 6 import java.util.Scanner; 7 import java.util.TreeMap; 8 import java.util.ArrayList; 9 10 public class Main { 11 12 public static void main(String[] args) throws ParseException { 13 // TODO Auto-generated method stub 14 Scanner in = new Scanner(System.in); 15 String s = in.nextLine(); 16 String str1 = "u-0791\\d{7,8}\\s0"; //注册座机用户 17 String str2 = "t-0791([0-9]{7,8})\\s0([0-9]{9,11})\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])"; 18 //座机打座机的记录 19 String str3 = "07(9[0-9]|01)";//判断地区 20 String str4 = "u-1\\d{10}\\s1";//注册手机用户。手机和座机统一在南昌开户 21 String str5 = "t-0\\d{9,11}\\s1\\d{10}\\s0\\d{2,3}\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])"; 22 //座机打手机 23 String str6 = "t-1\\d{10}\\s0\\d{2,3}\\s1\\d{10}\\s0\\d{2,3}\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])"; 24 //手机打手机 25 String str7 = "t-1\\d{10}\\s0\\d{2,3}\\s0([0-9]{9,11})\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])\\s\\d{4}\\.([1-9]|1[012])\\.([1-9]|([1-2][0-9])|[3][0,1])\\s((0[0-9])|(1[0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])"; 26 //手机打座机 27 TreeMap<String,User> set = new TreeMap<>(); 28 String number; 29 User user; 30 int k = 0; 31 while(!s.equals("end")) { 32 if(k==0) { 33 while(!s.equals("end")&&s.charAt(0)=='u') { 34 if(s.matches(str1)) { 35 String ss[] = s.split(" "); 36 user = new User(); 37 number = ss[0].substring(ss[0].indexOf("-")+1); 38 user.setNumber(number); 39 set.put(number,user); 40 } 41 else if(s.matches(str4)) { 42 String ss[] = s.split(" "); 43 user = new User(); 44 number = ss[0].substring(ss[0].indexOf("-")+1); 45 user.setNumber(number); 46 double a = 15; 47 user.getChargemode().setMonthlyRent(a); 48 set.put(number,user); 49 } 50 s = in.nextLine(); 51 if(s.charAt(0)=='t') { 52 k = 1; 53 } 54 } 55 } 56 57 while(!s.equals("end")&&s.charAt(0)=='t') { 58 if(s.matches(str2)) {//座机打座机 59 //t-079186300001 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:25 60 CallRecord record = new CallRecord(); 61 String ss[] = s.split(" "); 62 String s1 = ss[0].substring(ss[0].indexOf("-")+1); 63 SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss"); 64 Date startTime = m.parse(ss[2]+" "+ss[3]); 65 Date endTime = m.parse(ss[4]+" "+ss[5]); 66 record.setStartTime(startTime); 67 record.setEndTime(endTime); 68 record.setCallingAdressAreaCode(s1); 69 record.setAnswerAdressAreaCode(ss[1]); 70 String s2 = ss[1].substring(0,4); 71 for (Map.Entry<String, User> e : set.entrySet()) { 72 if(e.getKey().equals(s1)) { 73 if(s2.matches(str3)) { 74 if(s2.equals("0791")) { 75 e.getValue().getUserRecords().addCallingInCityRecords(record); 76 } 77 else { 78 e.getValue().getUserRecords().addCallingInProvinceRecords(record);; 79 } 80 } 81 else { 82 e.getValue().getUserRecords().addCallingInLandRecords(record); 83 } 84 } 85 } 86 } 87 else if(s.matches(str5)) {//座机打手机 88 //t-079186300001 13986300001 0371 2022.1.3 10:00:25 2022.1.3 10:05:05 89 CallRecord record = new CallRecord(); 90 String ss[] = s.split(" "); 91 String s1 = ss[0].substring(ss[0].indexOf("-")+1); 92 SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss"); 93 Date startTime = m.parse(ss[3]+" "+ss[4]); 94 Date endTime = m.parse(ss[5]+" "+ss[6]); 95 record.setStartTime(startTime); 96 record.setEndTime(endTime); 97 record.setCallingAdressAreaCode(s1); 98 record.setAnswerAdressAreaCode(ss[2]); 99 for (Map.Entry<String, User> e : set.entrySet()) { 100 if(e.getKey().equals(s1)) { 101 if(ss[2].matches(str3)) { 102 if(ss[2].equals("0791")) { 103 e.getValue().getUserRecords().addCallingInCityRecords(record); 104 } 105 else { 106 e.getValue().getUserRecords().addCallingInProvinceRecords(record);; 107 } 108 } 109 else { 110 e.getValue().getUserRecords().addCallingInLandRecords(record); 111 } 112 } 113 } 114 for (Map.Entry<String, User> e : set.entrySet()) { 115 if(e.getKey().equals(ss[1])) { 116 if(ss[2].matches(str3)) { 117 if(ss[2].equals("0791")) { 118 if(ss[3].matches(s1)) { 119 e.getValue().getUserRecords().addAnswerInCityRecords(record); 120 } 121 else { 122 e.getValue().getUserRecords().addAnswerInProvinceRecords(record); 123 } 124 } 125 else { 126 e.getValue().getUserRecords().addAnswerInLandRecords(record); 127 } 128 } 129 else { 130 e.getValue().getUserRecords().addAnswerInLandRecords(record); 131 } 132 } 133 }//录入拨打号码的信息 134 } 135 else if(s.matches(str6)) {//手机打手机 136 //t-18907910010 0791 13986300001 0371 2022.1.3 10:00:25 2022.1.3 10:05:11 137 CallRecord record = new CallRecord(); 138 String ss[] = s.split(" "); 139 String s1 = ss[0].substring(ss[0].indexOf("-")+1); 140 SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss"); 141 Date startTime = m.parse(ss[4]+" "+ss[5]); 142 Date endTime = m.parse(ss[6]+" "+ss[7]); 143 record.setStartTime(startTime); 144 record.setEndTime(endTime); 145 record.setCallingAdressAreaCode(s1); 146 record.setAnswerAdressAreaCode(ss[2]); 147 for (Map.Entry<String, User> e : set.entrySet()) { 148 if(e.getKey().equals(s1)) { 149 if(ss[1].matches(str3)) { 150 if(ss[1].equals("0791")) { 151 if(ss[3].matches(s1)) { 152 if(ss[3].equals("0791")) { 153 e.getValue().getUserRecords().addPhonecallingInCityInCityRecords(record);; 154 } 155 else { 156 e.getValue().getUserRecords().addPhonecallingInCityInProvinceRecords(record); 157 } 158 } 159 else { 160 e.getValue().getUserRecords().addPhonecallingInCityInLandRecords(record);; 161 } 162 } 163 else { 164 e.getValue().getUserRecords().addPhonecallingInProvinceRecords(record); 165 } 166 } 167 else { 168 e.getValue().getUserRecords().addPhonecallingInLandOtherRecords(record); 169 } 170 } 171 }//录入拨打号码的信息 172 for (Map.Entry<String, User> e : set.entrySet()) { 173 if(e.getKey().equals(ss[2])) { 174 if(ss[3].matches(s1)) { 175 if(ss[3].equals("0791")) { 176 e.getValue().getUserRecords().addAnswerInCityRecords(record); 177 } 178 else { 179 e.getValue().getUserRecords().addAnswerInProvinceRecords(record); 180 } 181 182 } 183 else { 184 e.getValue().getUserRecords().addAnswerInLandRecords(record); 185 } 186 } 187 } 188 } 189 else if(s.matches(str7)) {//手机打座机 190 //t-13986300001 0371 079186300001 2022.1.3 23:50:25 2022.1.4 00:05:11 191 CallRecord record = new CallRecord(); 192 String ss[] = s.split(" "); 193 String s1 = ss[0].substring(ss[0].indexOf("-")+1); 194 SimpleDateFormat m = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss"); 195 Date startTime = m.parse(ss[3]+" "+ss[4]); 196 Date endTime = m.parse(ss[5]+" "+ss[6]); 197 record.setStartTime(startTime); 198 record.setEndTime(endTime); 199 record.setCallingAdressAreaCode(s1); 200 record.setAnswerAdressAreaCode(ss[2]); 201 String s2 = ss[2].substring(0,4); 202 for (Map.Entry<String, User> e : set.entrySet()) { 203 if(e.getKey().equals(s1)) { 204 if(ss[1].matches(str3)) { 205 if(ss[1].equals("0791")) { 206 if(s2.matches(str3)) { 207 if(s2.equals("0791")) { 208 e.getValue().getUserRecords().addPhonecallingInCityInCityRecords(record);; 209 } 210 else { 211 e.getValue().getUserRecords().addPhonecallingInCityInProvinceRecords(record); 212 } 213 } 214 else { 215 e.getValue().getUserRecords().addPhonecallingInCityInLandRecords(record);; 216 } 217 } 218 else { 219 e.getValue().getUserRecords().addPhonecallingInProvinceRecords(record); 220 } 221 } 222 else { 223 e.getValue().getUserRecords().addPhonecallingInLandOtherRecords(record); 224 } 225 } 226 }//录入拨打号码的信息 227 } 228 s = in.nextLine(); 229 } 230 231 if(!s.equals("end")) { 232 s = in.nextLine(); 233 } 234 } 235 DecimalFormat d = new DecimalFormat("###0.0#"); 236 for (Map.Entry<String, User> e : set.entrySet()) { 237 System.out.println(e.getValue().getNumber()+" "+d.format(e.getValue().callCost())+" "+d.format(e.getValue().callBalance())); 238 } 239 } 240 241 } 242 abstract class AnswerChargeRule { 243 public abstract double AnswerCost (ArrayList<CallRecord> callRecords); 244 245 } 246 class AnswerInLandRule extends AnswerChargeRule{ 247 248 @Override 249 public double AnswerCost(ArrayList<CallRecord> answerRecords) { 250 // TODO Auto-generated method stub 251 double cost = 0; 252 double m; 253 for(CallRecord a : answerRecords) { 254 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 255 int n = (int)m; 256 if(m-n>0.000001) { 257 n = n+1; 258 } 259 cost += 0.3 * n; 260 } 261 return cost; 262 } 263 264 } 265 abstract class CallChargeRule{ 266 267 private double price; 268 269 public abstract double callCost (ArrayList<CallRecord> callRecords); 270 271 public double getPrice() { 272 return price; 273 } 274 275 public void setPrice(double price) { 276 this.price = price; 277 } 278 } 279 class CallRecord { 280 private String callingAdressAreaCode; 281 private String AnswerAdressAreaCode; 282 private Date startTime; 283 private Date endTime; 284 285 public String getCallingAdressAreaCode() { 286 return callingAdressAreaCode; 287 } 288 289 public void setCallingAdressAreaCode(String callingAdressAreaCode) { 290 this.callingAdressAreaCode = callingAdressAreaCode; 291 } 292 293 public String getAnswerAdressAreaCode() { 294 return AnswerAdressAreaCode; 295 } 296 297 public void setAnswerAdressAreaCode(String answerAdressAreaCode) { 298 AnswerAdressAreaCode = answerAdressAreaCode; 299 } 300 301 public Date getStartTime() { 302 return startTime; 303 } 304 305 public void setStartTime(Date startTime) { 306 this.startTime = startTime; 307 } 308 309 public Date getEndTime() { 310 return endTime; 311 } 312 313 public void setEndTime(Date endTime) { 314 this.endTime = endTime; 315 } 316 } 317 abstract class ChargeMode { 318 private ArrayList<CallChargeRule> chargeRules = new ArrayList<>(); 319 private ArrayList<AnswerChargeRule> answerule = new ArrayList<>(); 320 321 public ArrayList<CallChargeRule> getChargeRules() { 322 return chargeRules; 323 } 324 325 public void setChargeRules(ArrayList<CallChargeRule> chargeRules) { 326 this.chargeRules = chargeRules; 327 } 328 329 public abstract double callCost(UserRecords userRecords); 330 331 public abstract double getMonthlyRent (); 332 333 public abstract void setMonthlyRent(double a); 334 335 public ArrayList<AnswerChargeRule> getAnswerule() { 336 return answerule; 337 } 338 339 public void setAnswerule(ArrayList<AnswerChargeRule> answerule) { 340 this.answerule = answerule; 341 } 342 } 343 class CommunicateRecord { 344 protected String callingNumber; 345 protected String answerNumber; 346 347 public String getCallingNumber() { 348 return callingNumber; 349 } 350 351 public void setCallingNumber(String callingNumber) { 352 this.callingNumber = callingNumber; 353 } 354 355 public String getAnswerNumber() { 356 return answerNumber; 357 } 358 359 public void setAnswerNumber(String answerNumber) { 360 this.answerNumber = answerNumber; 361 } 362 } 363 class LandlinePhoneCharging extends ChargeMode{ 364 private double monthlyRent = 20; 365 @Override 366 public double callCost(UserRecords userRecords) { 367 // TODO Auto-generated method stub 368 CallChargeRule a = new LandPhoneInCityRule(); 369 CallChargeRule b = new LandPhoneInProvinceRule(); 370 CallChargeRule c = new LandPhoneInlandRule(); 371 372 double callcost = a.callCost(userRecords.getCallingInCityRecords()) + b.callCost(userRecords.getCallingInProvinceRecords()) + c.callCost(userRecords.getCallingInLandRecords()); 373 return callcost; 374 } 375 376 @Override 377 public double getMonthlyRent() { 378 // TODO Auto-generated method stub 379 return monthlyRent; 380 } 381 382 public void setMonthlyRent(double monthlyRent) { 383 this.monthlyRent = monthlyRent; 384 } 385 } 386 class LandPhoneInCityRule extends CallChargeRule{ 387 388 @Override 389 public double callCost(ArrayList<CallRecord> callRecords) { 390 // TODO Auto-generated method stub 391 double cost = 0; 392 double m; 393 for(CallRecord a : callRecords) { 394 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 395 int n = (int)m; 396 if(m-n>0.000001) { 397 n = n+1; 398 } 399 cost += 0.1 * n; 400 } 401 return cost; 402 } 403 404 405 } 406 class LandPhoneInlandRule extends CallChargeRule{ 407 408 @Override 409 public double callCost(ArrayList<CallRecord> callRecords) { 410 // TODO Auto-generated method stub 411 double cost = 0; 412 double m; 413 for(CallRecord a : callRecords) { 414 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 415 int n = (int)m; 416 if(m-n>0.000001) { 417 n = n+1; 418 } 419 cost += 0.6 * n; 420 } 421 return cost; 422 } 423 424 } 425 class LandPhoneInProvinceRule extends CallChargeRule{ 426 427 @Override 428 public double callCost(ArrayList<CallRecord> callRecords) { 429 // TODO Auto-generated method stub 430 double cost = 0; 431 double m; 432 for(CallRecord a : callRecords) { 433 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 434 int n = (int)m; 435 if(m-n>0.000001) { 436 n = n+1; 437 } 438 cost += 0.3 * n; 439 } 440 return cost; 441 } 442 443 } 444 class MessageRecord extends CommunicateRecord{ 445 private String message; 446 447 public String getMessage() { 448 return message; 449 } 450 451 public void setMessage(String message) { 452 this.message = message; 453 } 454 } 455 class PhoneCharging extends ChargeMode{ 456 private double monthlyRent = 15; 457 @Override 458 public double callCost(UserRecords userRecords) { 459 // TODO Auto-generated method stub 460 double cost = 0; 461 CallChargeRule a = new PhoneInCittCallInLand(); 462 CallChargeRule b = new PhoneInCityCallInCity(); 463 CallChargeRule c = new PhoneInCityCallInProvince(); 464 CallChargeRule d = new PhoneInLandCallOther(); 465 CallChargeRule e = new PhoneInProvinceCallOther(); 466 AnswerChargeRule f = new AnswerInLandRule(); 467 cost += f.AnswerCost(userRecords.getAnswerInLandRecords()) + a.callCost(userRecords.getPhonecallingInCityInLandRecords()); 468 cost += b.callCost(userRecords.getPhonecallingInCityInCityRecords()) + c.callCost(userRecords.getPhonecallingInCityInProvinceRecords()); 469 cost += d.callCost(userRecords.getPhonecallingInLandOtherRecords()) + e.callCost(userRecords.getPhonecallingInProvinceRecords()); 470 return cost; 471 } 472 473 @Override 474 public double getMonthlyRent() { 475 // TODO Auto-generated method stub 476 return monthlyRent; 477 } 478 479 @Override 480 public void setMonthlyRent(double monthlyRent) { 481 // TODO Auto-generated method stub 482 this.monthlyRent = monthlyRent; 483 } 484 485 } 486 class PhoneInCittCallInLand extends CallChargeRule{ 487 488 @Override 489 public double callCost(ArrayList<CallRecord> callRecords) { 490 // TODO Auto-generated method stub 491 double cost = 0; 492 double m; 493 for(CallRecord a : callRecords) { 494 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 495 int n = (int)m; 496 if(m-n>0.000001) { 497 n = n+1; 498 } 499 cost += 0.3 * n; 500 } 501 return cost; 502 } 503 } 504 class PhoneInCityCallInCity extends CallChargeRule{ 505 506 @Override 507 public double callCost(ArrayList<CallRecord> callRecords) { 508 // TODO Auto-generated method stub 509 double cost = 0; 510 double m; 511 for(CallRecord a : callRecords) { 512 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 513 int n = (int)m; 514 if(m-n>0.000001) { 515 n = n+1; 516 } 517 cost += 0.1 * n; 518 } 519 return cost; 520 } 521 } 522 class PhoneInCityCallInProvince extends CallChargeRule{ 523 524 @Override 525 public double callCost(ArrayList<CallRecord> callRecords) { 526 // TODO Auto-generated method stub 527 double cost = 0; 528 double m; 529 for(CallRecord a : callRecords) { 530 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 531 int n = (int)m; 532 if(m-n>0.000001) { 533 n = n+1; 534 } 535 cost += 0.2 * n; 536 } 537 return cost; 538 } 539 } 540 class PhoneInLandCallOther extends CallChargeRule{ 541 542 @Override 543 public double callCost(ArrayList<CallRecord> callRecords) { 544 // TODO Auto-generated method stub 545 double cost = 0; 546 double m; 547 for(CallRecord a : callRecords) { 548 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 549 int n = (int)m; 550 if(m-n>0.000001) { 551 n = n+1; 552 } 553 cost += 0.6 * n; 554 } 555 return cost; 556 } 557 } 558 class PhoneInProvinceCallOther extends CallChargeRule{ 559 560 @Override 561 public double callCost(ArrayList<CallRecord> callRecords) { 562 // TODO Auto-generated method stub 563 double cost = 0; 564 double m; 565 for(CallRecord a : callRecords) { 566 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 567 int n = (int)m; 568 if(m-n>0.000001) { 569 n = n+1; 570 } 571 cost += 0.3 * n; 572 } 573 return cost; 574 } 575 } 576 class User { 577 private UserRecords userRecords = new UserRecords(); 578 private double balance = 100; 579 private ChargeMode chargemode1 = new LandlinePhoneCharging(); 580 private ChargeMode chargemode2 = new PhoneCharging(); 581 private String number; 582 583 public double callBalance() { 584 if(number.charAt(0)=='1') { 585 balance = balance - (this.callCost() + chargemode2.getMonthlyRent()); 586 } 587 else { 588 balance = balance - (this.callCost() + chargemode1.getMonthlyRent()); 589 } 590 return balance; 591 } 592 593 public double callCost() { 594 if(number.charAt(0)=='1') { 595 return chargemode2.callCost(userRecords); 596 597 } 598 else { 599 return chargemode1.callCost(userRecords); 600 601 } 602 } 603 604 public UserRecords getUserRecords() { 605 return userRecords; 606 } 607 608 public void setUserRecords(UserRecords userRecords) { 609 this.userRecords = userRecords; 610 } 611 612 public double getBalance() { 613 return balance; 614 } 615 616 public ChargeMode getChargemode() { 617 if(number.charAt(0)=='1') { 618 return chargemode2; 619 } 620 else { 621 return chargemode1; 622 } 623 624 } 625 626 public void setChargemode(ChargeMode chargemode) { 627 if(number.charAt(0)=='1') { 628 this.chargemode2 = chargemode; 629 } 630 else { 631 this.chargemode1 = chargemode; 632 } 633 } 634 635 public String getNumber() { 636 return number; 637 } 638 639 public void setNumber(String number) { 640 this.number = number; 641 } 642 643 } 644 class UserRecords { 645 646 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 647 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 648 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); 649 650 private ArrayList<CallRecord> PhonecallingInLandOtherRecords = new ArrayList<CallRecord>(); 651 private ArrayList<CallRecord> PhonecallingInCityInLandRecords = new ArrayList<CallRecord>(); 652 private ArrayList<CallRecord> PhonecallingInProvinceRecords = new ArrayList<CallRecord>(); 653 private ArrayList<CallRecord> PhonecallingInCityInProvinceRecords = new ArrayList<CallRecord>(); 654 private ArrayList<CallRecord> PhonecallingInCityInCityRecords = new ArrayList<CallRecord>(); 655 656 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); 657 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); 658 private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); 659 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); 660 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); 661 662 public void addCallingInCityRecords (CallRecord callRecord) { 663 callingInCityRecords.add(callRecord); 664 } 665 666 public void addCallingInProvinceRecords (CallRecord callRecord) { 667 callingInProvinceRecords.add(callRecord); 668 } 669 670 public void addCallingInLandRecords (CallRecord callRecord) { 671 callingInLandRecords.add(callRecord); 672 } 673 674 public void addAnswerInCityRecords (CallRecord answerRecord) { 675 answerInCityRecords.add(answerRecord); 676 } 677 public void addAnswerInProvinceRecords (CallRecord answerRecord) { 678 answerInProvinceRecords.add(answerRecord); 679 } 680 681 public void addAnswerInLandRecords (CallRecord answerRecord) { 682 answerInLandRecords.add(answerRecord); 683 } 684 685 public void addSendMessageRecords (MessageRecord sendMessageRecord) { 686 sendMessageRecords.add(sendMessageRecord); 687 } 688 689 public void addReceiveMessageRecords (MessageRecord receiveMessageRecord) { 690 receiveMessageRecords.add(receiveMessageRecord); 691 } 692 693 public ArrayList<CallRecord> getCallingInCityRecords() { 694 return callingInCityRecords; 695 } 696 697 public ArrayList<CallRecord> getCallingInProvinceRecords() { 698 return callingInProvinceRecords; 699 } 700 701 public ArrayList<CallRecord> getCallingInLandRecords() { 702 return callingInLandRecords; 703 } 704 705 public ArrayList<CallRecord> getAnswerInCityRecords() { 706 return answerInCityRecords; 707 } 708 709 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 710 return answerInProvinceRecords; 711 } 712 713 public ArrayList<CallRecord> getAnswerInLandRecords() { 714 return answerInLandRecords; 715 } 716 717 718 public ArrayList<MessageRecord> getReceiveMessageRecords() { 719 return receiveMessageRecords; 720 } 721 722 723 public ArrayList<MessageRecord> getSendMessageRecords() { 724 return sendMessageRecords; 725 } 726 727 public ArrayList<CallRecord> getPhonecallingInLandOtherRecords() { 728 return PhonecallingInLandOtherRecords; 729 } 730 731 public void addPhonecallingInLandOtherRecords(CallRecord phonecallingInLandOtherRecords) { 732 PhonecallingInLandOtherRecords.add(phonecallingInLandOtherRecords); 733 } 734 735 public ArrayList<CallRecord> getPhonecallingInCityInLandRecords() { 736 return PhonecallingInCityInLandRecords; 737 } 738 739 public void addPhonecallingInCityInLandRecords(CallRecord phonecallingInCityInLandRecords) { 740 PhonecallingInCityInLandRecords.add(phonecallingInCityInLandRecords); 741 } 742 743 public ArrayList<CallRecord> getPhonecallingInCityInProvinceRecords() { 744 return PhonecallingInCityInProvinceRecords; 745 } 746 747 public void addPhonecallingInCityInProvinceRecords(CallRecord phonecallingInCityInProvinceRecords) { 748 PhonecallingInCityInProvinceRecords.add(phonecallingInCityInProvinceRecords); 749 } 750 751 public ArrayList<CallRecord> getPhonecallingInCityInCityRecords() { 752 return PhonecallingInCityInCityRecords; 753 } 754 755 public void addPhonecallingInCityInCityRecords(CallRecord phonecallingInCityInCityRecords) { 756 PhonecallingInCityInCityRecords.add(phonecallingInCityInCityRecords); 757 } 758 759 public ArrayList<CallRecord> getPhonecallingInProvinceRecords() { 760 return PhonecallingInProvinceRecords; 761 } 762 763 public void addPhonecallingInProvinceRecords(CallRecord phonecallingInProvinceRecords) { 764 PhonecallingInProvinceRecords.add(phonecallingInProvinceRecords); 765 } 766 767 }
分析:在第一题的基础上增加了新的种类的用户,使得计费的过程更加复杂,主要是完善所给类图中实现的功能,在Main判断好拨打的类型,地区等,增加到相应的ArrayList对应的通话记录再进行计算话费的计算,总体上有第一题的基础上难度主要在判断通话记录方面,运用正则来判断地区号是个很好的选择
心得:需要一个个的分析拨打地区和接收地区,在分类方面做了很多的功夫,也一直调式看自己分类部分的代码是否有错误,真的很需要头脑清楚的时候去写,不然很容易混乱
-
题目集10 7-1 电信计费系列3-短信计费
实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
1、接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。
2、如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。
输入:
输入信息包括两种类型
1、逐行输入南昌市手机用户开户的信息,每行一个用户。
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐 3-手机短信计费)
例如:u-13305862264 3
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题只针对类型3-手机短信计费。
2、逐行输入本月某些用户的短信信息,短信的格式:
m-主叫号码,接收号码,短信内容 (短信内容只能由数字、字母、空格、英文逗号、英文句号组成)
m-18907910010 13305862264 welcome to jiangxi.
m-13305862264 18907910010 thank you.
注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出:
根据输入的详细短信信息,计算所有已开户的用户的当月短信费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码、自己给自己打电话等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。
本题只考虑短信计费,不考虑通信费用以及月租费。
源码:
1 import java.text.DecimalFormat; 2 import java.text.ParseException; 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 import java.util.Map; 6 import java.util.Scanner; 7 import java.util.TreeMap; 8 import java.util.ArrayList; 9 import java.util.Date; 10 public class Main { 11 12 public static void main(String[] args) throws ParseException { 13 // TODO Auto-generated method stub 14 Scanner in = new Scanner(System.in); 15 String s = in.nextLine(); 16 String numberjudge = "[u][-]1[3-9]\\d{9}[ ][3]"; 17 String messagejudge = "m-1[3-9]\\d{9} 1[3-9]\\d{9} [a-z|0-9| |,|.]++"; 18 TreeMap<String,User> set = new TreeMap<>(); 19 String number; 20 User user; 21 int k = 0; 22 while(!s.equals("end")) { 23 if(k==0) { 24 while(!s.equals("end")&&s.charAt(0)=='u') { 25 if(s.matches(numberjudge)) { 26 String ss[] = s.split(" "); 27 user = new User(); 28 number = ss[0].substring(ss[0].indexOf("-")+1); 29 user.setNumber(number); 30 set.put(number,user); 31 } 32 s = in.nextLine(); 33 if(s.charAt(0)=='m') { 34 k = 1; 35 } 36 } 37 } 38 39 while(!s.equals("end")&&s.charAt(0)=='m') { 40 if(s.matches(messagejudge)) { 41 //m-18907910010 13305862264 bb,bbbb 42 MessageRecord record = new MessageRecord(); 43 String s1 = s.substring(0,s.indexOf(" ")); 44 String ss1 = s1.substring(s1.indexOf("-")+1);//发短信的电话号码 45 String s2 = s.substring(s.indexOf(" ")+1); 46 String ss2 = s2.substring(0,s2.indexOf(" ")-1);//收短信的号码 47 String message = s2.substring(s2.indexOf(" ")+1); 48 for (Map.Entry<String, User> e : set.entrySet()) { 49 if(e.getKey().equals(ss1)) { 50 record.setCallingNumber(ss1); 51 record.setAnswerNumber(ss2); 52 record.setMessage(message); 53 e.getValue().getUserRecords().addSendMessageRecords(record); 54 } 55 } 56 } 57 s = in.nextLine(); 58 } 59 60 if(!s.equals("end")) { 61 s = in.nextLine(); 62 } 63 } 64 DecimalFormat d = new DecimalFormat("###0.0#"); 65 for (Map.Entry<String, User> e : set.entrySet()) { 66 System.out.println(e.getValue().getNumber()+" "+d.format(e.getValue().callCost())+" "+d.format(e.getValue().callBalance())); 67 } 68 } 69 70 } 71 72 abstract class AnswerChargeRule { 73 public abstract double AnswerCost (ArrayList<CallRecord> callRecords); 74 75 } 76 class AnswerInLandRule extends AnswerChargeRule{ 77 78 @Override 79 public double AnswerCost(ArrayList<CallRecord> answerRecords) { 80 // TODO Auto-generated method stub 81 double cost = 0; 82 double m; 83 for(CallRecord a : answerRecords) { 84 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 85 int n = (int)m; 86 if(m-n>0.000001) { 87 n = n+1; 88 } 89 cost += 0.3 * n; 90 } 91 return cost; 92 } 93 94 } 95 abstract class CallChargeRule{ 96 97 private double price; 98 99 public abstract double callCost (ArrayList<CallRecord> callRecords); 100 101 public double getPrice() { 102 return price; 103 } 104 105 public void setPrice(double price) { 106 this.price = price; 107 } 108 } 109 110 class CallRecord { 111 private String callingAdressAreaCode; 112 private String AnswerAdressAreaCode; 113 private Date startTime; 114 private Date endTime; 115 116 public String getCallingAdressAreaCode() { 117 return callingAdressAreaCode; 118 } 119 120 public void setCallingAdressAreaCode(String callingAdressAreaCode) { 121 this.callingAdressAreaCode = callingAdressAreaCode; 122 } 123 124 public String getAnswerAdressAreaCode() { 125 return AnswerAdressAreaCode; 126 } 127 128 public void setAnswerAdressAreaCode(String answerAdressAreaCode) { 129 AnswerAdressAreaCode = answerAdressAreaCode; 130 } 131 132 public Date getStartTime() { 133 return startTime; 134 } 135 136 public void setStartTime(Date startTime) { 137 this.startTime = startTime; 138 } 139 140 public Date getEndTime() { 141 return endTime; 142 } 143 144 public void setEndTime(Date endTime) { 145 this.endTime = endTime; 146 } 147 } 148 abstract class ChargeMode { 149 private ArrayList<CallChargeRule> chargeRules = new ArrayList<>(); 150 private ArrayList<AnswerChargeRule> answerule = new ArrayList<>(); 151 152 public ArrayList<CallChargeRule> getChargeRules() { 153 return chargeRules; 154 } 155 156 public void setChargeRules(ArrayList<CallChargeRule> chargeRules) { 157 this.chargeRules = chargeRules; 158 } 159 160 public abstract double callCost(UserRecords userRecords); 161 162 public abstract double getMonthlyRent (); 163 164 public abstract void setMonthlyRent(double a); 165 166 public ArrayList<AnswerChargeRule> getAnswerule() { 167 return answerule; 168 } 169 170 public void setAnswerule(ArrayList<AnswerChargeRule> answerule) { 171 this.answerule = answerule; 172 } 173 } 174 class CommunicateRecord { 175 protected String callingNumber; 176 protected String answerNumber; 177 178 public String getCallingNumber() { 179 return callingNumber; 180 } 181 182 public void setCallingNumber(String callingNumber) { 183 this.callingNumber = callingNumber; 184 } 185 186 public String getAnswerNumber() { 187 return answerNumber; 188 } 189 190 public void setAnswerNumber(String answerNumber) { 191 this.answerNumber = answerNumber; 192 } 193 } 194 class LandlinePhoneCharging extends ChargeMode{ 195 private double monthlyRent = 20; 196 @Override 197 public double callCost(UserRecords userRecords) { 198 // TODO Auto-generated method stub 199 CallChargeRule a = new LandPhoneInCityRule(); 200 CallChargeRule b = new LandPhoneInProvinceRule(); 201 CallChargeRule c = new LandPhoneInlandRule(); 202 203 double callcost = a.callCost(userRecords.getCallingInCityRecords()) + b.callCost(userRecords.getCallingInProvinceRecords()) + c.callCost(userRecords.getCallingInLandRecords()); 204 return callcost; 205 } 206 207 @Override 208 public double getMonthlyRent() { 209 // TODO Auto-generated method stub 210 return monthlyRent; 211 } 212 213 public void setMonthlyRent(double monthlyRent) { 214 this.monthlyRent = monthlyRent; 215 } 216 } 217 class LandPhoneInCityRule extends CallChargeRule{ 218 219 @Override 220 public double callCost(ArrayList<CallRecord> callRecords) { 221 // TODO Auto-generated method stub 222 double cost = 0; 223 double m; 224 for(CallRecord a : callRecords) { 225 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 226 int n = (int)m; 227 if(m-n>0.000001) { 228 n = n+1; 229 } 230 cost += 0.1 * n; 231 } 232 return cost; 233 } 234 235 236 } 237 class LandPhoneInlandRule extends CallChargeRule{ 238 239 @Override 240 public double callCost(ArrayList<CallRecord> callRecords) { 241 // TODO Auto-generated method stub 242 double cost = 0; 243 double m; 244 for(CallRecord a : callRecords) { 245 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 246 int n = (int)m; 247 if(m-n>0.000001) { 248 n = n+1; 249 } 250 cost += 0.6 * n; 251 } 252 return cost; 253 } 254 255 } 256 class LandPhoneInProvinceRule extends CallChargeRule{ 257 258 @Override 259 public double callCost(ArrayList<CallRecord> callRecords) { 260 // TODO Auto-generated method stub 261 double cost = 0; 262 double m; 263 for(CallRecord a : callRecords) { 264 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 265 int n = (int)m; 266 if(m-n>0.000001) { 267 n = n+1; 268 } 269 cost += 0.3 * n; 270 } 271 return cost; 272 } 273 274 } 275 class MessageChargeRule { 276 public double MessageCost(ArrayList<MessageRecord> messageRecords) { 277 // TODO Auto-generated method stub 278 double cost = 0; 279 int i = 0; 280 int j = 0; 281 int n = messageRecords.size(); 282 for(MessageRecord a : messageRecords) { 283 j = 0; 284 String m = a.getMessage(); 285 int k = m.length(); 286 if(k>10) { 287 if(k%10>0) { 288 j = k/10 + 1; 289 } 290 else { 291 j = k/10; 292 } 293 } 294 else { 295 j = 1; 296 } 297 for(int x=1;x<=j;x++) { 298 if(i+x<=3) { 299 cost += 0.1; 300 } 301 else if(i+x>3&&i+x<=5) { 302 cost += 0.2; 303 } 304 else { 305 cost += 0.3; 306 } 307 } 308 i +=j; 309 } 310 return cost; 311 } 312 } 313 class MessageRecord extends CommunicateRecord{ 314 private String message; 315 316 public String getMessage() { 317 return message; 318 } 319 320 public void setMessage(String message) { 321 this.message = message; 322 } 323 } 324 class PhoneCharging extends ChargeMode{ 325 private double monthlyRent = 15; 326 @Override 327 public double callCost(UserRecords userRecords) { 328 // TODO Auto-generated method stub 329 double cost = 0; 330 CallChargeRule a = new PhoneInCittCallInLand(); 331 CallChargeRule b = new PhoneInCityCallInCity(); 332 CallChargeRule c = new PhoneInCityCallInProvince(); 333 CallChargeRule d = new PhoneInLandCallOther(); 334 CallChargeRule e = new PhoneInProvinceCallOther(); 335 AnswerChargeRule f = new AnswerInLandRule(); 336 cost += f.AnswerCost(userRecords.getAnswerInLandRecords()) + a.callCost(userRecords.getPhonecallingInCityInLandRecords()); 337 cost += b.callCost(userRecords.getPhonecallingInCityInCityRecords()) + c.callCost(userRecords.getPhonecallingInCityInProvinceRecords()); 338 cost += d.callCost(userRecords.getPhonecallingInLandOtherRecords()) + e.callCost(userRecords.getPhonecallingInProvinceRecords()); 339 return cost; 340 } 341 342 @Override 343 public double getMonthlyRent() { 344 // TODO Auto-generated method stub 345 return monthlyRent; 346 } 347 348 @Override 349 public void setMonthlyRent(double monthlyRent) { 350 // TODO Auto-generated method stub 351 this.monthlyRent = monthlyRent; 352 } 353 354 } 355 class PhoneInCittCallInLand extends CallChargeRule{ 356 357 @Override 358 public double callCost(ArrayList<CallRecord> callRecords) { 359 // TODO Auto-generated method stub 360 double cost = 0; 361 double m; 362 for(CallRecord a : callRecords) { 363 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 364 int n = (int)m; 365 if(m-n>0.000001) { 366 n = n+1; 367 } 368 cost += 0.3 * n; 369 } 370 return cost; 371 } 372 } 373 class PhoneInCityCallInCity extends CallChargeRule{ 374 375 @Override 376 public double callCost(ArrayList<CallRecord> callRecords) { 377 // TODO Auto-generated method stub 378 double cost = 0; 379 double m; 380 for(CallRecord a : callRecords) { 381 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 382 int n = (int)m; 383 if(m-n>0.000001) { 384 n = n+1; 385 } 386 cost += 0.1 * n; 387 } 388 return cost; 389 } 390 }class PhoneInCityCallInProvince extends CallChargeRule{ 391 392 @Override 393 public double callCost(ArrayList<CallRecord> callRecords) { 394 // TODO Auto-generated method stub 395 double cost = 0; 396 double m; 397 for(CallRecord a : callRecords) { 398 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 399 int n = (int)m; 400 if(m-n>0.000001) { 401 n = n+1; 402 } 403 cost += 0.2 * n; 404 } 405 return cost; 406 } 407 }class PhoneInLandCallOther extends CallChargeRule{ 408 409 @Override 410 public double callCost(ArrayList<CallRecord> callRecords) { 411 // TODO Auto-generated method stub 412 double cost = 0; 413 double m; 414 for(CallRecord a : callRecords) { 415 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 416 int n = (int)m; 417 if(m-n>0.000001) { 418 n = n+1; 419 } 420 cost += 0.6 * n; 421 } 422 return cost; 423 } 424 } 425 class PhoneInProvinceCallOther extends CallChargeRule{ 426 427 @Override 428 public double callCost(ArrayList<CallRecord> callRecords) { 429 // TODO Auto-generated method stub 430 double cost = 0; 431 double m; 432 for(CallRecord a : callRecords) { 433 m = Double.valueOf(a.getEndTime().getTime() - a.getStartTime().getTime())/1000/60; 434 int n = (int)m; 435 if(m-n>0.000001) { 436 n = n+1; 437 } 438 cost += 0.3 * n; 439 } 440 return cost; 441 } 442 } 443 class User { 444 private UserRecords userRecords = new UserRecords(); 445 private double balance = 100; 446 private ChargeMode chargemode1 = new LandlinePhoneCharging(); 447 private ChargeMode chargemode2 = new PhoneCharging(); 448 private MessageChargeRule message = new MessageChargeRule(); 449 private String number; 450 451 public double callBalance() { 452 if(number.charAt(0)=='1') { 453 balance = balance - message.MessageCost(userRecords.getSendMessageRecords()); 454 } 455 else { 456 balance = balance - (this.callCost() + chargemode1.getMonthlyRent()); 457 } 458 return balance; 459 } 460 461 public double callCost() { 462 if(number.charAt(0)=='1') { 463 return message.MessageCost(userRecords.getSendMessageRecords()); 464 465 } 466 else { 467 return chargemode1.callCost(userRecords); 468 469 } 470 } 471 472 public UserRecords getUserRecords() { 473 return userRecords; 474 } 475 476 public void setUserRecords(UserRecords userRecords) { 477 this.userRecords = userRecords; 478 } 479 480 public double getBalance() { 481 return balance; 482 } 483 484 public ChargeMode getChargemode() { 485 if(number.charAt(0)=='1') { 486 return chargemode2; 487 } 488 else { 489 return chargemode1; 490 } 491 492 } 493 494 public void setChargemode(ChargeMode chargemode) { 495 if(number.charAt(0)=='1') { 496 this.chargemode2 = chargemode; 497 } 498 else { 499 this.chargemode1 = chargemode; 500 } 501 } 502 503 public String getNumber() { 504 return number; 505 } 506 507 public void setNumber(String number) { 508 this.number = number; 509 } 510 511 } 512 class UserRecords { 513 514 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 515 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 516 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); 517 518 private ArrayList<CallRecord> PhonecallingInLandOtherRecords = new ArrayList<CallRecord>(); 519 private ArrayList<CallRecord> PhonecallingInCityInLandRecords = new ArrayList<CallRecord>(); 520 private ArrayList<CallRecord> PhonecallingInProvinceRecords = new ArrayList<CallRecord>(); 521 private ArrayList<CallRecord> PhonecallingInCityInProvinceRecords = new ArrayList<CallRecord>(); 522 private ArrayList<CallRecord> PhonecallingInCityInCityRecords = new ArrayList<CallRecord>(); 523 524 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); 525 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); 526 private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); 527 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); 528 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); 529 530 public void addCallingInCityRecords (CallRecord callRecord) { 531 callingInCityRecords.add(callRecord); 532 } 533 534 public void addCallingInProvinceRecords (CallRecord callRecord) { 535 callingInProvinceRecords.add(callRecord); 536 } 537 538 public void addCallingInLandRecords (CallRecord callRecord) { 539 callingInLandRecords.add(callRecord); 540 } 541 542 public void addAnswerInCityRecords (CallRecord answerRecord) { 543 answerInCityRecords.add(answerRecord); 544 } 545 public void addAnswerInProvinceRecords (CallRecord answerRecord) { 546 answerInProvinceRecords.add(answerRecord); 547 } 548 549 public void addAnswerInLandRecords (CallRecord answerRecord) { 550 answerInLandRecords.add(answerRecord); 551 } 552 553 public void addSendMessageRecords (MessageRecord sendMessageRecord) { 554 sendMessageRecords.add(sendMessageRecord); 555 } 556 557 public void addReceiveMessageRecords (MessageRecord receiveMessageRecord) { 558 receiveMessageRecords.add(receiveMessageRecord); 559 } 560 561 public ArrayList<CallRecord> getCallingInCityRecords() { 562 return callingInCityRecords; 563 } 564 565 public ArrayList<CallRecord> getCallingInProvinceRecords() { 566 return callingInProvinceRecords; 567 } 568 569 public ArrayList<CallRecord> getCallingInLandRecords() { 570 return callingInLandRecords; 571 } 572 573 public ArrayList<CallRecord> getAnswerInCityRecords() { 574 return answerInCityRecords; 575 } 576 577 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 578 return answerInProvinceRecords; 579 } 580 581 public ArrayList<CallRecord> getAnswerInLandRecords() { 582 return answerInLandRecords; 583 } 584 585 586 public ArrayList<MessageRecord> getReceiveMessageRecords() { 587 return receiveMessageRecords; 588 } 589 590 591 public ArrayList<MessageRecord> getSendMessageRecords() { 592 return sendMessageRecords; 593 } 594 595 public ArrayList<CallRecord> getPhonecallingInLandOtherRecords() { 596 return PhonecallingInLandOtherRecords; 597 } 598 599 public void addPhonecallingInLandOtherRecords(CallRecord phonecallingInLandOtherRecords) { 600 PhonecallingInLandOtherRecords.add(phonecallingInLandOtherRecords); 601 } 602 603 public ArrayList<CallRecord> getPhonecallingInCityInLandRecords() { 604 return PhonecallingInCityInLandRecords; 605 } 606 607 public void addPhonecallingInCityInLandRecords(CallRecord phonecallingInCityInLandRecords) { 608 PhonecallingInCityInLandRecords.add(phonecallingInCityInLandRecords); 609 } 610 611 public ArrayList<CallRecord> getPhonecallingInCityInProvinceRecords() { 612 return PhonecallingInCityInProvinceRecords; 613 } 614 615 public void addPhonecallingInCityInProvinceRecords(CallRecord phonecallingInCityInProvinceRecords) { 616 PhonecallingInCityInProvinceRecords.add(phonecallingInCityInProvinceRecords); 617 } 618 619 public ArrayList<CallRecord> getPhonecallingInCityInCityRecords() { 620 return PhonecallingInCityInCityRecords; 621 } 622 623 public void addPhonecallingInCityInCityRecords(CallRecord phonecallingInCityInCityRecords) { 624 PhonecallingInCityInCityRecords.add(phonecallingInCityInCityRecords); 625 } 626 627 public ArrayList<CallRecord> getPhonecallingInProvinceRecords() { 628 return PhonecallingInProvinceRecords; 629 } 630 631 public void addPhonecallingInProvinceRecords(CallRecord phonecallingInProvinceRecords) { 632 PhonecallingInProvinceRecords.add(phonecallingInProvinceRecords); 633 } 634 635 }
分析:最后一次的题目难度有所降低,主要问题是在于短信条数的计算,以10个为标准进行计算,总体较为简单
心得:主要就是卡在计算短信费用问题,在判断输入方面都没啥,最后还是用了for语句来解决了费用问题,当时打错了一个计算符号导致卡了很久,改好了就一下子过了,还是要细心。
三.踩坑心得
- 这三次作业主要考察的还是对类与类之间的关系和联系,梳理类之间的联系是很大的难点,中间运用TreeMap,将电话号码作为key来进行User的增加查找,TreeMap的好处就是在输入这个数组的数时会自己排列好,可以省去自己排列的麻烦,但是因为不太熟练使用TreeMap导致在使用的实在不知道如何获取value的值得到user对record进行储存,而第二个难点就格式输入的一个判断,在运用正则表达式的时候,总是会不符合标准,或者没能使用最简洁的表达式去判断,一开始甚至没有考虑过格式的问题,对于日期等判断 都是直接使用\\d{4}去表达,导致格式的测试点全错,第二次作业并没有满分,主要是因为在自身设计的方面出现了问题,没能解决好手机与座机在不同区域打电话和接电话,自己也在第一题所给的类图的基础上进行了手机计费的类图设计,因为手机和座机的话费计算并不相同,当时在这里卡了很久,最后勉勉强强算是到了及格线,还是没处理好手机和座机之间的关系,第三次主要针对短信计费,有了前面的基础,主要问题就是短信条数的计算,我是运用了for来处理接收到的短信,十个字符算一条,一开始用的/10直接处理,但是这样在小于十个字符中的短信不会计算费用,后面就是判断了一下/10后的大小来加1,最后也算是解决了。
·
四.改进建议
- 可以把三次结合一下出第四次的pta练习
五.总结
-
通过本阶段的学习自己的收获
熟练了基本的数据类型,for,if,等基础知识
了解到正则表达式,很方便,会继续加深了解和使用
可以基础的使用对象和类、类的继承、多态、异常处理、抽象类以及接口这些知识
认识到了TreeMap的一个使用
能应付不算太复杂的类与类之间的关系
-
通过本阶段的学习发现自己在知识掌握方面存在的不足
要学会自己根据题目的需求先做好类图,再进行代码的实现
需要有耐心去分析需求不然很容易就出错

浙公网安备 33010602011771号