第三次总结性Blog
作者:互联网
(1)前言:
1:难度分析:这次电信计费类型的题目难度比之前的多边形类型题目难度有所降低,手机难度比座机的大,第三次的题目简化成了短信计费难度降低了许多,总体难度中等。
2:题量:三次大作业的题量都差不多,题量中等。
3:知识点:选择结构应用、字符型数据与数值型数据之间的类型转换、一维数组、方法的定义与调用、循环结构、正则表达式、继承、多态、容器。
(2)设计与分析:
题1:PTA-7-1电信计费系统
实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
输入格式:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码除区号外由是7-8位数字组成。
本题只考虑计费类型0-座机计费,电信系列2、3题会逐步增加计费类型。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
注意:
本题非法输入只做格式非法的判断,不做内容是否合理的判断(时间除外,否则无法计算),比如:
1、输入的所有通讯信息均认为是同一个月的通讯信息,不做日期是否在同一个月还是多个月的判定,直接将通讯费用累加,因此月租只计算一次。
2、记录中如果同一电话号码的多条通话记录时间出现重合,这种情况也不做判断,直接 计算每条记录的费用并累加。
3、用户区号不为南昌市的区号也作为正常用户处理。
输出格式:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,
单位元)。假设每个用户初始余额是100元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
建议类图:
参见图1、2、3,可根据理解自行调整:
源码:
1 import java.lang.reflect.Array; 2 import java.text.DateFormat; 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.ArrayList; 6 import java.util.Arrays; 7 import java.util.Date; 8 import java.util.Scanner; 9 10 11 public class Main { 12 public static void main (String [] args) { 13 String s; 14 Scanner in = new Scanner(System.in); 15 DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 16 ArrayList<User> users = new ArrayList<>(); 17 while(true) 18 { 19 s = in.nextLine(); 20 // if(s.matches("u-\\d{12} 0||t-\\d{12} \\d{12}( \\d{4}\\.[1-9]*[0-2]*\\.[1-3]*[0-9]* [0-2][0-3]:[0-5][0-9]:[0-5][0-9]){2}")) { 21 if(s.charAt(0) == 'u') { 22 //注册 23 String [] ss = s.split(" ");//一个字符串进行分割成多个字符串数组 24 String phoneNumber = ss[0].substring(2); 25 User user = new User(phoneNumber); 26 user.setChargeMode(new LandlinePhoneCharging()); 27 users.add(user); 28 } 29 else 30 break; 31 // } 32 } 33 Arrays.sort(new ArrayList[]{users});//T 34 s = s.substring(2); 35 String [] ss = s.split(" "); 36 String startTime; 37 String endTime; 38 Date StartTime,EndTime; 39 40 for(User user : users) 41 { 42 if(user.getNumber().equals(ss[0])) 43 { 44 String call = ss[0].substring(0, 4); 45 String receive = ss[1].substring(0, 4); 46 startTime = ss[2] + " " + ss[3]; 47 endTime = ss[4] + " " + ss[5]; 48 try { 49 StartTime = dateFormat.parse(startTime); 50 } catch (ParseException e) { 51 continue; 52 } 53 try { 54 EndTime = dateFormat.parse(endTime); 55 } catch (ParseException e) { 56 continue; 57 } 58 if(check(receive)== 1) 59 { 60 user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive)); 61 }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime,call,receive)); 62 else user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime,call,receive)); 63 } 64 } 65 while(true) 66 { 67 s = in.nextLine(); 68 if(s.equals("end"))break;//T 69 s = s.substring(2); 70 String [] sss = s.split(" "); 71 String sstartTime; 72 String eendTime; 73 Date SStartTime,EEndTime; 74 for(User user : users) 75 { 76 if(user.getNumber().equals(sss[0])) 77 { 78 String call = sss[0].substring(0, 4); 79 String receive = sss[1].substring(0, 4); 80 sstartTime = sss[2] + " " + sss[3]; 81 eendTime = sss[4] + " " + sss[5]; 82 83 try { 84 SStartTime = dateFormat.parse(sstartTime); 85 } catch (ParseException e) { 86 continue; 87 } 88 try { 89 EEndTime = dateFormat.parse(eendTime); 90 } catch (ParseException e) { 91 continue; 92 } 93 if(check(receive) == 1) 94 { 95 user.getUserRecords().addCallingInCityRecord(new CallRecord(SStartTime, EEndTime, call, receive)); 96 }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(SStartTime, EEndTime,call,receive)); 97 else user.getUserRecords().addCallingInLandRecord(new CallRecord(SStartTime, EEndTime,call,receive)); 98 } 99 } 100 } 101 int a = 0; 102 int b = 0; 103 Call call = new Call(a,b); 104 call.getDistance(call); 105 106 for(User user : users) 107 { 108 System.out.printf("%s %.1f %.1f\n",user.getNumber(),user.calCost(),user.calBalance()); 109 } 110 } 111 public static int check(String s) 112 { 113 if(s.equals("0791"))return 1;//市内0.1 114 else if(s.equals("0790") || s.equals("0792") || s.equals("0793") || s.equals("0794")|| 115 s.equals("0795")|| s.equals("0796") || s.equals("0797")|| s.equals("0798")|| s.equals("0799")|| 116 s.equals("0701"))return 2;//省内0.3 117 else return 3;//国内0.6 118 } 119 } 120 121 abstract class CallChargeRule extends ChargeRule{ 122 abstract double calCost(ArrayList<CallRecord>callRecords); 123 } 124 125 class CallRecord extends CommunicationRecord{ 126 Date startTime; 127 Date endTime; 128 String callingAddressAreaCode; 129 String answerAddressAreaCode; 130 131 public Date getStartTime() { 132 return startTime; 133 } 134 135 public void setStartTime(Date startTime) { 136 this.startTime = startTime; 137 } 138 139 public Date getEndTime() { 140 return endTime; 141 } 142 143 public void setEndTime(Date endTime) { 144 this.endTime = endTime; 145 } 146 147 public String getCallingAddressAreaCode() { 148 return callingAddressAreaCode; 149 } 150 151 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 152 this.callingAddressAreaCode = callingAddressAreaCode; 153 } 154 155 public String getAnswerAddressAreaCode() { 156 return answerAddressAreaCode; 157 } 158 159 public void setAnswerAddressAreaCode(String answerAddressAreaCode) { 160 this.answerAddressAreaCode = answerAddressAreaCode; 161 } 162 public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { 163 this.startTime = startTime; 164 this.endTime = endTime; 165 this.callingAddressAreaCode = callingAddressAreaCode; 166 this.answerAddressAreaCode = answerAddressAreaCode; 167 } 168 } 169 class InputData { 170 private int choice;;//用户输入的选择项 171 public int getChoice() { 172 return choice; 173 } 174 public void setChoice(int choice) { 175 this.choice = choice; 176 } 177 private String color; 178 private String brand; 179 180 181 public String getColor() {//私有成员get方法 182 return this.color; 183 } 184 public String getBrand() { 185 return this.brand; 186 } 187 188 } 189 190 class Call{ 191 public double x; 192 public double y; 193 194 public Call() { 195 196 } 197 198 public Call(double x,double y) { 199 this.x=x; 200 this.y=y; 201 } 202 203 /* 设置坐标x,将输入参数赋值给属性x */ 204 public void setX(double x) { 205 this.x = x; 206 } 207 208 /* 设置坐标y,将输入参数赋值给属性y */ 209 public void setY(double y) { 210 this.y = y; 211 } 212 213 /* 获取坐标x,返回属性x的值 */ 214 public double getX() { 215 return x; 216 } 217 218 /* 获取坐标y,返回属性y的值 */ 219 public double getY() { 220 return y; 221 } 222 public boolean equals(Call p) { 223 boolean b = false; 224 if(this.x==p.getX()&&this.y==p.getY()) { 225 b=true; 226 } 227 return b; 228 } 229 230 public double getDistance(Call p) { 231 return x; 232 } 233 } 234 235 236 abstract class ChargeMode { 237 ArrayList<ChargeRule> chargeRules = new ArrayList<>(); 238 239 public ArrayList<ChargeRule> getChargeRules() { 240 return chargeRules; 241 } 242 243 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 244 this.chargeRules = chargeRules; 245 } 246 abstract double calCost(UserRecords userRecords); 247 248 abstract double getMonthlyRent(); 249 } 250 abstract class ChargeRule { 251 abstract double calCost(ArrayList<CallRecord> callRecords); 252 } 253 class CommunicationRecord { 254 String callingNumber; 255 String answerNumber; 256 257 public String getCallingNumber() { 258 return callingNumber; 259 } 260 261 public void setCallingNumber(String callingNumber) { 262 this.callingNumber = callingNumber; 263 } 264 265 public String getAnswerNumber() { 266 return answerNumber; 267 } 268 269 public void setAnswerNumber(String answerNumber) { 270 this.answerNumber = answerNumber; 271 } 272 } 273 class LandlinePhoneCharging extends ChargeMode{ 274 double monthlyRent = 20; 275 public LandlinePhoneCharging() 276 { 277 getChargeRules().add(new LandPhoneCityRule()); 278 getChargeRules().add(new LandPhoneLandRule()); 279 getChargeRules().add(new LandPhoneProvinceRule()); 280 } 281 282 @Override 283 double calCost(UserRecords userRecords) { 284 double cost = 0; 285 cost = getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) + 286 getChargeRules().get(1).calCost(userRecords.getCallingInLandRecord()) + 287 getChargeRules().get(2).calCost(userRecords.getCallingInProvinceRecord()); 288 return cost; 289 } 290 291 @Override 292 public double getMonthlyRent() { 293 return monthlyRent; 294 } 295 } 296 class LandPhoneCityRule extends CallChargeRule{ 297 @Override 298 double calCost(ArrayList<CallRecord> callRecords) { 299 double cost = 0; 300 for(CallRecord land : callRecords) 301 { 302 double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - 303 land.getStartTime().getTime()) / 1000.0 / 60.0); 304 cost += 0.1 * sumTimeMinutes; 305 } 306 return cost; 307 } 308 } 309 class LandPhoneLandRule extends CallChargeRule{ 310 @Override 311 double calCost(ArrayList<CallRecord> callRecords) { 312 double cost = 0; 313 for(CallRecord land : callRecords) 314 { 315 double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - 316 land.getStartTime().getTime()) / 1000.0 / 60.0); 317 cost += 0.6 * sumTimeMinutes; 318 } 319 return cost; 320 } 321 } 322 323 324 class LandPhoneProvinceRule extends CallChargeRule{ 325 @Override 326 double calCost(ArrayList<CallRecord> callRecords) { 327 double cost = 0; 328 for(CallRecord land : callRecords) 329 { 330 double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - 331 land.getStartTime().getTime()) / 1000.0 / 60.0); 332 cost += 0.3 * sumTimeMinutes; 333 } 334 return cost; 335 } 336 } 337 class MessageRecord extends CommunicationRecord{ 338 String message ; 339 340 public String getMessage() { 341 return message; 342 } 343 344 public void setMessage(String message) { 345 this.message = message; 346 } 347 } 348 class User { 349 UserRecords userRecords = new UserRecords(); 350 double balance = 100; 351 ChargeMode chargeMode; 352 String number; 353 354 public User(String number) { 355 this.number = number; 356 } 357 358 double calBalance() 359 { 360 return getBalance() - calCost() - chargeMode.getMonthlyRent(); 361 } 362 double calCost(){ 363 return chargeMode.calCost(userRecords); 364 } 365 366 public UserRecords getUserRecords() { 367 return userRecords; 368 } 369 370 public void setUserRecords(UserRecords userRecords) { 371 this.userRecords = userRecords; 372 } 373 374 public double getBalance() { 375 return balance; 376 } 377 378 public void setBalance(double balance) { 379 this.balance = balance; 380 } 381 382 public ChargeMode getChargeMode() { 383 return chargeMode; 384 } 385 386 public void setChargeMode(ChargeMode chargeMode) { 387 this.chargeMode = chargeMode; 388 } 389 390 public String getNumber() { 391 return number; 392 } 393 394 public void setNumber(String number) { 395 this.number = number; 396 } 397 } 398 class InputError { 399 //判断从字符串中解析出的点的数量是否合格。 400 public static void wrongNumberOfPoints(ArrayList ps, int num) { 401 if (ps.size() != num) { 402 System.out.println("wrong number of points"); 403 System.exit(0); 404 } 405 } 406 //判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序 407 public static void wrongPointFormat(String s) { 408 if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) { 409 System.out.println("Wrong Format"); 410 System.exit(0); 411 } 412 } 413 414 // 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一 415 public static void wrongChoice(String s) { 416 if (!s.matches("[1-5]:.+")) { 417 System.out.println("Wrong Format"); 418 System.exit(0); 419 } 420 } 421 } 422 class UserRecords { 423 ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 424 ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 425 ArrayList<CallRecord>callingInLandRecords = new ArrayList<CallRecord>(); 426 ArrayList<CallRecord>answerInCityRecords = new ArrayList<CallRecord>(); 427 ArrayList<CallRecord>answerInProvinceRecords = new ArrayList<CallRecord>(); 428 ArrayList<CallRecord>answerInLandRecords = new ArrayList<CallRecord>(); 429 ArrayList<MessageRecord>sendMessageRecords = new ArrayList<MessageRecord>(); 430 ArrayList<MessageRecord>receiveMessageRecords = new ArrayList<MessageRecord>(); 431 public void addCallingInCityRecord(CallRecord callRecord) 432 { 433 callingInCityRecords.add(callRecord); 434 } 435 public void addCallingInProvinceRecord(CallRecord callRecord) 436 { 437 callingInProvinceRecords.add(callRecord); 438 } 439 public void addCallingInLandRecord(CallRecord callRecord) 440 { 441 callingInLandRecords.add(callRecord); 442 } 443 public void answerInCityRecord(CallRecord callRecord) 444 { 445 answerInCityRecords.add(callRecord); 446 } 447 public void answerInProvinceRecord(CallRecord callRecord) 448 { 449 answerInProvinceRecords.add(callRecord); 450 } 451 public void answerInLandRecord(CallRecord callRecord) 452 { 453 answerInLandRecords.add(callRecord); 454 } 455 public void addSendMessageRecords(MessageRecord sendMessageRecord) 456 { 457 sendMessageRecords.add(sendMessageRecord); 458 } 459 public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) 460 { 461 receiveMessageRecords.add(receiveMessageRecord); 462 } 463 public ArrayList<CallRecord> getCallingInCityRecords() { 464 return callingInCityRecords; 465 } 466 467 public ArrayList<CallRecord> getCallingInProvinceRecord() { 468 return callingInProvinceRecords; 469 } 470 471 public ArrayList<CallRecord> getCallingInLandRecord() { 472 return callingInLandRecords; 473 } 474 475 public ArrayList<CallRecord> getAnswerInCityRecords() { 476 return answerInCityRecords; 477 } 478 479 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 480 return answerInProvinceRecords; 481 } 482 483 public ArrayList<CallRecord> getAnswerInLandRecords() { 484 return answerInLandRecords; 485 } 486 487 public ArrayList<MessageRecord> getSendMessageRecord() { 488 return sendMessageRecords; 489 } 490 491 public ArrayList<MessageRecord> getReceiveMessageRecord() { 492 return receiveMessageRecords; 493 } 494 }
分析:
while(true) { s = in.nextLine(); // if(s.matches("u-\\d{12} 0||t-\\d{12} \\d{12}( \\d{4}\\.[1-9]*[0-2]*\\.[1-3]*[0-9]* [0-2][0-3]:[0-5][0-9]:[0-5][0-9]){2}")) { if(s.charAt(0) == 'u') { //注册 String [] ss = s.split(" ");//一个字符串进行分割成多个字符串数组 String phoneNumber = ss[0].substring(2); User user = new User(phoneNumber); user.setChargeMode(new LandlinePhoneCharging()); users.add(user); } else break; // } }
对输入的U注册用户数据进行处理并存储
for(User user : users) { if(user.getNumber().equals(ss[0])) { String call = ss[0].substring(0, 4); String receive = ss[1].substring(0, 4); startTime = ss[2] + " " + ss[3]; endTime = ss[4] + " " + ss[5]; try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { continue; } if(check(receive)== 1) { user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive)); }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime,call,receive)); else user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime,call,receive)); } }
拨打电话的时间和号码进行记录并处理
题2: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元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
源码:
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int i = 0 ; String [] s = new String[100];//s数组 ArrayList<User> users = new ArrayList<>();//user容器 DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); for(;;){ s[i] = in.nextLine();//将每一行输入存入s数组 if(s[i].equals("end")) break; i ++;//个数 } for(int j = 0;j < i;j ++)//u注册用户 { if(s[j].charAt(0) == 'u') { boolean t = false; if (s[j].equals("")) continue;//去掉空的 if(cheakDate(s[j]) == false)continue; if (checkFirst(s[j]) == false) continue;//去掉不符合格式的 String[] s2 = s[j].split(" "); String phoneNumber = s2[0].substring(2);//提取s[j]中的电话号码存入phoneNumber for (User user : users) if (user.getNumber().equals(phoneNumber)) { t = true; break; } if (t) continue;//除去相同号码 User user = new User(phoneNumber); users.add(user); if (s[j].charAt(s[j].length() - 1) == '0')//座机计费 user.setChargeMode(new LandlinePhoneCharging()); else if(s[j].charAt(s[j].length() - 1) == '1')//手机计费 user.setChargeMode(new MobilePhoneCharging()); } else break; } for(int j = 0;j < i;j ++)//t { if(s[j].charAt(0) == 't') { if(s[j].equals(""))continue; if(s[j].charAt(0) == 't') { phone(1, 2, 3, 4); Date(3,4,3,2); } if(cheakDate(s[j]) == false) if (checkString(s[j]) == true) {//格式检查 s[j] = s[j].substring(2); String[] s2 = s[j].split(" "); String startTime; String endTime; Date StartTime = null, EndTime = null; boolean Efficient = false; for (User user : users) { if (user.getNumber().equals(s2[0])) { Efficient = true; if (s2.length == 6) {//079186300001 079186300003 2022.1.3 10:00:25 2022.1.3 10:05:25 String call = s2[0].substring(0, 4);//0791 String receive = s2[1].substring(0, 4);//0791 startTime = s2[2] + " " + s2[3]; endTime = s2[4] + " " + s2[5]; phone(1, 2, 3, 4); Date(3,4,3,2); //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { continue; } if (checkCode(receive) == 1) {//接收地区 市内部 user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive)); } else if (checkCode(receive) == 2)//省 user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime, call, receive)); else if (checkCode(receive) == 3)//国内 user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime, call, receive)); }else if(s2.length == 8)//13811111111 0791 13811111110 020 2022.1.3 08:00:00 2022.1.3 08:09:20 { String call = s2[1];//13811111111 String receive = s2[3];//13811111110 startTime = s2[4] + " " + s2[5];//2022.1.3 08:00:00 endTime = s2[6] + " " + s2[7];//2022.1.3 08:09:20 //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { continue; } if(checkCode(call) == 1 && checkCode(receive) == 1)//市到市 { user.getUserRecords().getMobilePhoneCityCallCity().add(new CallRecord(StartTime, EndTime, call, receive)); }else if(checkCode(call) == 1 && checkCode(receive) == 2) {//市到省 user.getUserRecords().getMobilePhoneCityCallProvince().add(new CallRecord(StartTime, EndTime, call, receive)); }else if(checkCode(call) == 1 && checkCode(receive) == 3){//市到国 user.getUserRecords().getMobilePhoneCityCallLand().add(new CallRecord(StartTime, EndTime, call, receive)); ///判断接听电话的有没有开户 // for(User user1 : users) // { // if(user1.getNumber().equals(ss[2]) == true) // { // user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); // break; // } // } phone(1, 2, 3, 4); Date(3,4,3,2); } else if(checkCode(call) == 2){//省主叫 user.getUserRecords().getMobilePhoneProvincialRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive)); if(checkCode(receive) == 3) { for(User user1 : users) { if(user1.getNumber().equals(s2[2]) == true) { user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); break; } } } }else if(checkCode(call) == 3){ user.getUserRecords().getMobilePhoneDomesticRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive)); if(checkCode(receive) == 3) { phone(1, 2, 3, 4); Date(3,4,3,2); for(User user1 : users) { if(user1.getNumber().equals(s2[2]) == true) { user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); break; } } } } }else if(s2.length == 7)//079186300001 13986300001 0371 2022.1.3 10:00:25 2022.1.3 10:05:11 { if(s2[0].charAt(0) == '1')//手机打座机 13986300001 0791 079186300001 2022.12.31 23:50:25 2023.1.1 00:05:11 { String call = s2[1]; String receive = s2[2].substring(0, 4); startTime = s2[3] + " " + s2[4]; endTime = s2[5] + " " + s2[6]; //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { continue; } if (checkCode(call) == 1 && checkCode(receive) == 1) { user.getUserRecords().getMobilePhoneCityCallCity().add(new CallRecord(StartTime, EndTime, call, receive)); } else if (checkCode(call) == 1 && checkCode(receive) == 2) { user.getUserRecords().getMobilePhoneCityCallProvince().add(new CallRecord(StartTime, EndTime, call, receive)); } else if (checkCode(call) == 1 && checkCode(receive) == 3) { user.getUserRecords().getMobilePhoneCityCallLand().add(new CallRecord(StartTime, EndTime, call, receive)); phone(1, 2, 3, 4); Date(3,4,3,2); } else if (checkCode(call) == 2) { user.getUserRecords().getMobilePhoneProvincialRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive)); } else if (checkCode(call) == 3) { user.getUserRecords().getMobilePhoneDomesticRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive)); } }else//座机打手机079186300001 13986300001 0371 2022.1.3 10:00:25 2022.1.3 10:05:11 { String call = s2[0].substring(0, 4); String receive = s2[2]; startTime = s2[3] + " " + s2[4]; endTime = s2[5] + " " + s2[6]; //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { continue; } if(checkCode(receive) == 1) { user.getUserRecords().getCallingInCityRecords().add(new CallRecord(StartTime, EndTime, call, receive)); } else if(checkCode(receive) == 2) { user.getUserRecords().getCallingInProvinceRecord().add(new CallRecord(StartTime, EndTime, call, receive)); } else if (checkCode(receive) == 3) { user.getUserRecords().getCallingInLandRecord().add(new CallRecord(StartTime, EndTime, call, receive)); for(User user1 : users) if(user1.getNumber().equals(s2[1]) == true) { user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); break; } phone(1, 2, 3, 4); Date(3,4,3,2); } } } } } if(Efficient == false) { if(s2.length == 8) { String call = s2[1]; String receive = s2[3]; startTime = s2[4] + " " + s2[5]; endTime = s2[6] + " " + s2[7]; try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { // continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { // continue; } //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode ///判断接听电话的有没有开户 for(User user : users) if(user.getNumber().equals(s2[2])) if (checkCode(receive) == 3) { user.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); phone(1, 2, 3, 4); Date(3,4,3,2); } } // else if(ss.length == 7 && ss[0].charAt(0) == '0') // { // String call = ss[0].substring(0,4); // String receive = ss[2]; // startTime = ss[3] + " " + ss[4]; // endTime = ss[5] + " " + ss[6]; // try { // StartTime = dateFormat.parse(startTime); // } catch (ParseException e) { // // continue; // } // try { // EndTime = dateFormat.parse(endTime); // } catch (ParseException e) { // // continue; // } // //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode // ///判断接听电话的有没有开户 // for(User user : users) // if(user.getNumber().equals(ss[1])) // if (checkCode(receive) == 3) { // user.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); // } // } } } } } //座机打座机 座机打手机 手机打座机 手机打手机 TreeMap<String, User> treeMap = new TreeMap<>(); for (User user : users) { treeMap.put(user.getNumber(), user); } Iterator<User> t = treeMap.values().iterator(); while (t.hasNext()) { User user = t.next(); System.out.println(user.number + " " + user.calCost() + " " + user.calBalance()); } } public static double phone(double x1, double y1, double x2, double y2){ double dis = 0 ; dis = Math.abs((x1-x2)-(y1-y2)); return dis; } public static double Date(double x1, double y1, double x2, double y2){ double dis = 0 ; dis = Math.abs((x1+x2)-(y1+y2)); return dis; } public static boolean cheakDate(String s){ if(s.matches("u-0[0-9]{10,11} [0-1]")) return true; if(s.matches("u-1[0-9]{10} [0-1]")) return true; return false; } static boolean checkString(String str) { //月份:((((20)\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\d|3[01]))|(((19|20)\d{2}).(0?[469]|11).(0?[1-9]|[12]\d|30))|(((19|20)\d{2}).0?2.(0?[1-9]|1\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] //座机打座机 //座机打手机 t-0[0-9]{10,11} 1[0-9]{10} [0-9]{3,4} if(str.matches("t-0[0-9]{10,11} 0[0-9]{9,11} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]")) return true; else if(str.matches("t-0[0-9]{10,11} 1[0-9]{10} [0-9]{3,4} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]")) return true; else if(str.matches("t-1[0-9]{10} [0-9]{3,4} 0[0-9]{9,11} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]")) return true; else if(str.matches("t-1[0-9]{10} [0-9]{3,4} 1[0-9]{10} [0-9]{3,4} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]")) return true; //手机打座机 //手机打手机 //if(str.matches()) else return false; } static boolean checkFirst(String s) { if(s.matches("u-0[0-9]{10,11} [0-1]")) return true; if(s.matches("u-1[0-9]{10} [0-1]")) return true; return false; } public static int checkCode(String s) { if (s.equals("0791")) return 1;//市内 else if (s.equals("0790") || s.equals("0792") || s.equals("0793") || s.equals("0794") || s.equals("0795") || s.equals("0796") || s.equals("0797") || s.equals("0798") || s.equals("0799") || s.equals("0701")) return 2;//省内 else return 3;//国内 } public abstract static class ChargeRule { abstract double calCost(ArrayList<CallRecord> callRecords); } public static class MobilePhoneCityCallCityRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.1 * sumTimeMinutes; } return cost; } } public static class MobilePhoneCharging extends ChargeMode{ double monthlyRent = 15; public MobilePhoneCharging () { getChargeRules().add(new MobilePhoneCityCallCityRule()); getChargeRules().add(new MobilePhoneCityCallProvinceRule()); getChargeRules().add(new MobilePhoneCityCallLandRule()); getChargeRules().add(new MobilePhoneDomesticRoamingCallRule()); getChargeRules().add(new MobilePhoneProvincialRoamingCallRule()); getChargeRules().add(new MobilePhoneRoamingAnsweringOutsideProvinceRule()); } @Override double calCost(UserRecords userRecords) { double cost = 0; cost = getChargeRules().get(0).calCost(userRecords.getMobilePhoneCityCallCity()) + getChargeRules().get(1).calCost(userRecords.getMobilePhoneCityCallProvince()) + getChargeRules().get(2).calCost(userRecords.getMobilePhoneCityCallLand()) + getChargeRules().get(3).calCost(userRecords.getMobilePhoneDomesticRoamingCall()) + getChargeRules().get(4).calCost(userRecords.getMobilePhoneProvincialRoamingCall()) + getChargeRules().get(5).calCost(userRecords.getMobilePhoneRoamingAnsweringOutsideProvince()); return cost; } @Override public double getMonthlyRent() { return monthlyRent; } } public abstract static class CallChargeRule extends ChargeRule { abstract double calCost(ArrayList<CallRecord> callRecords); } public static class MobilePhoneProvincialRoamingCallRule extends CallChargeRule {//手机省级漫游呼叫规则 @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.3 * sumTimeMinutes; } return cost; } } public static class MessageRecord extends CommunicationRecord { String message ; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } public static class LandlinePhoneCharging extends ChargeMode { double monthlyRent = 20; public LandlinePhoneCharging() { getChargeRules().add(new LandPhoneCityRule()); getChargeRules().add(new LandPhoneLandRule()); getChargeRules().add(new LandPhoneProvinceRule()); } @Override double calCost(UserRecords userRecords) { double cost = 0; cost = getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) + getChargeRules().get(1).calCost(userRecords.getCallingInLandRecord()) + getChargeRules().get(2).calCost(userRecords.getCallingInProvinceRecord()); return cost; } @Override public double getMonthlyRent() { return monthlyRent; } } public static class MobilePhoneCityCallProvinceRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.2 * sumTimeMinutes; } return cost; } } public static class CommunicationRecord { String callingNumber; String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } public static class LandPhoneLandRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord land : callRecords) { double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - land.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.6 * sumTimeMinutes; } return cost; } } public static class User { UserRecords userRecords = new UserRecords(); double balance = 100; ChargeMode chargeMode; String number; public User(String number) { this.number = number; } double calBalance() { return getBalance() - calCost() - chargeMode.getMonthlyRent(); } double calCost(){ return chargeMode.calCost(userRecords); } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } public static class CallRecord extends CommunicationRecord { Date startTime; Date endTime; String callingAddressAreaCode; String answerAddressAreaCode; public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { this.startTime = startTime; this.endTime = endTime; this.callingAddressAreaCode = callingAddressAreaCode; this.answerAddressAreaCode = answerAddressAreaCode; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } public static class MobilePhoneCityCallLandRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.3 * sumTimeMinutes; } return cost; } } public static class UserRecords { ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>callingInLandRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>answerInCityRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>answerInProvinceRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>answerInLandRecords = new ArrayList<CallRecord>(); ArrayList<MessageRecord>sendMessageRecords = new ArrayList<MessageRecord>(); ArrayList<MessageRecord>receiveMessageRecords = new ArrayList<MessageRecord>(); ArrayList<CallRecord> mobilePhoneCityCallCity = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneCityCallProvince = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneCityCallLand = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneDomesticRoamingCall = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneProvincialRoamingCall = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneRoamingAnsweringOutsideProvince = new ArrayList<CallRecord>(); public void addMobilePhoneCityCallCity(CallRecord callRecord){mobilePhoneCityCallCity.add(callRecord);}; public void addMobilePhoneCityCallProvince(CallRecord callRecord){mobilePhoneCityCallProvince.add(callRecord);}; public void addMobilePhoneCityCallLand(CallRecord callRecord){mobilePhoneCityCallLand.add(callRecord);}; public void addMobilePhoneDomesticRoamingCall(CallRecord callRecord){mobilePhoneDomesticRoamingCall.add(callRecord);}; public void addMobilePhoneProvincialRoamingCall(CallRecord callRecord){mobilePhoneProvincialRoamingCall.add(callRecord);}; public void addMobilePhoneRoamingAnsweringOutsideProvince(CallRecord callRecord){mobilePhoneRoamingAnsweringOutsideProvince.add(callRecord);}; public void addCallingInCityRecord(CallRecord callRecord) { callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecord(CallRecord callRecord) { callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecord(CallRecord callRecord) { callingInLandRecords.add(callRecord); } public void answerInCityRecord(CallRecord callRecord) { answerInCityRecords.add(callRecord); } public void answerInProvinceRecord(CallRecord callRecord) { answerInProvinceRecords.add(callRecord); } public void answerInLandRecord(CallRecord callRecord) { answerInLandRecords.add(callRecord); } public void addSendMessageRecords(MessageRecord sendMessageRecord) { sendMessageRecords.add(sendMessageRecord); } public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) { receiveMessageRecords.add(receiveMessageRecord); } public ArrayList<CallRecord> getMobilePhoneCityCallCity() { return mobilePhoneCityCallCity; } public ArrayList<CallRecord> getMobilePhoneCityCallProvince() { return mobilePhoneCityCallProvince; } public ArrayList<CallRecord> getMobilePhoneCityCallLand() { return mobilePhoneCityCallLand; } public ArrayList<CallRecord> getMobilePhoneDomesticRoamingCall() { return mobilePhoneDomesticRoamingCall; } public ArrayList<CallRecord> getMobilePhoneProvincialRoamingCall() { return mobilePhoneProvincialRoamingCall; } public ArrayList<CallRecord> getMobilePhoneRoamingAnsweringOutsideProvince() { return mobilePhoneRoamingAnsweringOutsideProvince; } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public ArrayList<CallRecord> getCallingInProvinceRecord() { return callingInProvinceRecords; } public ArrayList<CallRecord> getCallingInLandRecord() { return callingInLandRecords; } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public ArrayList<MessageRecord> getSendMessageRecord() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecord() { return receiveMessageRecords; } } public abstract static class ChargeMode { ArrayList<ChargeRule> chargeRules = new ArrayList<>(); public ArrayList<ChargeRule> getChargeRules() { return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } abstract double calCost(UserRecords userRecords); abstract double getMonthlyRent(); } //移动电话省外漫游呼叫规则 public static class MobilePhoneRoamingAnsweringOutsideProvinceRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.3 * sumTimeMinutes; } return cost; } } public static class LandPhoneProvinceRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord land : callRecords) { double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - land.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.3 * sumTimeMinutes; } return cost; } } public static class LandPhoneCityRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord land : callRecords) { double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - land.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.1 * sumTimeMinutes; } return cost; } } public static class MobilePhoneDomesticRoamingCallRule extends CallChargeRule {//手机国内漫游呼叫规则 @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.6 * sumTimeMinutes; } return cost; } } }
分析:
利用checkCode类判断地区从而分类计费
if (checkCode(receive) == 1) {//接收地区 市内部 user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive)); } else if (checkCode(receive) == 2)//省 user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime, call, receive)); else if (checkCode(receive) == 3)//国内 user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime, call, rec
方法和上一次相同就是多了很多判断。
if(checkCode(receive) == 1) { user.getUserRecords().getCallingInCityRecords().add(new CallRecord(StartTime, EndTime, call, receive)); } else if(checkCode(receive) == 2) { user.getUserRecords().getCallingInProvinceRecord().add(new CallRecord(StartTime, EndTime, call, receive)); } else if (checkCode(receive) == 3) { user.getUserRecords().getCallingInLandRecord().add(new CallRecord(StartTime, EndTime, call, receive)); for(User user1 : users) if(user1.getNumber().equals(s2[1]) == true) { user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); break; }题3: 7-1 电信计费系列3-短信计费 分数 50 作者 蔡轲 单位 南昌航空大学
实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
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。
本题只考虑短信计费,不考虑通信费用以及月租费。
源码:
import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); HashSet<User> users = new HashSet<>();//存入用户 ArrayList<String> messages = new ArrayList<>();//存入信息 String Line; do{ Line = input.nextLine(); User a; if (Line.equals("")) continue; if (Line.charAt(0) == 'u' && Line.charAt(14) == '3') {//注册 a = new User(Line.substring(2, 13)); users.add(a);//注册用户电话号码 } else if ( legal(Line.substring(2)) && Line.charAt(0) == 'm') {//拨打 messages.add(Line); } }while (!Line.equals("end")); ArrayList<User> userone = new ArrayList<>(users); Collections.sort(userone); InputData inputData = new InputData(); inputData.getChoice(); inputData.getPoints(); inputData.getselect(); for (User j : userone) { double cost; cost = callCost(j, messages); System.out.printf("%s %.1f %.1f\n", j.num, cost, 100 - cost); } } public static double callCost(User user, ArrayList<String> messages) { int num = 0; for (String m : messages) { if (Objects.equals(getNum(m), user.num)) num = num + getMessageNum(m); } if (num > 5) return 0.7 + (num - 5) * 0.3; else if (num > 3) return 0.3 + (num - 3) * 0.2; else return num * 0.1; } static String getNum(String s) { for (int i = 2; i < 13; i++) { if (!(s.charAt(i) >= '0' && s.charAt(i) <= '9')) return null; } return s.substring(2, 13); } private static int getMessageNum(String string) { int a = 0; for (int i = 0; i < string.length(); i++) { if (string.charAt(i) == ' ') { if (a != 1) a++; else { a = i; break; } } } int b = string.length() - a; int c = b / 10; if (b % 10 != 0) c++; return c; } static boolean legal(String s) { for (int i = 0; i < s.length(); i++) { if (!(s.charAt(i) >= '0' && s.charAt(i) <= '9') && s.charAt(i) != ',' && s.charAt(i) != ' ' && s.charAt(i) != '.' && !(s.charAt(i) >= 'a' && s.charAt(i) <= 'z') && !(s.charAt(i) >= 'A' && s.charAt(i) <= 'Z')) { return false; } } return true; } } class InputData { private int choice;;//用户输入的选择项 public int getChoice() { return choice; } public int getselect() { return choice; } public double getPoints() { return 0; } } class User implements Comparable<User> { String num; public User(String num) { this.num = num; } @Override public int compareTo(User o) { return num.compareTo(o.num); } }
分析:
这次的功能比较简单利用如下容器存储信息
HashSet<User> users = new HashSet<>();//存入用户
ArrayList<String> messages = new ArrayList<>();//存入信息
用如下方法获得短信数量
static String getNum(String s) { for (int i = 2; i < 13; i++) { if (!(s.charAt(i) >= '0' && s.charAt(i) <= '9')) return null; } return s.substring(2, 13); } private static int getMessageNum(String string) { int a = 0; for (int i = 0; i < string.length(); i++) { if (string.charAt(i) == ' ') { if (a != 1) a++; else { a = i; break; } } } int b = string.length() - a; int c = b / 10; if (b % 10 != 0) c++; return c; }
(3)采坑心得:
不知道怎么计算通话时间
public class FormatDateTime { public static String toLongDateString(Date dt){ SimpleDateFormat myFmt=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E "); return myFmt.format(dt); } public static String toShortDateString(Date dt){ SimpleDateFormat myFmt=new SimpleDateFormat("yy年MM月dd日 HH时mm分"); return myFmt.format(dt); } public static String toLongTimeString(Date dt){ SimpleDateFormat myFmt=new SimpleDateFormat("HH mm ss SSSS"); return myFmt.format(dt); } public static String toShortTimeString(Date dt){ SimpleDateFormat myFmt=new SimpleDateFormat("yy/MM/dd HH:mm"); return myFmt.format(dt); } public static void main(String[] args) { Date now=new Date(); System.out.println(FormatDateTime.toLongDateString(now)); System.out.println(FormatDateTime.toShortDateString(now)); System.out.println(FormatDateTime.toLongTimeString(now)); System.out.println(FormatDateTime.toShortTimeString(now)); } } 调用的main 测试结果: 2004年12月16日 17时38分26秒 星期四 04年12月16日 17时38分 17 38 26 0965 04/12/16 17:38
(4)改进建议:
类图中的类有些我没有用到,有些情况也没有考虑到,有待完善。
(5)总结:
(1)下次要提前开始写大作业,不能卡着时间点,这样才有更多的时间去修改代码,去思考难的问题,提升解决问题的能力。
(2)要提升自学能力和学习能力,提高学习的主动性,很多问题在网上都能找到解决方法,解决问题的过程就是学习的过程。
(3)我对于多类还有许多不懂的地方,今后要加强这方面的学习。
标签:总结性,return,String,double,ArrayList,Blog,new,public,第三次 来源: https://www.cnblogs.com/luokeliu/p/16363257.html