作业总结
前言:
pta6中给出了一道看起来很有挑战性并且和后面的作业题目联系紧密的大题,涉及到了继承、多态、抽象类、集合框架等知识点。而且题给的类图并不是合在一起的,这也给我的理解造成了许多困难。
pta7是关于移动业务资费的第二次题目,由于第一次是座机与座机间的交流,所以不需要考虑打电话的座机的位置,但是本次作业包括了手机的套餐,还需要考虑手机的所在地,并且手机接听电话也有收费的情况,所以需要添加许多东西到计费规则上去,而这也导致了正则表达式的改变。
pta8有关于移动业务资费的第三次题目,难度较第一、二次降低了很多,因为本题只要考虑短信的计费,不需要前两次复杂的规则计费,因此写起来比较简单。
设计与分析:
一、编写一个类Shop(商店),该类中有一个成员内部类InnerCoupons(内部购物券),可以用于购买该商店的牛奶(假设每箱牛奶售价为50元)。要求如下:
(1)Shop类中有私有属性milkCount(牛奶的箱数,int类型)、公有的成员方法setMilkCount( )和getMilkCount( )分别用于设置和获取牛奶的箱数。
(2)成员内部类InnerCoupons,有公有属性value(面值,int类型),一个带参数的构造方法可以设定购物券的面值value,一个公有的成员方法buy( )要求输出使用了面值为多少的购物券进行支付,同时使商店牛奶的箱数减少value/50。
(3)Shop类中还有成员变量coupons50(面值为50元的内部购物券,类型为InnerCoupons)、coupons100(面值为100元的内部购物券,类型为InnerCoupons)。
(4)在Shop类的构造方法中,调用内部类InnerCoupons的带参数的构造方法分别创建上面的购物券coupons50、coupons100。
在测试类Main中,创建一个Shop类的对象myshop,从键盘输入一个整数(大于或等于3),将其设置为牛奶的箱数。假定有顾客分别使用了该商店面值为50的购物券、面值为100的购物券各消费一次,分别输出消费后商店剩下的牛奶箱数。
首先对此题进行分析,题目需要设计两个类,并将InnerCoupons类的对象作为Shop类的成员变量,此外,牛奶的箱数也作为Shop类的私有的成员变量。首先对InnerCoupons类进行分析。Value(面值)作为共有成员变量,setValue()和buy()这两个成员函数,以完成对面值value的设定和对优惠券的使用进行输出以及控制商店牛奶的箱数。对Shop类进行分析,除了前面提到的成员变量,还需加入两个成员函数,setMilkCount(),getMilkCount()分别用于设置和获取牛奶的箱数。
在程序设计的过程中,在实现对应的函数操作时会相对简单,需要注意的就是将其它类的对象作为本类中的成员变量,对其初始化和使用需要小心,以免造成不必要的错误,在调用内部类InnerCoupons的带参数的构造方法分别创建购物券coupons50、coupons100时需要注意其初始化过程。然后在程序的使用过程中,需要做好对优惠券的统计以及对牛闹箱数的统计,在对应的函数中实验功能。在这些类的设计都完成了之后,再对程序进行调试检查,确认无误后,再新增一个Interaction()作为面向对象过程中的交互系统。最后在测试类Main中,创建一个Shop类的对象myshop,从键盘输入一个整数(大于或等于3),并将其设置为牛奶的箱数,对给定的输入样例进行,最终确认程序无误,程序设计完成。
1 import java.util.Scanner; 2 3 /* 4 5 编写一个类Shop(商店),该类中有一个成员内部类InnerCoupons(内部购物券),可以用于购买该商店的牛奶(假设每箱牛奶售价为50元)。要求如下: 6 (1)Shop类中有私有属性milkCount(牛奶的箱数,int类型)、公有的成员方法setMilkCount( )和getMilkCount( )分别用于设置和获取牛奶的箱数。 7 (2)成员内部类InnerCoupons,有公有属性value(面值,int类型),一个带参数的构造方法可以设定购物券的面值value 8 ,一个公有的成员方法buy( )要求输出使用了面值为多少的购物券进行支付,同时使商店牛奶的箱数减少value/50。 9 (3)Shop类中还有成员变量coupons50(面值为50元的内部购物券,类型为InnerCoupons)、coupons100(面值为100元的内部购物券,类型为InnerCoupons)。 10 (4)在Shop类的构造方法中,调用内部类InnerCoupons的带参数的构造方法分别创建上面的购物券coupons50、coupons100。 11 12 13 在测试类Main中,创建一个Shop类的对象myshop,从键盘输入一个整数(大于或等于3),将其设置为牛奶的箱数。假定有顾客分别使用了该商店面值为50的购物券、 14 面值为100的购物券各消费一次,分别输出消费后商店剩下的牛奶箱数。 15 */ 16 public class Main { 17 public static void main(String[] args) { 18 Shop myshop = new Shop(); 19 Scanner sc = new Scanner(System.in); 20 myshop.setMilkCount(sc.nextInt()); 21 System.out.println("使用了面值为50的购物券进行支付"); 22 myshop.coupons50.buy(); 23 System.out.println("牛奶还剩"+myshop.getMilkCount()+"箱"); 24 System.out.println("使用了面值为100的购物券进行支付"); 25 myshop.coupons100.buy(); 26 System.out.println("牛奶还剩"+myshop.getMilkCount()+"箱"); 27 } 28 29 } 30 class Shop{ 31 InnerCoupons coupons50; 32 InnerCoupons coupons100; 33 Shop(){ 34 coupons50 = new InnerCoupons(50); 35 coupons100 = new InnerCoupons(100); 36 } 37 private int milkCount; 38 public int getMilkCount() { 39 return milkCount; 40 } 41 42 public void setMilkCount(int milkCount) { 43 this.milkCount = milkCount; 44 } 45 class InnerCoupons{ 46 public int value; 47 InnerCoupons(int m){ 48 value = m; 49 } 50 51 public void buy(){ 52 setMilkCount(getMilkCount()-value/50); 53 } 54 } 55 56 }
二、
经过不懈的努力,C~K终于当上了班主任。
现在他要统计班里学生的名单,但是C~K在教务系统中导出班级名单时出了问题,发现会有同学的信息重复,现在他想把重复的同学信息删掉,只保留一个,
但是工作量太大了,所以找到了会编程的你,你能帮他解决这个问题吗?
输入格式:
第一行输入一个N,代表C~K导出的名单共有N行(N<100000).
接下来的N行,每一行包括一个同学的信息,学号 姓名 年龄 性别。
输出格式:
第一行输出一个n,代表删除重复名字后C~K的班级共有几人。
接下来的n行,输出每一个同学的信息,输出按照学号从小到大的顺序。
分析问题,对于给定的多组数据,要求删除相同的数据,并将数据按照学号由小到大的顺序将数据排序并进行输出。可以通过数组+链表这种数据结构来实现此程序。首先提示用户在第一行输入一个N来做为数组的长度,然后对于接下来输入的同学的信息储存在链表当中。之后便开始依次检查这些数组,提前设置一个flag结点作为此学号是否已经出现的标志,并检查此后的数据,若flag为1表示已经出现,则将重复出现的结点删去,将其指向NULL。如此操作将数组全部扫描完毕,最后得到的是未排序但无重复的一组数据。最后再采用快速排序对学号进行排序,并统计好最终的个数。最终,按照输出样例进行输出即可。题目主要的难点在于设计好数组+链表这种数据结构,已经使用一种合适的排序算法来实验排序,程序本身并不复杂。
1 import java.util.ArrayList; 2 import java.util.Collection; 3 import java.util.Collections; 4 import java.util.Scanner; 5 public class Main { 6 7 public static void main(String[] args) { 8 // write your code here 9 Scanner scan = new Scanner(System.in); 10 int num = scan.nextInt(); 11 ArrayList<String> a = new ArrayList<>(); 12 for (int i = 0; i < num * 4; i++) { 13 a.add(scan.next()); 14 } 15 for (int i = 0; i < a.size()-4; i+= 4) { 16 for (int j = a.size()-4; j > i; j-=4){ 17 if (a.get(j).equals(a.get(i))){ 18 for(int k = 0;k < 4;k ++){ 19 a.remove(j); 20 } 21 22 } 23 } 24 } 25 26 for (int i = 0; i <= a.size() - 8; i += 4) { 27 for (int j = i + 4; j <= a.size() - 4; j += 4) { 28 if (Integer.parseInt(a.get(i)) > Integer.parseInt(a.get(j))) { 29 int b = i; 30 int c = j; 31 for (int k = 0; k < 4; k++) { 32 Collections.swap(a, b++, c++); 33 } 34 } 35 } 36 } 37 System.out.println(a.size() / 4); 38 for (int o = 0; o < a.size(); o += 4) { 39 System.out.print(a.get(o) + " "); 40 System.out.print(a.get(o + 1) + " "); 41 System.out.print(a.get(o + 2) + " "); 42 System.out.print(a.get(o + 3)); 43 System.out.println(); 44 45 } 46 } 47 }
三、
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、输入的所有通讯信息均认为是同一个月的通讯信息,不做日期是否在同一个月还是多个月的判定,直接将通讯费用累加,因此月租只计算一次。
2、记录中如果同一电话号码的多条通话记录时间出现重合,这种情况也不做判断,直接 计算每条记录的费用并累加。
3、用户区号不为南昌市的区号也作为正常用户处理。
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,
单位元)。假设每个用户初始余额是100元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
1 import java.util.Scanner; 2 import java.util.TreeMap; 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.ArrayList; 6 import java.util.Date; 7 8 public class Main { 9 10 public static void main(String[] args) { 11 // TODO 自动生成的方法存根 12 Scanner in = new Scanner(System.in); 13 TreeMap<String,User> userrecords = new TreeMap<String, User>(); 14 String check1 = "^u-\\d{11,12}\\s(0|1|2)$"; 15 String check2 = "t-(\\d){11,12}\\s(\\d){10,12}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d"; 16 String a = in.nextLine(); 17 18 while(!a.equals("end")) { 19 if(a.matches(check1)) { 20 String[] s1 = a.split("-"); 21 String[] s2 = s1[1].split(" "); 22 String s3 = s2[0].substring(4); 23 ChargeMode chargeMode = new LandlinePhoneCharging(); 24 User user = new User(s3,chargeMode); 25 userrecords.put(s3, user); 26 27 } 28 29 if(a.matches(check2)) { 30 String[] a1 = a.split("-"); 31 String[] a2 = a1[1].split(" "); 32 String callingarea = a2[0].substring(0, 4); 33 String callingnumber = a2[0].substring(4); 34 String listeningnumber = a2[1].substring(4); 35 String listeningarea = a2[1].substring(0, 4); 36 String startTime = a2[2]+" "+a2[3]; 37 String endTime = a2[4]+" "+a2[5]; 38 Date startDate = new Date(); 39 Date endDate = new Date(); 40 41 SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 42 try { 43 startDate = format.parse(startTime); 44 endDate = format.parse(endTime); 45 } 46 catch (ParseException e) { 47 e.printStackTrace(); 48 } 49 50 CallRecord callRecord = new CallRecord(callingnumber,listeningnumber,callingarea,listeningarea,startDate,endDate); 51 if(userrecords.get(callingnumber)!=null){ 52 53 54 if(callingarea.equals("0791")&&listeningarea.equals("0791")) { 55 userrecords.get(callingnumber).getUserRecords().addCallingInCityRecords(callRecord); 56 } 57 else if(callingarea.equals("0791")&&(listeningarea.equals("0790")||listeningarea.equals("0792")||listeningarea.equals("0793")||listeningarea.equals("0794")||listeningarea.equals("0795")||listeningarea.equals("0796")||listeningarea.equals("0797")||listeningarea.equals("0798")||listeningarea.equals("0799")||listeningarea.equals("0701"))) { 58 userrecords.get(callingnumber).getUserRecords().addCallingInProvinceRecords(callRecord); 59 } 60 else { 61 userrecords.get(callingnumber).getUserRecords().addCallingInLandRecords(callRecord); 62 } 63 } 64 } 65 a = in.nextLine(); 66 } 67 68 for(User user : userrecords.values()) { 69 System.out.println("0791"+user.getNumber()+" "+Math.round(user.calCost()*100.0)/100.0+" "+Math.round(user.calBalance()*100.0)/100.0); 70 } 71 72 } 73 74 } 75 76 class CallChargeRule extends ChargeRule{ 77 78 public double calCost(ArrayList<CallRecord> callRecords) { 79 return 0; 80 } 81 82 } 83 class CallRecord extends CommunicationRecord{ 84 85 private Date startTime; 86 private Date endTime; 87 private String callingAddressAreaCode; 88 private String answeringAddressAreaCode; 89 private String callingNumber; 90 private String answeringNumber; 91 92 public CallRecord(String callingNumber,String answeringNumber,String callingAddressAreaCode,String answeringAddressAreaCode,Date startTime,Date endTime) { 93 this.answeringAddressAreaCode = answeringAddressAreaCode; 94 this.callingAddressAreaCode = callingAddressAreaCode; 95 this.answeringNumber = answeringNumber; 96 this.callingNumber = callingNumber; 97 this.endTime = endTime; 98 this.startTime = startTime; 99 } 100 101 public Date getStartTime() { 102 return startTime; 103 } 104 105 public void setStartTime(Date startTime) { 106 this.startTime = startTime; 107 } 108 109 public Date getEndTime() { 110 return endTime; 111 } 112 113 public void setEndTime(Date endTime) { 114 this.endTime = endTime; 115 } 116 117 public String getCallingAddressAreaCode() { 118 return callingAddressAreaCode; 119 } 120 121 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 122 this.callingAddressAreaCode = callingAddressAreaCode; 123 } 124 125 public String getAnsweringAddressAreaCode() { 126 return answeringAddressAreaCode; 127 } 128 129 public void setAnsweringAddressAreaCode(String answeringAddressAreaCode) { 130 this.answeringAddressAreaCode = answeringAddressAreaCode; 131 } 132 133 public String getCallingNumber() { 134 return callingNumber; 135 } 136 137 public void setCallingNumber(String callingNumber) { 138 this.callingNumber = callingNumber; 139 } 140 141 public String getAnsweringNumber() { 142 return answeringNumber; 143 } 144 145 public void setAnsweringNumber(String answeringNumber) { 146 this.answeringNumber = answeringNumber; 147 } 148 149 150 151 } 152 abstract class ChargeMode { 153 154 private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); 155 156 157 public ArrayList<ChargeRule> getChargeRules() { 158 return chargeRules; 159 } 160 161 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 162 this.chargeRules = chargeRules; 163 } 164 165 public double calCost(UserRecords userRecords) { 166 return 0; 167 } 168 169 public double getMonthlyRent() { 170 return 0; 171 } 172 173 } 174 abstract class ChargeRule { 175 176 public double calCost(ArrayList<CallRecord> callingInCityRecords) { 177 // TODO 自动生成的方法存根 178 return 0; 179 } 180 181 182 } 183 abstract class CommunicationRecord { 184 185 protected String callingnumber; 186 187 public String getCallingnumber() { 188 return callingnumber; 189 } 190 191 public void setCallingnumber(String callingnumber) { 192 this.callingnumber = callingnumber; 193 } 194 195 } 196 class LandlinePhoneCharging extends ChargeMode{ 197 198 private double monthlyRent = 20; 199 200 @Override 201 public double calCost(UserRecords userRecords) { 202 // TODO 自动生成的方法存根 203 double sum = 0,a,b,c; 204 205 getChargeRules().add(new LandPhoneInCityRule()); 206 getChargeRules().add(new LandPhoneInProvinceRule()); 207 getChargeRules().add(new LandPhoneInLandRule()); 208 209 a = super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()); 210 b = super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords()); 211 c = super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords()); 212 sum = a+b+c; 213 214 return sum; 215 } 216 217 @Override 218 public double getMonthlyRent() { 219 // TODO 自动生成的方法存根 220 return monthlyRent; 221 } 222 223 } 224 class LandPhoneInCityRule extends CallChargeRule{ 225 226 @Override 227 public double calCost(ArrayList<CallRecord> callRecords) { 228 // TODO 自动生成的方法存根 229 double sum3 = 0; 230 for(CallRecord a:callRecords) { 231 sum3 = sum3 + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.1; 232 } 233 return sum3; 234 } 235 236 237 238 } 239 class LandPhoneInLandRule extends CallChargeRule{ 240 241 @Override 242 public double calCost(ArrayList<CallRecord> callRecords) { 243 // TODO 自动生成的方法存根 244 double sum1 = 0; 245 for(CallRecord a:callRecords) { 246 sum1=sum1+Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.6; 247 } 248 return sum1; 249 } 250 251 252 253 } 254 class LandPhoneInProvinceRule extends CallChargeRule{ 255 256 @Override 257 public double calCost(ArrayList<CallRecord> callRecords) { 258 // TODO 自动生成的方法存根 259 double sum2 = 0; 260 for(CallRecord a:callRecords) { 261 sum2 = sum2 + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.3; 262 } 263 return sum2; 264 } 265 266 267 268 } 269 class User { 270 271 private UserRecords userRecords = new UserRecords(); 272 private double balance = 100; 273 private ChargeMode chargeMode; 274 private String number; 275 276 public User(String number, ChargeMode chargeMode) { 277 this.number = number; 278 this.chargeMode = chargeMode; 279 280 // TODO 自动生成的构造函数存根 281 } 282 283 public double calBalance() { 284 return (balance-calCost()-chargeMode.getMonthlyRent()); 285 } 286 287 public double calCost() { 288 return chargeMode.calCost(userRecords); 289 290 } 291 292 public UserRecords getUserRecords() { 293 return userRecords; 294 } 295 296 public void setUserRecords(UserRecords userRecords) { 297 this.userRecords = userRecords; 298 } 299 300 public double getBalance() { 301 return balance; 302 } 303 304 public void setBalance(double balance) { 305 this.balance = balance; 306 } 307 308 public ChargeMode getChargeMode() { 309 return chargeMode; 310 } 311 312 public void setChargeMode(ChargeMode chargeMode) { 313 this.chargeMode = chargeMode; 314 } 315 316 public String getNumber() { 317 return number; 318 } 319 320 public void setNumber(String number) { 321 this.number = number; 322 } 323 324 325 } 326 class UserRecords { 327 328 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 329 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 330 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); 331 332 public void addCallingInCityRecords(CallRecord callRecord) { 333 callingInCityRecords.add(callRecord); 334 } 335 336 public void addCallingInProvinceRecords(CallRecord callRecord) { 337 callingInProvinceRecords.add(callRecord); 338 } 339 340 public void addCallingInLandRecords(CallRecord callRecord) { 341 callingInLandRecords.add(callRecord); 342 } 343 344 public UserRecords() { 345 super(); 346 // TODO 自动生成的构造函数存根 347 } 348 349 public ArrayList<CallRecord> getCallingInCityRecords() { 350 return callingInCityRecords; 351 } 352 353 public ArrayList<CallRecord> getCallingInProvinceRecords() { 354 return callingInProvinceRecords; 355 } 356 357 public ArrayList<CallRecord> getCallingInLandRecords() { 358 return callingInLandRecords; 359 } 360 361 362 363 }
类图:


心得:真的特别难,光是看类图写代码都要累死了,这道题真的让我知道到了搞清类与类之间的关系是多么重要,因为题目给出的类图是分开的,我需要先根据给出的类图理解、并且掌握类与类之间的所有关系,其中还包括许多的抽象类。
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.util.Scanner; 2 import java.util.TreeMap; 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.ArrayList; 6 import java.util.Date; 7 8 public class Main { 9 10 public static void main(String[] args) { 11 // TODO 自动生成的方法存根 12 Scanner in = new Scanner(System.in); 13 TreeMap<String,User> userrecords = new TreeMap<String, User>(); 14 String check1 = "^u-0\\d{10,11}\\s0$"; 15 String check3 = "^u-1\\d{10}\\s1$"; 16 String check2 = "t-0(\\d){9,11}\\s0(\\d){9,11}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d"; 17 String check4 = "t-0(\\d){9,11}\\s1(\\d){10}\\s0(\\d){2,3}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}"; 18 String check5 = "t-1(\\d){10}\\s0(\\d){2,3}\\s0(\\d){9,11}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}"; 19 String check6 = "t-1(\\d){10}\\s0(\\d){2,3}\\s1(\\d){10}\\s0(\\d){2,3}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d"; 20 21 String a = in.nextLine(); 22 23 while(!a.equals("end")) { 24 if(a.matches(check1)) { 25 String[] s1 = a.split("-"); 26 String[] s2 = s1[1].split(" "); 27 String s3 = s2[0]; 28 ChargeMode chargeMode = new LandlinePhoneCharging(); 29 User user = new User(s3,chargeMode); 30 userrecords.put(s3, user); 31 32 } 33 34 if(a.matches(check3)) { 35 String[] s1 = a.split("-"); 36 String[] s2 = s1[1].split(" "); 37 String s3 = s2[0]; 38 ChargeMode chargeMode = new PhoneCharging(); 39 User user = new User(s3,chargeMode); 40 userrecords.put(s3, user); 41 42 } 43 44 if(a.matches(check2)) { 45 String[] a1 = a.split("-"); 46 String[] a2 = a1[1].split(" "); 47 String callingarea = a2[0].substring(0, 4); 48 String callingnumber = a2[0]; 49 String listeningnumber = a2[1]; 50 String listeningarea = a2[1].substring(0, 4); 51 String startTime = a2[2]+" "+a2[3]; 52 String endTime = a2[4]+" "+a2[5]; 53 Date startDate = new Date(); 54 Date endDate = new Date(); 55 56 SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 57 try { 58 startDate = format.parse(startTime); 59 endDate = format.parse(endTime); 60 } 61 catch (ParseException e) { 62 e.printStackTrace(); 63 } 64 65 CallRecord callRecord = new CallRecord(callingnumber,listeningnumber,callingarea,listeningarea,startDate,endDate); 66 67 if(listeningarea.equals("0791")) { 68 userrecords.get(callingnumber).getUserRecords().addCallingInCityRecords(callRecord); 69 } 70 else if((listeningarea.equals("0790")||listeningarea.equals("0792")||listeningarea.equals("0793")||listeningarea.equals("0794")||listeningarea.equals("0795")||listeningarea.equals("0796")||listeningarea.equals("0797")||listeningarea.equals("0798")||listeningarea.equals("0799")||listeningarea.equals("0701"))) { 71 userrecords.get(callingnumber).getUserRecords().addCallingInProvinceRecords(callRecord); 72 } 73 else { 74 userrecords.get(callingnumber).getUserRecords().addCallingInLandRecords(callRecord); 75 } 76 } 77 78 if(a.matches(check4)) { 79 String[] a1 = a.split("-"); 80 String[] a2 = a1[1].split(" "); 81 String callingarea = a2[0].substring(0, 4); 82 String callingnumber = a2[0]; 83 String listeningnumber = a2[1]; 84 String listeningarea = a2[2]; 85 String startTime = a2[3]+" "+a2[4]; 86 String endTime = a2[5]+" "+a2[6]; 87 Date startDate = new Date(); 88 Date endDate = new Date(); 89 90 SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 91 try { 92 startDate = format.parse(startTime); 93 endDate = format.parse(endTime); 94 } 95 catch (ParseException e) { 96 e.printStackTrace(); 97 } 98 99 CallRecord callRecord = new CallRecord(callingnumber,listeningnumber,callingarea,listeningarea,startDate,endDate); 100 if(listeningarea.equals("0791")) { 101 if(userrecords.get(callingnumber)!=null) { 102 userrecords.get(callingnumber).getUserRecords().addCallingInCityRecords(callRecord); 103 } 104 } 105 else if((listeningarea.equals("0790")||listeningarea.equals("0792")||listeningarea.equals("0793")||listeningarea.equals("0794")||listeningarea.equals("0795")||listeningarea.equals("0796")||listeningarea.equals("0797")||listeningarea.equals("0798")||listeningarea.equals("0799")||listeningarea.equals("0701"))) { 106 if(userrecords.get(callingnumber)!=null) { 107 userrecords.get(callingnumber).getUserRecords().addCallingInProvinceRecords(callRecord); 108 } 109 if(userrecords.get(listeningnumber)!=null) { 110 userrecords.get(listeningnumber).getUserRecords().addanswerInProvinceRecords(callRecord); 111 } 112 } 113 else { 114 if(userrecords.get(callingnumber)!=null) { 115 userrecords.get(callingnumber).getUserRecords().addCallingInLandRecords(callRecord); 116 } 117 if(userrecords.get(listeningnumber)!=null) { 118 userrecords.get(listeningnumber).getUserRecords().addanswerInLandRecords(callRecord); 119 } 120 } 121 } 122 123 if(a.matches(check5)) { 124 String[] a1 = a.split("-"); 125 String[] a2 = a1[1].split(" "); 126 String callingarea = a2[1]; 127 String callingnumber = a2[0]; 128 String listeningnumber = a2[2]; 129 String listeningarea = a2[2].substring(0,4); 130 String startTime = a2[3]+" "+a2[4]; 131 String endTime = a2[5]+" "+a2[6]; 132 Date startDate = new Date(); 133 Date endDate = new Date(); 134 135 136 SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 137 try { 138 startDate = format.parse(startTime); 139 endDate = format.parse(endTime); 140 } 141 catch (ParseException e) { 142 e.printStackTrace(); 143 } 144 145 CallRecord callRecord = new CallRecord(callingnumber,listeningnumber,callingarea,listeningarea,startDate,endDate); 146 147 if(listeningarea.equals("0791")) { 148 if(userrecords.get(callingnumber)!=null) { 149 userrecords.get(callingnumber).getUserRecords().addCallingInCityRecords(callRecord); 150 } 151 } 152 else if((listeningarea.equals("0790")||listeningarea.equals("0792")||listeningarea.equals("0793")||listeningarea.equals("0794")||listeningarea.equals("0795")||listeningarea.equals("0796")||listeningarea.equals("0797")||listeningarea.equals("0798")||listeningarea.equals("0799")||listeningarea.equals("0701"))) { 153 if(userrecords.get(callingnumber)!=null) { 154 userrecords.get(callingnumber).getUserRecords().addCallingInProvinceRecords(callRecord); 155 } 156 } 157 else { 158 if(userrecords.get(callingnumber)!=null) { 159 userrecords.get(callingnumber).getUserRecords().addCallingInLandRecords(callRecord); 160 } 161 } 162 } 163 164 if(a.matches(check6)) { 165 String[] a1 = a.split("-"); 166 String[] a2 = a1[1].split(" "); 167 String callingarea = a2[1]; 168 String callingnumber = a2[0]; 169 String listeningnumber = a2[2]; 170 String listeningarea = a2[3]; 171 String startTime = a2[4]+" "+a2[5]; 172 String endTime = a2[6]+" "+a2[7]; 173 Date startDate = new Date(); 174 Date endDate = new Date(); 175 176 SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 177 try { 178 startDate = format.parse(startTime); 179 endDate = format.parse(endTime); 180 } 181 catch (ParseException e) { 182 e.printStackTrace(); 183 } 184 185 CallRecord callRecord = new CallRecord(callingnumber,listeningnumber,callingarea,listeningarea,startDate,endDate); 186 if(listeningarea.equals("0791")) { 187 if(userrecords.get(callingnumber)!=null) { 188 userrecords.get(callingnumber).getUserRecords().addCallingInCityRecords(callRecord); 189 } 190 if(userrecords.get(listeningnumber)!=null) { 191 userrecords.get(listeningnumber).getUserRecords().addanswerInCityRecords(callRecord); 192 } 193 } 194 else if((listeningarea.equals("0790")||listeningarea.equals("0792")||listeningarea.equals("0793")||listeningarea.equals("0794")||listeningarea.equals("0795")||listeningarea.equals("0796")||listeningarea.equals("0797")||listeningarea.equals("0798")||listeningarea.equals("0799")||listeningarea.equals("0701"))) { 195 if(userrecords.get(callingnumber)!=null) { 196 userrecords.get(callingnumber).getUserRecords().addCallingInProvinceRecords(callRecord); 197 } 198 if(userrecords.get(listeningnumber)!=null) { 199 userrecords.get(listeningnumber).getUserRecords().addanswerInProvinceRecords(callRecord); 200 } 201 } 202 else { 203 if(userrecords.get(callingnumber)!=null) { 204 userrecords.get(callingnumber).getUserRecords().addCallingInLandRecords(callRecord); 205 } 206 if(userrecords.get(listeningnumber)!=null) { 207 userrecords.get(listeningnumber).getUserRecords().addanswerInLandRecords(callRecord); 208 } 209 } 210 } 211 212 a = in.nextLine(); 213 } 214 215 216 217 for(User user : userrecords.values()) { 218 System.out.println(user.getNumber()+" "+user.calCost()+" "+user.calBalance()); 219 } 220 221 } 222 223 } 224 225 226 227 228 229 class answerInLandRule extends CallChargeRule{ 230 @Override 231 public double calCost(ArrayList<CallRecord> callRecords) { 232 // TODO 自动生成的方法存根 233 double sum = 0; 234 for(CallRecord a:callRecords) { 235 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.3; 236 } 237 return sum; 238 } 239 240 } 241 class CallChargeRule extends ChargeRule{ 242 243 public double calCost(ArrayList<CallRecord> callRecords) { 244 return 0; 245 } 246 247 } 248 class CallRecord extends CommunicationRecord{ 249 250 private Date startTime; 251 private Date endTime; 252 private String callingAddressAreaCode; 253 private String answeringAddressAreaCode; 254 private String callingNumber; 255 private String answeringNumber; 256 257 public CallRecord(String callingNumber,String answeringNumber,String callingAddressAreaCode,String answeringAddressAreaCode,Date startTime,Date endTime) { 258 this.answeringAddressAreaCode = answeringAddressAreaCode; 259 this.callingAddressAreaCode = callingAddressAreaCode; 260 this.answeringNumber = answeringNumber; 261 this.callingNumber = callingNumber; 262 this.endTime = endTime; 263 this.startTime = startTime; 264 } 265 266 public Date getStartTime() { 267 return startTime; 268 } 269 270 public void setStartTime(Date startTime) { 271 this.startTime = startTime; 272 } 273 274 public Date getEndTime() { 275 return endTime; 276 } 277 278 public void setEndTime(Date endTime) { 279 this.endTime = endTime; 280 } 281 282 public String getCallingAddressAreaCode() { 283 return callingAddressAreaCode; 284 } 285 286 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 287 this.callingAddressAreaCode = callingAddressAreaCode; 288 } 289 290 public String getAnsweringAddressAreaCode() { 291 return answeringAddressAreaCode; 292 } 293 294 public void setAnsweringAddressAreaCode(String answeringAddressAreaCode) { 295 this.answeringAddressAreaCode = answeringAddressAreaCode; 296 } 297 298 public String getCallingNumber() { 299 return callingNumber; 300 } 301 302 public void setCallingNumber(String callingNumber) { 303 this.callingNumber = callingNumber; 304 } 305 306 public String getAnsweringNumber() { 307 return answeringNumber; 308 } 309 310 public void setAnsweringNumber(String answeringNumber) { 311 this.answeringNumber = answeringNumber; 312 } 313 314 315 316 } 317 class ChargeMode { 318 319 private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); 320 321 322 public ArrayList<ChargeRule> getChargeRules() { 323 return chargeRules; 324 } 325 326 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 327 this.chargeRules = chargeRules; 328 } 329 330 public double calCost(UserRecords userRecords) { 331 return 0; 332 } 333 334 public double getMonthlyRent() { 335 return 0; 336 } 337 338 } 339 abstract class ChargeRule { 340 341 public double calCost(ArrayList<CallRecord> callingInCityRecords) { 342 // TODO 自动生成的方法存根 343 return 0; 344 } 345 346 347 } 348 abstract class CommunicationRecord { 349 350 protected String callingNumber; 351 protected String answerNumber; 352 353 354 public String getCallingNumber() { 355 return callingNumber; 356 } 357 358 public void setCallingNumber(String callingNumber) { 359 this.callingNumber = callingNumber; 360 } 361 362 public String getAnswerNumber() { 363 return answerNumber; 364 } 365 366 public void setAnswerNumber(String answerNumber) { 367 this.answerNumber = answerNumber; 368 } 369 370 } 371 class LandlinePhoneCharging extends ChargeMode{ 372 373 private double monthlyRent = 20; 374 375 @Override 376 public double calCost(UserRecords userRecords) { 377 // TODO 自动生成的方法存根 378 double sum = 0,a,b,c; 379 380 getChargeRules().add(new LandPhoneInCityRule()); 381 getChargeRules().add(new LandPhoneInProvinceRule()); 382 getChargeRules().add(new LandPhoneInLandRule()); 383 384 a = super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()); 385 b = super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords()); 386 c = super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords()); 387 sum = a+b+c; 388 389 return sum; 390 } 391 392 @Override 393 public double getMonthlyRent() { 394 // TODO 自动生成的方法存根 395 return monthlyRent; 396 } 397 398 } 399 class LandPhoneInCityRule extends CallChargeRule{ 400 401 @Override 402 public double calCost(ArrayList<CallRecord> callRecords) { 403 // TODO 自动生成的方法存根 404 double sum3 = 0; 405 for(CallRecord a:callRecords) { 406 sum3 = sum3 + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.1; 407 } 408 return sum3; 409 } 410 411 412 413 } 414 class LandPhoneInLandRule extends CallChargeRule{ 415 416 @Override 417 public double calCost(ArrayList<CallRecord> callRecords) { 418 // TODO 自动生成的方法存根 419 double sum1 = 0; 420 for(CallRecord a:callRecords) { 421 sum1=sum1+Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.6; 422 } 423 return sum1; 424 } 425 426 427 428 } 429 class LandPhoneInProvinceRule extends CallChargeRule{ 430 431 @Override 432 public double calCost(ArrayList<CallRecord> callRecords) { 433 // TODO 自动生成的方法存根 434 double sum2 = 0; 435 for(CallRecord a:callRecords) { 436 sum2 = sum2 + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.3; 437 } 438 return sum2; 439 } 440 441 442 443 } 444 class PhoneCharging extends ChargeMode{ 445 private double monthlyRent = 15; 446 447 @Override 448 public double calCost(UserRecords userRecords) { 449 // TODO 自动生成的方法存根 450 double sum = 0,a,b,c,d; 451 452 getChargeRules().add(new PhoneInCityRule()); 453 getChargeRules().add(new PhoneInProvinceRule()); 454 getChargeRules().add(new PhoneInLandRule()); 455 getChargeRules().add(new answerInLandRule()); 456 457 a = super.getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()); 458 b = super.getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords()); 459 c = super.getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords()); 460 d = super.getChargeRules().get(3).calCost(userRecords.getAnswerInLandRecords()); 461 sum = a+b+c+d; 462 463 return sum; 464 } 465 466 @Override 467 public double getMonthlyRent() { 468 // TODO 自动生成的方法存根 469 return monthlyRent; 470 } 471 472 } 473 class PhoneInCityRule extends CallChargeRule{ 474 @Override 475 public double calCost(ArrayList<CallRecord> callRecords) { 476 // TODO 自动生成的方法存根 477 double sum = 0; 478 479 for(CallRecord a:callRecords) { 480 if(a.getCallingAddressAreaCode().equals("0791")) { 481 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.1; 482 } 483 else if(a.getCallingAddressAreaCode().equals("0790")||a.getCallingAddressAreaCode().equals("0792")||a.getCallingAddressAreaCode().equals("0793")||a.getCallingAddressAreaCode().equals("0794")||a.getCallingAddressAreaCode().equals("0795")||a.getCallingAddressAreaCode().equals("0796")||a.getCallingAddressAreaCode().equals("0797")||a.getCallingAddressAreaCode().equals("0798")||a.getCallingAddressAreaCode().equals("0799")||a.getCallingAddressAreaCode().equals("0701")) { 484 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.3; 485 } 486 else { 487 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.6; 488 } 489 490 } 491 return sum; 492 } 493 494 } 495 class PhoneInLandRule extends CallChargeRule{ 496 @Override 497 public double calCost(ArrayList<CallRecord> callRecords) { 498 // TODO 自动生成的方法存根 499 double sum = 0; 500 for(CallRecord a:callRecords) { 501 if(a.getCallingAddressAreaCode().equals("0791")) { 502 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.3; 503 } 504 else if(a.getCallingAddressAreaCode().equals("0790")||a.getCallingAddressAreaCode().equals("0792")||a.getCallingAddressAreaCode().equals("0793")||a.getCallingAddressAreaCode().equals("0794")||a.getCallingAddressAreaCode().equals("0795")||a.getCallingAddressAreaCode().equals("0796")||a.getCallingAddressAreaCode().equals("0797")||a.getCallingAddressAreaCode().equals("0798")||a.getCallingAddressAreaCode().equals("0799")||a.getCallingAddressAreaCode().equals("0701")) { 505 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.3; 506 } 507 else { 508 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.6; 509 } 510 511 } 512 return sum; 513 } 514 515 } 516 class PhoneInProvinceRule extends CallChargeRule{ 517 @Override 518 public double calCost(ArrayList<CallRecord> callRecords) { 519 // TODO 自动生成的方法存根 520 double sum = 0; 521 for(CallRecord a:callRecords) { 522 if(a.getCallingAddressAreaCode().equals("0791")) { 523 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.2; 524 } 525 else if(a.getCallingAddressAreaCode().equals("0790")||a.getCallingAddressAreaCode().equals("0792")||a.getCallingAddressAreaCode().equals("0793")||a.getCallingAddressAreaCode().equals("0794")||a.getCallingAddressAreaCode().equals("0795")||a.getCallingAddressAreaCode().equals("0796")||a.getCallingAddressAreaCode().equals("0797")||a.getCallingAddressAreaCode().equals("0798")||a.getCallingAddressAreaCode().equals("0799")||a.getCallingAddressAreaCode().equals("0701")) { 526 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.3; 527 } 528 else { 529 sum = sum + Math.ceil((a.getEndTime().getTime()-a.getStartTime().getTime())/60000.0)*0.6; 530 } 531 532 } 533 return sum; 534 } 535 536 } 537 class User { 538 539 private UserRecords userRecords = new UserRecords(); 540 private double balance = 100; 541 private ChargeMode chargeMode; 542 private String number; 543 544 public User(String number, ChargeMode chargeMode) { 545 this.number = number; 546 this.chargeMode = chargeMode; 547 548 // TODO 自动生成的构造函数存根 549 } 550 551 public double calBalance() { 552 return (balance-calCost()-chargeMode.getMonthlyRent()); 553 } 554 555 public double calCost() { 556 return chargeMode.calCost(userRecords); 557 558 } 559 560 public UserRecords getUserRecords() { 561 return userRecords; 562 } 563 564 public void setUserRecords(UserRecords userRecords) { 565 this.userRecords = userRecords; 566 } 567 568 public double getBalance() { 569 return balance; 570 } 571 572 public void setBalance(double balance) { 573 this.balance = balance; 574 } 575 576 public ChargeMode getChargeMode() { 577 return chargeMode; 578 } 579 580 public void setChargeMode(ChargeMode chargeMode) { 581 this.chargeMode = chargeMode; 582 } 583 584 public String getNumber() { 585 return number; 586 } 587 588 public void setNumber(String number) { 589 this.number = number; 590 } 591 592 593 } 594 class UserRecords { 595 596 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); 597 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); 598 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>(); 599 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>(); 600 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>(); 601 private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>(); 602 603 604 605 public void addCallingInCityRecords(CallRecord callRecord) { 606 callingInCityRecords.add(callRecord); 607 } 608 609 public void addCallingInProvinceRecords(CallRecord callRecord) { 610 callingInProvinceRecords.add(callRecord); 611 } 612 613 public void addCallingInLandRecords(CallRecord callRecord) { 614 callingInLandRecords.add(callRecord); 615 } 616 617 public void addanswerInCityRecords(CallRecord callRecord) { 618 answerInCityRecords.add(callRecord); 619 } 620 621 public void addanswerInProvinceRecords(CallRecord callRecord) { 622 answerInProvinceRecords.add(callRecord); 623 } 624 625 public void addanswerInLandRecords(CallRecord callRecord) { 626 answerInLandRecords.add(callRecord); 627 } 628 629 630 public UserRecords() { 631 super(); 632 // TODO 自动生成的构造函数存根 633 } 634 635 public ArrayList<CallRecord> getCallingInCityRecords() { 636 return callingInCityRecords; 637 } 638 639 public ArrayList<CallRecord> getCallingInProvinceRecords() { 640 return callingInProvinceRecords; 641 } 642 643 public ArrayList<CallRecord> getCallingInLandRecords() { 644 return callingInLandRecords; 645 } 646 647 public ArrayList<CallRecord> getAnswerInCityRecords() { 648 return answerInCityRecords; 649 } 650 651 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 652 return answerInProvinceRecords; 653 } 654 655 public ArrayList<CallRecord> getAnswerInLandRecords() { 656 return answerInLandRecords; 657 } 658 659 660 661 }
类图:



心得:由于第一次是座机与座机间的交流,所以不需要考虑打电话的座机的位置,但是本次作业包括了手机的套餐,还需要考虑手机的所在地,并且手机接听电话也有收费的情况,所以需要添加许多东西到计费规则上去,而这也导致了正则表达式的改变。
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.util.Scanner; 2 import java.util.TreeMap; 3 import java.util.ArrayList; 4 5 6 public class Main { 7 8 public static void main(String[] args) { 9 // TODO 自动生成的方法存根 10 Scanner in = new Scanner(System.in); 11 TreeMap<String,User> userrecords = new TreeMap<String, User>(); 12 String check1 = "^u-1\\d{10}\\s3$"; 13 String check2 = "m-1(\\d){10}\\s1(\\d){10}\\s[A-Za-z0-9,. ]{1,}"; 14 String a = in.nextLine(); 15 while(!a.equals("end")) { 16 if(a.matches(check1)) { 17 String[] s1 = a.split("-"); 18 String[] s2 = s1[1].split(" "); 19 String s3 = s2[0]; 20 ChargeMode chargeMode = new MessageCharging(); 21 User user = new User(s3,chargeMode); 22 userrecords.put(s3, user); 23 } 24 25 if(a.matches(check2)) { 26 String[] a1 = a.split("-"); 27 String[] a2 = a1[1].split(" "); 28 String callingnumber = a2[0]; 29 String message = a1[1].substring(24); 30 31 32 MessageRecord messageRecord = new MessageRecord(message); 33 34 if(userrecords.get(callingnumber)!=null) { 35 userrecords.get(callingnumber).getUserRecords().addSendMessageRecords(messageRecord);; 36 } 37 } 38 39 a = in.nextLine(); 40 } 41 42 43 44 for(User user : userrecords.values()) { 45 System.out.println(String.format("%s",user.getNumber())+" "+String.format("%.1f",user.calCost())+" "+user.calBalance()); 46 } 47 48 } 49 50 } 51 class UserRecords { 52 53 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); 54 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); 55 56 57 public void addSendMessageRecords(MessageRecord sendMessageRecord) { 58 sendMessageRecords.add(sendMessageRecord); 59 } 60 61 public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) { 62 receiveMessageRecords.add(receiveMessageRecord); 63 } 64 65 public ArrayList<MessageRecord> getSendMessageRecords() { 66 return sendMessageRecords; 67 } 68 69 public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) { 70 this.sendMessageRecords = sendMessageRecords; 71 } 72 73 public ArrayList<MessageRecord> getReceiveMessageRecords() { 74 return receiveMessageRecords; 75 } 76 77 public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) { 78 this.receiveMessageRecords = receiveMessageRecords; 79 } 80 81 public UserRecords() { 82 super(); 83 // TODO 自动生成的构造函数存根 84 } 85 86 87 88 89 90 } 91 class User { 92 93 private UserRecords userRecords = new UserRecords(); 94 private double balance = 100; 95 private ChargeMode chargeMode; 96 private String number; 97 98 public User(String number, ChargeMode chargeMode) { 99 this.number = number; 100 this.chargeMode = chargeMode; 101 102 // TODO 自动生成的构造函数存根 103 } 104 105 public double calBalance() { 106 return (balance-calCost()); 107 } 108 109 public double calCost() { 110 return chargeMode.calCost(userRecords); 111 112 } 113 114 public UserRecords getUserRecords() { 115 return userRecords; 116 } 117 118 public void setUserRecords(UserRecords userRecords) { 119 this.userRecords = userRecords; 120 } 121 122 public double getBalance() { 123 return balance; 124 } 125 126 public void setBalance(double balance) { 127 this.balance = balance; 128 } 129 130 public ChargeMode getChargeMode() { 131 return chargeMode; 132 } 133 134 public void setChargeMode(ChargeMode chargeMode) { 135 this.chargeMode = chargeMode; 136 } 137 138 public String getNumber() { 139 return number; 140 } 141 142 public void setNumber(String number) { 143 this.number = number; 144 } 145 146 147 } 148 abstract class ChargeMode { 149 150 private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); 151 152 153 public ArrayList<ChargeRule> getChargeRules() { 154 return chargeRules; 155 } 156 157 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 158 this.chargeRules = chargeRules; 159 } 160 161 public double calCost(UserRecords userRecords) { 162 return 0; 163 } 164 165 public double getMonthlyRent() { 166 return 0; 167 } 168 169 } 170 abstract class ChargeRule { 171 172 protected abstract double calCost(ArrayList<MessageRecord> sendMessageRecords); 173 174 175 176 } 177 abstract class CommunicationRecord { 178 179 protected String callingNumber; 180 protected String answerNumber; 181 182 183 public String getCallingNumber() { 184 return callingNumber; 185 } 186 187 public void setCallingNumber(String callingNumber) { 188 this.callingNumber = callingNumber; 189 } 190 191 public String getAnswerNumber() { 192 return answerNumber; 193 } 194 195 public void setAnswerNumber(String answerNumber) { 196 this.answerNumber = answerNumber; 197 } 198 199 } 200 abstract class MessageChargeRule extends ChargeRule { 201 202 203 public double calCost(ArrayList<MessageRecord> sendmessageRecords) { 204 // TODO 自动生成的方法存根 205 return 0; 206 } 207 208 209 } 210 class MessageCharging extends ChargeMode{ 211 212 @Override 213 public double calCost(UserRecords userRecords) { 214 double sum = 0; 215 216 getChargeRules().add(new SendMessageRule()); 217 218 sum = super.getChargeRules().get(0).calCost(userRecords.getSendMessageRecords()); 219 220 return sum; 221 } 222 223 } 224 class MessageRecord extends CommunicationRecord{ 225 226 private String message; 227 228 public MessageRecord(String message) { 229 this.message = message; 230 } 231 232 public String getMessage() { 233 return message; 234 } 235 236 public void setMessage(String message) { 237 this.message = message; 238 } 239 240 } 241 class SendMessageRule extends MessageChargeRule{ 242 243 @Override 244 public double calCost(ArrayList<MessageRecord> messageRecords) { 245 // TODO 自动生成的方法存根 246 double sum = 0,b ,n=0; 247 for(MessageRecord a:messageRecords) { 248 b=Math.ceil(a.getMessage().length()/10.0); 249 n=n+b; 250 } 251 if(n<=3) { 252 sum = n*0.1; 253 } 254 if(n>3&&n<=5) { 255 sum = 0.3+(n-3)*0.2; 256 } 257 if(n>5) { 258 sum = 0.7+(n-5)*0.3; 259 } 260 261 return sum; 262 } 263 264 }
类图:



总结:
经过这几次作业,我深刻理解了面向对象设计的优势和方法。对于类的使用也有了更深一步的理解,能够帮助我在编程这条路上走远走长久。对于Java的学习也有了更进一步的了解。同时,我也自主学习了部分算法以及数据结构,这对于我编程能力的提升是巨大的,今后我也会进一步的学习,并将所学运用到平时的作业,刷题中去,以巩固知识,提升自己的能力,这几次的作业让我深刻的理解到了这些知识,使我受益良多。

浙公网安备 33010602011771号