加载中...

第三次博客作业

一.前言

1.知识点总结

<1>电信系列的座机,电话,短信计费系列

  考查的知识点为:

  类设计的搭建与实现
  SimpleDateFormat类实现输入,以及时间格式化处理
  对不同通话记录的输入进行判断以及反应,通过正则表达式判断输入是否合法
  类的封装、继承、多态、接口、抽象类的使用
  集合框架,以及重写Collection的方法等
  个人认为难点在于:

  对不同种通话记录的添加以及详情计费方式
  对于输入的通话记录,用正则表达式验证
  非法输入情况的考虑,如用户是否出现重复,以及存在,如国内漫游接听也要收费
  Collection里自己重写Comparator,学要了解源码,进行改进,改成需要的顺序
  后期测试点太难过了

<2>PTA6—多态测试

要求模拟一个容器类层次结构,考察接口、重写抽象方法、和多态机制等知识点,在已有代码基础上增添,比较简单


<3>PTA7—删除集合元素—修改班级成员信息

对集合里元素的更改,主要考察它的遍历和删减重复元素,比较简单


<4>PTA7—添加元素到集合里—有序存储员工信息

考察集合包内的方法的使用


<5>PTA8—编写一个Shop(商店)、内部类InnerCoupons(内部购物券)

类的组合,继承,设计


<6>PTA8—设计一个动物发生模拟器

类的设计与方法实现
多态的使用


2.题量与难度评估

近三次作业题量适中,题目较之前的习题集难度减小,题目很巧妙,也很较符合实际生活

二.设计与分析

6_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、2、3,可根据理解自行调整:

                                    图1
图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。

ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。

UserRecords是用户记录类,保存用户各种通话、短信的记录,    
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。

  

                                     图2
图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。

CallRecord(通话记录类)包含属性:
通话的起始、结束时间以及
拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。
区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。

  

                                        图3
图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList<CallRecord> callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。

LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是
座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。    
(提示:可以从UserRecords类中获取各种类型的callRecords)。

  

后续扩展说明:
后续题目集将增加手机用户,手机用户的计费方式中除了与座机计费类似的主叫通话费之外,还包含市外接听电话的漫游费以及发短信的费用。在本题的设计时可统一考虑。
通话记录中,手机需要额外记录拨打/接听的地点的区号,比如:
座机打手机: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
短信的格式:m-主叫号码,接收号码,短信内容
m-18907910010 13305862264 welcome to jiangxi
m-13305862264 18907910010 thank you

输入样例:
在这里给出一组输入。例如:

u-079186300001 0
t-079186300001 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:25
end

  

输出样例:
在这里给出相应的输出。例如:

079186300001 3.0 77.0

代码:

  1 import java.text.DecimalFormat;
  2 import java.text.ParseException;
  3 import java.text.SimpleDateFormat;
  4 import java.util.*;
  5 
  6 public class Main {
  7     public static void main(String[] args) {
  8         Scanner input = new Scanner(System.in);
  9         ArrayList<Users> usersArrayList = new ArrayList<>();
 10         String str = input.nextLine();
 11         boolean repetition = false;
 12         while (!str.equals("end")){
 13             if(str.matches("u\\-0791\\d{7,8}\\s0")){
 14                 String str1[] = str.split("-");
 15                 String str2[] = str1[1].split(" ");
 16                 for(int i = 0;i < usersArrayList.size();i++){
 17                     if(usersArrayList.get(i).number.equals(str2[0])) {
 18                         repetition = true;
 19                         break;
 20                     }
 21                 }
 22                 if(repetition == false){
 23                     usersArrayList.add(new Users(str2[0]));
 24                 }
 25             }
 26             if(str.matches("t-(\\d){11,12}\\s(\\d){10,12}\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\s((((1[6-9]|[2-9]\\d)\\d{2}).([13578]|1[02]).([1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2}).([13456789]|1[012]).([1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-2-([1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-2-29-)) (20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d")){
 27                 String str3[] = str.split("-");
 28                 String str4[] = str3[1].split(" ");
 29                 for (int i = 0;i < usersArrayList.size();i++){
 30                     if(usersArrayList.get(i).number.equals(str4[0])){
 31                         if(str4[1].substring(0,4).matches("0791")){
 32                             usersArrayList.get(i).getUserRecords().addgetCallingInCityRecords(new CallRecord(str4[2]+" "+str4[3],str4[4]+" "+str4[5]));
 33                             usersArrayList.get(i).setUserRecords(usersArrayList.get(i).getUserRecords());
 34                         }
 35                         else if(str4[1].substring(0,4).matches("079\\d|0701")){
 36                             usersArrayList.get(i).getUserRecords().addgetCallingInProvinceRecords(new CallRecord(str4[2]+" "+str4[3],str4[4]+" "+str4[5]));
 37                             usersArrayList.get(i).setUserRecords(usersArrayList.get(i).getUserRecords());
 38                         }
 39                         else
 40                             usersArrayList.get(i).getUserRecords().addgetCallingInLandRecords(new CallRecord(str4[2]+" "+str4[3],str4[4]+" "+str4[5]));
 41                             usersArrayList.get(i).setUserRecords(usersArrayList.get(i).getUserRecords());
 42                     }
 43                 }
 44             }
 45             str = input.nextLine();
 46         }
 47 
 48         Collections.sort(usersArrayList,new Comparator<Users>() {
 49             @Override
 50             public int compare(Users o1, Users o2) {
 51                 return o1.getNumber().compareTo(o2.getNumber());
 52             }
 53         });
 54         for(int i = 0;i<usersArrayList.size();i++){
 55             System.out.print(usersArrayList.get(i).number+" ");
 56             System.out.print(new DecimalFormat("0.0#").format(usersArrayList.get(i).calCost())+" ");
 57             System.out.print(new DecimalFormat("0.0#").format(usersArrayList.get(i).getBalance()-usersArrayList.get(i).calCost()-20));
 58             System.out.println();
 59         }
 60     }
 61 }
 62 
 63 class Users{
 64     private UserRecords userRecords = new UserRecords();
 65     double balance = 100;
 66     String number;
 67     ChargeMode chargeMode;
 68 
 69     public Users(String number) {
 70         this.number = number;
 71     }
 72 
 73     public double CalBalance(){
 74         return 0;
 75     }
 76 
 77     public double calCost(){
 78         LandPhoneInCityRule landPhoneInCityRule = new LandPhoneInCityRule();
 79         LandPhoneInLandRule landPhoneInLandRule = new LandPhoneInLandRule();
 80         LandPhoneInProvinceRule landPhoneInProvinceRule = new LandPhoneInProvinceRule();
 81         return landPhoneInLandRule.calCost(userRecords.getCallingInLandRecords())+landPhoneInCityRule.calCost(userRecords.getCallingInCityRecords())+landPhoneInProvinceRule.calCost(userRecords.getCallingInProvinceRecords());
 82     }
 83 
 84     public UserRecords getUserRecords() {
 85         return userRecords;
 86     }
 87 
 88     public void setUserRecords(UserRecords userRecords) {
 89         this.userRecords = userRecords;
 90     }
 91 
 92     public double getBalance() {
 93         return balance;
 94     }
 95 
 96     public String getNumber() {
 97         return number;
 98     }
 99 
100     public void setNumber(String number) {
101         this.number = number;
102     }
103 
104     public ChargeMode getChargeMode() {
105         return chargeMode;
106     }
107 
108     public void setChargeMode(ChargeMode chargeMode) {
109         this.chargeMode = chargeMode;
110     }
111 
112 }
113 
114 class UserRecords{
115     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
116     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
117     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
118     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
119     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
120     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
121     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
122     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
123 
124     public ArrayList<CallRecord> getCallingInCityRecords() {
125         return callingInCityRecords;
126     }
127 
128     public ArrayList<CallRecord> getCallingInProvinceRecords() {
129         return callingInProvinceRecords;
130     }
131 
132     public ArrayList<CallRecord> getCallingInLandRecords() {
133         return callingInLandRecords;
134     }
135 
136     public ArrayList<CallRecord> getAnswerInCityRecords() {
137         return answerInCityRecords;
138     }
139 
140     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
141         return answerInProvinceRecords;
142     }
143 
144     public ArrayList<CallRecord> getAnswerInLandRecords() {
145         return answerInLandRecords;
146     }
147 
148     public ArrayList<MessageRecord> getSendMessageRecords() {
149         return sendMessageRecords;
150     }
151 
152     public ArrayList<MessageRecord> getReceiveMessageRecords() {
153         return receiveMessageRecords;
154     }
155 
156     public void addgetCallingInCityRecords(CallRecord callRecord){
157         getCallingInCityRecords().add(callRecord);
158     }
159 
160     public void addgetCallingInProvinceRecords(CallRecord callRecord){
161         getCallingInProvinceRecords().add(callRecord);
162     }
163 
164     public void addgetCallingInLandRecords(CallRecord callRecord){
165         getCallingInLandRecords().add(callRecord);
166     }
167 
168     public void addAnswerInCityRecords(CallRecord answerRecord){
169         answerInCityRecords.add(answerRecord);
170     }
171 
172     public void addAnswerInProvinceRecords(CallRecord answerRecord){
173         answerInProvinceRecords.add(answerRecord);
174     }
175 
176     public void addAnswerInLandRecords(CallRecord answerRecord){
177         answerInLandRecords.add(answerRecord);
178     }
179 
180     public void addSendMessageRecords(MessageRecord sendMessageRecord){
181         sendMessageRecords.add(sendMessageRecord);
182     }
183 
184     public void addReceiveMessageRecords(MessageRecord receiveMessageRecord){
185         receiveMessageRecords.add(receiveMessageRecord);
186     }
187 }
188 
189 abstract class ChargeMode{
190     private ArrayList<ChargeRule> chargeRules = new ArrayList<>();
191 
192     public ArrayList<ChargeRule> getChargeRules() {
193         return chargeRules;
194     }
195 
196     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
197         this.chargeRules = chargeRules;
198     }
199 
200     public double calCost(UserRecords userRecords){
201         return 0;
202     }
203 
204     public double getMonthlyRent(){
205 
206         return 20;
207     }
208 }
209 
210 class LandlinePhoneCharging extends ChargeMode{
211     private double monthlyRent = 20;
212 
213     @Override
214     public double calCost(UserRecords userRecords) {
215         return 0;
216     }
217 
218     @Override
219     public double getMonthlyRent() {
220         return monthlyRent;
221     }
222 }
223 
224 abstract class CommunicationRecord{
225     protected String callingNumber;
226     protected String answerNumber;
227 
228     public String getCallingNumber() {
229         return callingNumber;
230     }
231 
232     public void setCallingNumber(String callingNumber) {
233 
234         this.callingNumber = callingNumber;
235     }
236 
237     public String getAnswerNumber() {
238         return answerNumber;
239     }
240 
241     public void setAnswerNumber(String answerNumber) {
242         this.answerNumber = answerNumber;
243     }
244 }
245 
246 class CallRecord extends CommunicationRecord{
247     private Date startTime;
248     private Date endTime;
249     private String callingAddressAreaCode;
250     private String answerAddressAreaCode;
251 
252     public CallRecord(String startTime, String endTime)  {
253         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
254         try {
255             this.startTime = simpleDateFormat.parse(startTime);
256         } catch (ParseException e) {
257             e.printStackTrace();
258         }
259         try {
260             this.endTime = simpleDateFormat.parse(endTime);
261         } catch (ParseException e) {
262             e.printStackTrace();
263         }
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 String getCallingAddressAreaCode() {
275         return callingAddressAreaCode;
276     }
277 
278     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
279         this.callingAddressAreaCode = callingAddressAreaCode;
280     }
281 
282     public Date getEndTime() {
283         return endTime;
284     }
285 
286     public void setEndTime(Date endTime) {
287         this.endTime = endTime;
288     }
289 
290     public String getAnswerAddressAreaCode() {
291         return answerAddressAreaCode;
292     }
293 
294     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
295         this.answerAddressAreaCode = answerAddressAreaCode;
296     }
297 }
298 
299 class MessageRecord extends CommunicationRecord{
300     private String message;
301 
302     public String getMessage() {
303         return message;
304     }
305 
306     public void setMessage(String message) {
307         this.message = message;
308     }
309 }
310 
311 abstract class ChargeRule{
312 
313 }
314 
315 abstract class CallChargeRule extends ChargeRule{
316     public double calCost(ArrayList<CallRecord> callRecords){
317 
318         return 0;
319     }
320 }
321 
322 class LandPhoneInCityRule extends CallChargeRule{
323     @Override
324     public double calCost(ArrayList<CallRecord> callRecords) {
325         double cost = 0;
326         double minutes;
327         for(CallRecord e:callRecords){
328             long diff = e.getEndTime().getTime() - e.getStartTime().getTime();
329             minutes = (int) Math.ceil((double) diff / (double) 60000);
330             cost += 0.1*minutes;
331         }
332         return cost;
333     }
334 }
335 
336 class LandPhoneInLandRule extends CallChargeRule{
337     @Override
338     public double calCost(ArrayList<CallRecord> callRecords) {
339         double cost = 0;
340         double minutes;
341         for(CallRecord e:callRecords){
342             long diff = e.getEndTime().getTime() - e.getStartTime().getTime();
343             minutes = (int) Math.ceil((double) diff / (double) 60000);
344             cost += 0.6*minutes;
345         }
346         return cost;
347     }
348 }
349 
350 class LandPhoneInProvinceRule extends CallChargeRule{
351     @Override
352     public double calCost(ArrayList<CallRecord> callRecords) {
353         double cost = 0;
354         double minutes;
355         for(CallRecord e:callRecords){
356             long diff = e.getEndTime().getTime() - e.getStartTime().getTime();
357             minutes = (int) Math.ceil((double) diff / (double) 60000);
358             cost += 0.3*minutes;
359         }
360         return cost;
361     }
362 }
View Code

 

分析:

  对待非法输入时候时长没耐心琢磨,心静不下来导致的有些函数拼写错误及大小写搞混,由提交列表就可以看出本人代码急于求成,缺少实际经验的同时强调写作业效率,加上打字速度本来就慢,这导致函数常常出现拼写错误也多亏了编译器的报错,标红,让我一次次的修改,一次次的订正,一次次的反思,一次次的迭代,这告诫了我们要编程过程中要脚踏实地,宁愿降低自己的效率也要提高代码的可读性,降低代码的耦合性,让别人好找,自己好查代码存在的漏洞以及迭代的方法内容。

6_2.多态测试

定义容器Container接口。模拟实现一个容器类层次结构,并进行接口的实现、抽象方法重写和多态机制测试。各容器类实现求表面积、体积的方法。

定义接口Container:
属性:
public static final double pi=3.1415926;
抽象方法:
public abstract double area();
public abstract double volume();
static double sumofArea(Container c[]);
static double sumofVolume(Container c[]);
其中两个静态方法分别计算返回容器数组中所有对象的面积之和、周长之和;
定义Cube类、Cylinder类均实现自Container接口。
Cube类(属性:边长double类型)、Cylinder类(属性:底圆半径、高,double类型)。
输入格式:
第一行n表示对象个数,对象类型用cube、cylinder区分,cube表示立方体对象,后面输入边长,输入cylinder表示圆柱体对象,后面是底圆半径、高。

输出格式:
分别输出所有容器对象的表面积之和、体积之和,结果保留小数点后2位。

输入样例:
在这里给出一组输入。例如:

4
cube
15.7
cylinder
23.5 100
cube
46.8
cylinder
17.5 200

  

输出样例:
在这里给出相应的输出。例如:

56771.13
472290.12

代码:

  1 import java.util.Scanner;
  2 public class Main {
  3     public static void main(String[] args) {
  4                /* 4
  5                 cube
  6                 15.7
  7                 cylinder
  8                 23.5 100
  9                 cube
 10                 46.8
 11                 cylinder
 12                 17.5 200*/
 13         Scanner input = new Scanner(System.in);
 14         int n = input.nextInt();
 15         Shape3d[] arr = new Shape3d[n];
 16         for (int i = 0; i < arr.length; i++) {
 17             String str = input.next();
 18             if(str.equals("cube")){
 19                 arr[i] = new Cube(input.nextDouble());
 20             }else if(str.equals("cylinder")){
 21                 arr[i] = new Cylinder(input.nextDouble(),input.nextDouble());
 22             }
 23         }
 24         double sum1 = 0;//总表面积初始化
 25         double sum2 = 0;//总体积初始化
 26         for (Shape3d i:arr) {
 27             sum1 += i.area();
 28             sum2 += i.volume();
 29         }
 30         double sumS = (double) Math.round(sum1 * 100) / 100;
 31         double sumV = (double) Math.round(sum2* 100) / 100;
 32         System.out.println(sumS);
 33         System.out.println(sumV);
 34 
 35     }
 36 }
 37 
 38 interface Container {
 39     //属性
 40     public static final double pi=3.1415926;
 41     //方法
 42     public abstract double area();//求表面积
 43     public abstract double volume();//求体积
 44 
 45     static double sumofArea(Container c[]) {
 46         double sum = 0;
 47         for (Container i:c) {
 48             sum += i.area();
 49         }
 50         return sum;
 51     }
 52 
 53     static double sumofVolume(Container c[]) {
 54         double sum = 0;
 55         for (Container i:c) {
 56             sum += i.volume();
 57         }
 58         return sum;
 59     }
 60 }
 61 
 62 abstract class Shape3d implements Container{
 63     @Override
 64     public abstract double area();//求立体图形表面积
 65 
 66 
 67 
 68     @Override
 69     public abstract double volume();//求立体图形体积
 70 }
 71 
 72 class Cube extends Shape3d{//立方体,也就是正方体
 73     //属性:正方体的边长
 74     private double a;
 75 
 76     public Cube() {
 77     }
 78 
 79     public Cube(double a) {
 80         this.a = a;
 81     }
 82 
 83     public double getA() {
 84         return a;
 85     }
 86 
 87     public void setA(double a) {
 88         this.a = a;
 89     }
 90 
 91     @Override
 92     public double area() {//正方体表面积
 93         return 6*a*a;
 94     }
 95 
 96     @Override
 97     public double volume() {//正方体体积
 98         return a*a*a;
 99     }
100 }
101 
102 
103 class Cylinder extends Shape3d{//圆柱体
104     //半径和高
105     private double r,h;
106 
107     public Cylinder() {
108     }
109 
110     public Cylinder(double r, double h) {
111         this.r = r;
112         this.h = h;
113     }
114 
115     public double getR() {
116         return r;
117     }
118 
119     public void setR(double r) {
120         this.r = r;
121     }
122 
123     public double getH() {
124         return h;
125     }
126 
127     public void setH(double h) {
128         this.h = h;
129     }
130 
131     @Override
132     public double area() {//表面积,两个圆面积加一个侧面面积
133         return 2*pi*r*r + 2*pi*r*h;
134     }
135 
136     @Override
137     public double volume() {//体积,圆面积乘高
138         return pi*r*r*h;
139     }
140 
141 }
View Code

 

分析:

  这题主要是对继承,多态,接口等知识的掌握,懂相关的知识并且按照题目的要求去写还是比较简单的。

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元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。

本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。

  

建议类图:
参见图1、2、3:

图1

图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。
ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。
UserRecords是用户记录类,保存用户各种通话、短信的记录,    
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。

  

图2

图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。CallRecord(通话记录类)包含属性:
通话的起始、结束时间以及
拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。
区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。

  

图3

图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList<CallRecord> callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。
SendMessageRule是发送短信的计费规则类,用于计算发送短信的费用。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。    

  

(提示:可以从UserRecords类中获取各种类型的callRecords)。
注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。

输入样例:
在这里给出一组输入。例如:

u-13811111111 1
t-13811111111 0791 13811111110 020 2022.1.3 08:00:00 2022.1.3 08:09:20
end

  

输出样例:
在这里给出相应的输出。例如:

13811111111 3.0 82.0

 

代码:

  1 import java.util.ArrayList;
  2 import java.util.Comparator;
  3 import java.util.Scanner;
  4 import java.util.regex.Matcher;
  5 import java.util.regex.Pattern;
  6 import java.math.BigDecimal;
  7 import java.text.SimpleDateFormat;
  8 import java.util.Date;
  9 import java.util.Locale;
 10 import java.text.ParseException;
 11 
 12 public class Main {
 13 
 14 public static void main(String[] args) {
 15 
 16 Outputtool outputtool = new Outputtool();
 17 
 18 Inputdeal inputdeal = new Inputdeal();
 19 
 20 ArrayList<User> users = new ArrayList<>();
 21 
 22 Scanner in = new Scanner(System.in);
 23 
 24 String input = in.nextLine();
 25 
 26 while (!input.equals("end")) {
 27 if (1 == inputdeal.check(input)) {
 28 inputdeal.writeUser(users, input);
 29 } else if (2 == inputdeal.check(input)) {
 30 inputdeal.writeRecord(users, input);
 31 }
 32 input = in.nextLine();
 33 }
 34 
 35 users.sort(new Comparator<User>() {
 36 
 37 @Override
 38 public int compare(User u1, User u2) {
 39 if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') {
 40 return -1;
 41 } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') {
 42 return 1;
 43 }
 44 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
 45 return 1;
 46 } else {
 47 return -1;
 48 }
 49 }
 50 });
 51 
 52 for (User u : users) {
 53 System.out.print(u.getNumber() + " ");
 54 outputtool.output(u.calCost());
 55 System.out.print(" ");
 56 outputtool.output(u.calBalance());
 57 System.out.println();
 58 
 59 }
 60 
 61 }
 62 
 63 }
 64 
 65 abstract class ChargeMode {
 66 protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
 67 
 68 public abstract double calCost(UserRecords userRecords);
 69 
 70 public abstract double getMonthlyRent();
 71 
 72 public ArrayList<ChargeRule> getChargeRules() {
 73 return chargeRules;
 74 }
 75 
 76 public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
 77 this.chargeRules = chargeRules;
 78 }
 79 }
 80 
 81 class UserRecords {
 82 
 83 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
 84 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
 85 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
 86 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
 87 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
 88 private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
 89 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
 90 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
 91 
 92 public void addCallingInCityRecords(CallRecord callRecord) {
 93 callingInCityRecords.add(callRecord);
 94 }
 95 
 96 public void addCallingInProvinceRecords(CallRecord callRecord) {
 97 callingInProvinceRecords.add(callRecord);
 98 }
 99 
100 public void addCallingInLandRecords(CallRecord callRecord) {
101 callingInLandRecords.add(callRecord);
102 }
103 
104 public void addAnswerInCityRecords(CallRecord callRecord) {
105 answerInCityRecords.add(callRecord);
106 }
107 
108 public void aaddAnswerInProvinceRecords(CallRecord callRecord) {
109 answerInProvinceRecords.add(callRecord);
110 }
111 
112 public void addAnswerInLandRecords(CallRecord callRecord) {
113 answerInLandRecords.add(callRecord);
114 }
115 
116 public void addSendMessageRecords(MessageRecord callRecord) {
117 sendMessageRecords.add(callRecord);
118 }
119 
120 public void addReceiveMessageRecords(MessageRecord callRecord) {
121 receiveMessageRecords.add(callRecord);
122 }
123 
124 public ArrayList<CallRecord> getCallingInCityRecords() {
125 return callingInCityRecords;
126 }
127 
128 public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
129 this.callingInCityRecords = callingInCityRecords;
130 }
131 
132 public ArrayList<CallRecord> getCallingInProvinceRecords() {
133 return callingInProvinceRecords;
134 }
135 
136 public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
137 this.callingInProvinceRecords = callingInProvinceRecords;
138 }
139 
140 public ArrayList<CallRecord> getCallingInLandRecords() {
141 return callingInLandRecords;
142 }
143 
144 public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
145 this.callingInLandRecords = callingInLandRecords;
146 }
147 
148 public ArrayList<CallRecord> getAnswerInCityRecords() {
149 return answerInCityRecords;
150 }
151 
152 public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
153 this.answerInCityRecords = answerInCityRecords;
154 }
155 
156 public ArrayList<CallRecord> getAnswerInProvinceRecords() {
157 return answerInProvinceRecords;
158 }
159 
160 public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
161 this.answerInProvinceRecords = answerInProvinceRecords;
162 }
163 
164 public ArrayList<CallRecord> getAnswerInLandRecords() {
165 return answerInLandRecords;
166 }
167 
168 public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
169 this.answerInLandRecords = answerInLandRecords;
170 }
171 
172 public ArrayList<MessageRecord> getSendMessageRecords() {
173 return sendMessageRecords;
174 }
175 
176 public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
177 this.sendMessageRecords = sendMessageRecords;
178 }
179 
180 public ArrayList<MessageRecord> getReceiveMessageRecords() {
181 return receiveMessageRecords;
182 }
183 
184 public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
185 this.receiveMessageRecords = receiveMessageRecords;
186 }
187 
188 }
189 
190 class LandlinePhoneCharging extends ChargeMode {
191 
192 private double monthlyRent = 20;
193 
194 public LandlinePhoneCharging() {
195 super();
196 chargeRules.add(new LandPhoneInCityRule());
197 chargeRules.add(new LandPhoneInProvinceRule());
198 chargeRules.add(new LandPhoneInlandRule());
199 }
200 
201 @Override
202 public double calCost(UserRecords userRecords) {
203 double sumCost = 0;
204 for (ChargeRule rule : chargeRules) {
205 sumCost += rule.calCost(userRecords);
206 }
207 return sumCost;
208 }
209 
210 @Override
211 public double getMonthlyRent() {
212 return monthlyRent;
213 }
214 
215 }
216 
217 class MobilePhoneCharging extends ChargeMode {
218 
219 private double monthlyRent = 15;
220 
221 public MobilePhoneCharging() {
222 super();
223 chargeRules.add(new MobilePhoneInCityRule());
224 chargeRules.add(new MobilePhoneInProvinceRule());
225 chargeRules.add(new MobilePhoneInlandRule());
226 }
227 
228 @Override
229 public double calCost(UserRecords userRecords) {
230 double sumCost = 0;
231 for (ChargeRule rule : chargeRules) {
232 sumCost += rule.calCost(userRecords);
233 }
234 return sumCost;
235 }
236 
237 @Override
238 public double getMonthlyRent() {
239 return monthlyRent;
240 }
241 
242 }
243 
244 class Inputdeal {
245 
246 public int check(String input) {
247 if (input.matches("[u]-0791[0-9]{7,8}\\s[0]") || input.matches("[u]-1[0-9]{10}\\s[1]")) {
248 return 1;
249 // } else if (input.charAt(0) == 'm') {
250 // return 2;
251 } else if (input.matches("(([t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s)|"
252 + "([t]-0791[0-9]{7,8}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s)|"
253 + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "0[0-9]{9,11}\\s)|"
254 + "([t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s))"
255 
256 + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?"
257 + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((("
258 + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"
259 + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s"
260 + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.("
261 + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((("
262 + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))"
263 + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])")) {
264 return 2;
265 }
266 return 0;
267 }
268 
269 @SuppressWarnings("unused")
270 private boolean validatet(String string) {
271 if (!string.matches("^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$")) {
272 return false;
273 }
274 return true;
275 }
276 
277 public static boolean validate(String dateString) {
278 // 使用正则表达式 测试 字符 符合 dddd.dd.dd 的格式(d表示数字)
279 Pattern p = Pattern.compile("\\d{4}+[\\.]\\d{1,2}+[\\.]\\d{1,2}+");
280 Matcher m = p.matcher(dateString);
281 if (!m.matches()) {
282 return false;
283 }
284 
285 // 得到年月日
286 String[] array = dateString.split("\\.");
287 int year = Integer.valueOf(array[0]);
288 int month = Integer.valueOf(array[1]);
289 int day = Integer.valueOf(array[2]);
290 
291 if (month < 1 || month > 12) {
292 return false;
293 }
294 int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
295 if (isLeapYear(year)) {
296 monthLengths[2] = 29;
297 } else {
298 monthLengths[2] = 28;
299 }
300 int monthLength = monthLengths[month];
301 if (day < 1 || day > monthLength) {
302 return false;
303 }
304 return true;
305 }
306 
307 /** 是否是闰年 */
308 private static boolean isLeapYear(int year) {
309 return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
310 }
311 
312 public boolean judge(String input) {
313 
314 return false;
315 }
316 
317 public void writeUser(ArrayList<User> users, String input) {
318 User usernew = new User();
319 String[] inputs = input.split(" ");
320 String num = inputs[0].substring(2);
321 for (User i : users) {
322 if (i.getNumber().equals(num)) {
323 return;
324 }
325 }
326 usernew.setNumber(num);
327 int mode = Integer.parseInt(inputs[1]);
328 if (mode == 0) {
329 usernew.setChargeMode(new LandlinePhoneCharging());
330 } else if (mode == 1) {
331 usernew.setChargeMode(new MobilePhoneCharging());
332 }
333 users.add(usernew);
334 }
335 
336 public void writeRecord(ArrayList<User> users, String input) {
337 String[] inputs = input.split(" ");
338 
339 User callu = null, answeru = null;
340 CallRecord callrecord = new CallRecord(inputs);
341 
342 if (input.charAt(0) == 't') {
343 String out = inputs[0];
344 String in = "";
345 if (inputs.length == 6) {
346 in = inputs[1];
347 } else if (inputs.length == 7) {
348 in = inputs[1];
349 } else if (inputs.length == 8) {
350 in = inputs[2];
351 }
352 
353 for (User i : users) {
354 if (i.getNumber().equals(out)) {
355 callu = i;
356 }
357 if (i.getNumber().equals(in)) {
358 answeru = i;
359 }
360 if (callu != null && answeru != null) {
361 break;
362 }
363 }
364 
365 if (callu != null) {
366 if (callrecord.getCallType().matches("^1[1-3]$")) {
367 callu.getUserRecords().addCallingInCityRecords(callrecord);
368 } else if (callrecord.getCallType().matches("^2[1-3]$")) {
369 callu.getUserRecords().addCallingInProvinceRecords(callrecord);
370 } else {
371 callu.getUserRecords().addCallingInLandRecords(callrecord);
372 }
373 }
374 
375 if (answeru != null) {
376 if (callrecord.getCallType().matches("^[1-3]1$")) {
377 answeru.getUserRecords().addAnswerInCityRecords(callrecord);
378 } else if (callrecord.getCallType().matches("^[1-3]2$")) {
379 answeru.getUserRecords().aaddAnswerInProvinceRecords(callrecord);
380 } else {
381 answeru.getUserRecords().addAnswerInLandRecords(callrecord);
382 }
383 }
384 } else if (input.charAt(0) == 'm') {
385 
386 }
387 
388 }
389 
390 }
391 
392 abstract class CommunicationRecord {
393 protected String callingNumber;
394 protected String answerNumbe;
395 
396 public String getCallingNumber() {
397 return callingNumber;
398 }
399 
400 public void setCallingNumber(String callingNumber) {
401 this.callingNumber = callingNumber;
402 }
403 
404 public String getAnswerNumbe() {
405 return answerNumbe;
406 }
407 
408 public void setAnswerNumbe(String answerNumbe) {
409 this.answerNumbe = answerNumbe;
410 }
411 
412 }
413 
414 abstract class ChargeRule {
415 
416 abstract public double calCost(UserRecords userRecords);
417 
418 }
419 
420 class CallRecord extends CommunicationRecord {
421 private Date startTime;
422 private Date endTime;
423 private String callingAddressAreaCode;
424 private String answerAddressAreaCode;
425 
426 public String getCallType() {
427 String type = "";
428 if (callingAddressAreaCode.equals("0791")) {
429 type = type.concat("1");
430 } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) {
431 type = type.concat("2");
432 } else {
433 type = type.concat("3");
434 }
435 
436 if (answerAddressAreaCode.equals("0791")) {
437 type = type.concat("1");
438 } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) {
439 type = type.concat("2");
440 } else {
441 type = type.concat("3");
442 }
443 
444 return type;
445 }
446 
447 public CallRecord(String[] inputs) {
448 super();
449 
450 char type = inputs[0].charAt(0);
451 inputs[0] = inputs[0].substring(2);
452 
453 String sd = null, st = null, ed = null, et = null;
454 
455 if (type == 't') {
456 if (inputs.length == 6) {
457 sd = inputs[2];
458 st = inputs[3];
459 ed = inputs[4];
460 et = inputs[5];
461 callingAddressAreaCode = inputs[0].substring(0, 4);
462 answerAddressAreaCode = inputs[1].substring(0, 4);
463 } else if (inputs.length == 7) {
464 sd = inputs[3];
465 st = inputs[4];
466 ed = inputs[5];
467 et = inputs[6];
468 if (inputs[0].charAt(0) != '0') {
469 if (inputs[2].length() == 10) {
470 answerAddressAreaCode = inputs[2].substring(0, 3);
471 } else {
472 answerAddressAreaCode = inputs[2].substring(0, 4);
473 }
474 callingAddressAreaCode = inputs[1];
475 } else {
476 if (inputs[0].length() == 10) {
477 callingAddressAreaCode = inputs[0].substring(0, 3);
478 } else {
479 callingAddressAreaCode = inputs[0].substring(0, 4);
480 }
481 answerAddressAreaCode = inputs[2];
482 }
483 } else if (inputs.length == 8) {
484 sd = inputs[4];
485 st = inputs[5];
486 ed = inputs[6];
487 et = inputs[7];
488 callingAddressAreaCode = inputs[1];
489 answerAddressAreaCode = inputs[3];
490 }
491 } else if (type == 'm') {
492 
493 }
494 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
495 try {
496 startTime = simpleDateFormat.parse(sd + " " + st);
497 endTime = simpleDateFormat.parse(ed + " " + et);
498 } catch (ParseException e) {
499 }
500 
501 }
502 
503 public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
504 super();
505 this.startTime = startTime;
506 this.endTime = endTime;
507 this.callingAddressAreaCode = callingAddressAreaCode;
508 this.answerAddressAreaCode = answerAddressAreaCode;
509 }
510 
511 public Date getStartTime() {
512 return startTime;
513 }
514 
515 public void setStartTime(Date startTime) {
516 this.startTime = startTime;
517 }
518 
519 public Date getEndTime() {
520 return endTime;
521 }
522 
523 public void setEndTime(Date endTime) {
524 this.endTime = endTime;
525 }
526 
527 public String getCallingAddressAreaCode() {
528 return callingAddressAreaCode;
529 }
530 
531 public void setCallingAddressAreaCode(String callingAddressAreaCode) {
532 this.callingAddressAreaCode = callingAddressAreaCode;
533 }
534 
535 public String getAnswerAddressAreaCode() {
536 return answerAddressAreaCode;
537 }
538 
539 public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
540 this.answerAddressAreaCode = answerAddressAreaCode;
541 }
542 }
543 
544 abstract class CallChargeRule extends ChargeRule {
545 
546 }
547 
548 class LandPhoneInCityRule extends CallChargeRule {
549 
550 @Override
551 public double calCost(UserRecords userRecords) {
552 double sumCost = 0;
553 for (CallRecord call : userRecords.getCallingInCityRecords()) {
554 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
555 if (distanceS < 0) {
556 continue;
557 }
558 double distanceM = (int) distanceS / 60;
559 if (distanceS % 60 != 0) {
560 distanceM += 1;
561 }
562 if (call.getCallType().equals("11")) {
563 sumCost += distanceM * 0.1;
564 } else if (call.getCallType().equals("12")) {
565 sumCost += distanceM * 0.3;
566 } else if (call.getCallType().equals("13")) {
567 sumCost += distanceM * 0.6;
568 }
569 }
570 return sumCost;
571 }
572 
573 }
574 
575 class LandPhoneInlandRule extends CallChargeRule {
576 
577 @Override
578 public double calCost(UserRecords userRecords) {
579 double sumCost = 0;
580 for (CallRecord call : userRecords.getCallingInLandRecords()) {
581 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
582 if (distanceS < 0) {
583 continue;
584 }
585 double distanceM = (int) distanceS / 60;
586 if (distanceS % 60 != 0) {
587 distanceM += 1;
588 }
589 sumCost += distanceM * 0.6;
590 }
591 return sumCost;
592 }
593 
594 }
595 
596 class LandPhoneInProvinceRule extends CallChargeRule {
597 
598 @Override
599 public double calCost(UserRecords userRecords) {
600 double sumCost = 0;
601 for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
602 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
603 if (distanceS < 0) {
604 continue;
605 }
606 double distanceM = (int) distanceS / 60;
607 if (distanceS % 60 != 0) {
608 distanceM += 1;
609 }
610 sumCost += distanceM * 0.3;
611 }
612 return sumCost;
613 }
614 
615 }
616 
617 class MobilePhoneInCityRule extends CallChargeRule {
618 
619 @Override
620 public double calCost(UserRecords userRecords) {
621 double sumCost = 0;
622 for (CallRecord call : userRecords.getCallingInCityRecords()) {
623 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
624 if (distanceS < 0) {
625 continue;
626 }
627 double distanceM = (int) distanceS / 60;
628 if (distanceS % 60 != 0) {
629 distanceM += 1;
630 }
631 if (call.getCallType().equals("11")) {
632 sumCost += distanceM * 0.1;
633 } else if (call.getCallType().equals("12")) {
634 sumCost += distanceM * 0.2;
635 } else if (call.getCallType().equals("13")) {
636 sumCost += distanceM * 0.3;
637 }
638 
639 }
640 return sumCost;
641 }
642 
643 }
644 
645 class MobilePhoneInlandRule extends CallChargeRule {
646 
647 @Override
648 public double calCost(UserRecords userRecords) {
649 double sumCost = 0;
650 for (CallRecord call : userRecords.getCallingInLandRecords()) {
651 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
652 if (distanceS < 0) {
653 continue;
654 }
655 double distanceM = (int) distanceS / 60;
656 if (distanceS % 60 != 0) {
657 distanceM += 1;
658 }
659 sumCost += distanceM * 0.6;
660 }
661 for (CallRecord call : userRecords.getAnswerInLandRecords()) {
662 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
663 if (distanceS < 0) {
664 continue;
665 }
666 double distanceM = (int) distanceS / 60;
667 if (distanceS % 60 != 0) {
668 distanceM += 1;
669 }
670 sumCost += distanceM * 0.3;
671 }
672 return sumCost;
673 }
674 
675 }
676 
677 class MobilePhoneInProvinceRule extends CallChargeRule {
678 
679 @Override
680 public double calCost(UserRecords userRecords) {
681 double sumCost = 0;
682 for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
683 double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
684 if (distanceS < 0) {
685 continue;
686 }
687 double distanceM = (int) distanceS / 60;
688 if (distanceS % 60 != 0) {
689 distanceM += 1;
690 }
691 if (call.getCallType().equals("21")) {
692 sumCost += distanceM * 0.3;
693 } else if (call.getCallType().equals("22")) {
694 sumCost += distanceM * 0.3;
695 } else if (call.getCallType().equals("23")) {
696 sumCost += distanceM * 0.3;
697 }
698 }
699 return sumCost;
700 }
701 
702 }
703 
704 class MessageRecord extends CommunicationRecord {
705 
706 private String message;
707 
708 public String getMessage() {
709 return message;
710 }
711 
712 public void setMessage(String message) {
713 this.message = message;
714 }
715 }
716 
717 class User {
718 
719 private UserRecords userRecords = new UserRecords();
720 private double balance = 100;
721 private ChargeMode chargeMode;
722 private String number;
723 
724 public double calCost() {
725 return chargeMode.calCost(userRecords);
726 }
727 
728 public double calBalance() {
729 return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
730 }
731 
732 public UserRecords getUserRecords() {
733 return userRecords;
734 }
735 
736 public void setUserRecords(UserRecords userRecords) {
737 this.userRecords = userRecords;
738 }
739 
740 public ChargeMode getChargeMode() {
741 return chargeMode;
742 }
743 
744 public void setChargeMode(ChargeMode chargeMode) {
745 this.chargeMode = chargeMode;
746 }
747 
748 public String getNumber() {
749 return number;
750 }
751 
752 public void setNumber(String number) {
753 this.number = number;
754 }
755 
756 }
757 
758 class Outputtool {
759 
760 @SuppressWarnings("deprecation")
761 public void output(double out) {
762 // java.text.DecimalFormat df=new java.text.DecimalFormat("#.##");
763 // String a=df.format(out);
764 // System.out.print(a);
765 BigDecimal numb = new BigDecimal(out);
766 out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
767 System.out.print(out);
768 }
769 }
View Code

 

 

 

7_2.sdut-Collection-sort--C~K的班级(II)

经过不懈的努力,C~K终于当上了班主任。

现在他要统计班里学生的名单,但是C~K在教务系统中导出班级名单时出了问题,发现会有同学的信息重复,现在他想把重复的同学信息删掉,只保留一个,
但是工作量太大了,所以找到了会编程的你,你能帮他解决这个问题吗?

输入格式:
第一行输入一个N,代表C~K导出的名单共有N行(N<100000).

接下来的N行,每一行包括一个同学的信息,学号 姓名 年龄 性别。

输出格式:
第一行输出一个n,代表删除重复名字后C~K的班级共有几人。

接下来的n行,输出每一个同学的信息,输出按照学号从小到大的顺序。

输入样例:

6
0001 MeiK 20 M
0001 MeiK 20 M
0002 sdk2 21 M
0002 sdk2 21 M
0002 sdk2 21 M
0000 blf2 22 F

  

输出样例:

3
0000 blf2 22 F
0001 MeiK 20 M
0002 sdk2 21 M

  

代码:

 1 import java.util.*;
 2 public class Main {
 3         public static void main(String[] args){
 4             HashSet<Student> students = new HashSet<>();
 5             Scanner input = new Scanner(System.in);
 6             int N = input.nextInt();//班级人数
 7             for(int i=0;i<N;i++){
 8                 students.add(new Student(input.next(),input.next(),input.nextInt(),input.next())) ;
 9             }
10             System.out.println(students.size());
11             ArrayList<Student> studentArrayList = new ArrayList<>(students);
12             Collections.sort(studentArrayList);
13             for (Student student : studentArrayList) System.out.println(student.sno + " " + student.name + " " + student.age + " " + student.gender);
14         }
15 }
16 class Student implements Comparable<Student>{
17     String sno;//学号
18     String name;//姓名
19     int age;//年龄
20     String gender;//性别
21     public Student(String sno,String name,int age,String gender){
22         this.sno = sno;
23         this.name = name;
24         this.age = age;
25         this.gender = gender;
26     }
27     public boolean equals(Object obj) {
28         return sno.equals(((Student) obj).sno);
29     }
30 
31     public String toString() {
32         return sno + " " + name + " " + age + " " + sno;
33     }
34     @Override
35     public int compareTo(Student o) {
36         return Integer.compare(Integer.parseInt(sno), Integer.parseInt(o.sno));
37     }
38     public int hashCode() {
39         return Integer.parseInt(sno);
40     }
41 }
View Code

 

分析:

  这里运用了拉姆达表达式解决该问题,保持了学号对应的姓名,年龄,性别的连接性是一个不错的解决方法,在复习拉姆达表达式的同时,也让我们体会到了拉姆达表达式的实用性,是一个非常不错的题目。

7_3.阅读程序,按照题目需求修改程序

功能需求:
      使用集合存储3个员工的信息(有序);
      通过迭代器依次找出所有的员工。

 提示:学生复制以下代码到编程区,并按需求进行调试修改。

// 1、导入相关包

//定义员工类
class Employee {

	private String name;
	private int age;

	public Employee() {
		super();
	}

	public Employee(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

//主函数
public class Main {

	public static void main(String[] args) {
				// 1、创建有序集合对象
				Collection c ;

      // 创建3个员工元素对象
		for (int i = 0; i < 3; i++) {
			Scanner sc = new Scanner(System.in);
			String employeeName = sc.nextLine();
			int employeeAge = sc.nextInt();
			
			Employee employee = new Employee(employeeName, employeeAge);
			c.add(employee);
		}			
				
				
				
				// 2、创建迭代器遍历集合
				Iterator it;
				
				//3、遍历
				while (it.hasnext) {
					
					//4、集合中对象未知,向下转型
					Employee e =  it.next();
					
					System.out.println(e.getName() + "---" + e.getAge());
				}
	}

}

  

输入样例:
在这里给出一组输入。例如:

zs 
10
ls
20
ww 
30

  

输出样例:
在这里给出相应的输出。例如

zs---10
ls---20
ww---30

  

代码:

 1 // 1、导入相关包
 2 import java.util.*;
 3 //定义员工类
 4 class Employee {
 5 
 6     private String name;
 7     private int age;
 8 
 9     public Employee() {
10         super();
11     }
12 
13     public Employee(String name, int age) {
14         super();
15         this.name = name;
16         this.age = age;
17     }
18 
19     public String getName() {
20         return name;
21     }
22 
23     public void setName(String name) {
24         this.name = name;
25     }
26 
27     public int getAge() {
28         return age;
29     }
30 
31     public void setAge(int age) {
32         this.age = age;
33     }
34 }
35 
36 //主函数
37 public class Main {
38 
39     public static void main(String[] args) {
40                 // 1、创建有序集合对象
41                 Collection<Employee> c = new ArrayList<>();
42 
43       // 创建3个员工元素对象
44         for (int i = 0; i < 3; i++) {
45             Scanner sc = new Scanner(System.in);
46             String employeeName = sc.nextLine();
47             int employeeAge = sc.nextInt();
48             
49             Employee employee = new Employee(employeeName, employeeAge);
50             c.add(employee);
51         }            
52                 
53                 
54                 
55                 // 2、创建迭代器遍历集合
56                 Iterator<Employee> it = c.iterator();
57                 
58                 //3、遍历
59                 while (it.hasNext()) {
60                     
61                     //4、集合中对象未知,向下转型
62                     Employee e =  it.next();
63                     
64                     System.out.println(e.getName() + "---" + e.getAge());
65                 }
66     }
67 
68 }
View Code

 

分析:

  这题就是对给定的代码进行编译测试,调试运行,这里面只需要改 创建有序集合对象 和 创建迭代器遍历集合 这两部分,第一个是缺少创建集合对象,第二个是没有使用迭代器。

 

 

 

8_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、2、3:

图1

图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。
ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。    
UserRecords是用户记录类,保存用户各种通话、短信的记录,    
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。

 

图2

    图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。

  

图3

图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。
SendMessageRule是发送短信的计费规则类,用于计算发送短信的费用。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。

(提示:可以从UserRecords类中获取各种类型的callRecords)。

  

注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。

输入样例:
在这里给出一组输入。例如:

u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaaaaaaaaaaaaa
end

  

输出样例:
在这里给出相应的输出。例如:

18907910010 0.3 99.7

  

### 输入样例1:

在这里给出一组输入。例如:

u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaa
m-18907910010 13305862264 aaaaaaa.
m-18907910010 13305862264 bb,bbbb
end

  

输出样例1:
在这里给出相应的输出。例如:

18907910010 0.5 99.5

  

代码:

  1  
  2  
  3 import java.util.ArrayList;
  4 import java.util.Comparator;
  5 import java.util.Scanner;
  6 import java.util.regex.Matcher;
  7 import java.util.regex.Pattern;
  8 import java.math.BigDecimal;
  9 import java.text.SimpleDateFormat;
 10 import java.util.Date;
 11 import java.util.Locale;
 12 import java.text.ParseException;
 13  
 14 public class Main {
 15  
 16     public static void main(String[] args) {
 17  
 18         Outputtool outputtool = new Outputtool();
 19  
 20         Inputdeal inputdeal = new Inputdeal();
 21  
 22         ArrayList<User> users = new ArrayList<>();
 23  
 24         Scanner in = new Scanner(System.in);
 25  
 26         String input = in.nextLine();
 27  
 28         while (!input.equals("end")) {
 29             if (1 == inputdeal.check(input)) {
 30                 inputdeal.writeUser(users, input);
 31             } else if (2 == inputdeal.check(input)) {
 32                 inputdeal.writeRecord(users, input);
 33             }
 34             input = in.nextLine();
 35         }
 36  
 37         users.sort(new Comparator<User>() {
 38  
 39             @Override
 40             public int compare(User u1, User u2) {
 41                 if (u1.getNumber().charAt(0) == '0' && u2.getNumber().charAt(0) != '0') {
 42                     return -1;
 43                 } else if (u1.getNumber().charAt(0) != '0' && u2.getNumber().charAt(0) == '0') {
 44                     return 1;
 45                 }
 46                 if (Double.parseDouble(u1.getNumber()) > Double.parseDouble(u2.getNumber())) {
 47                     return 1;
 48                 } else {
 49                     return -1;
 50                 }
 51             }
 52         });
 53  
 54         for (User u : users) {
 55             System.out.print(u.getNumber() + " ");
 56             outputtool.output(u.calCost());
 57             System.out.print(" ");
 58             outputtool.output(u.calBalance());
 59             System.out.println();
 60  
 61         }
 62  
 63     }
 64  
 65 }
 66  
 67 abstract class ChargeMode {
 68     protected ArrayList<ChargeRule> chargeRules = new ArrayList<>();
 69  
 70     public abstract double calCost(UserRecords userRecords);
 71  
 72     public abstract double getMonthlyRent();
 73  
 74     public ArrayList<ChargeRule> getChargeRules() {
 75         return chargeRules;
 76     }
 77  
 78     public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
 79         this.chargeRules = chargeRules;
 80     }
 81 }
 82  
 83 class UserRecords {
 84  
 85     private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
 86     private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
 87     private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
 88     private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
 89     private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
 90     private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
 91     private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
 92     private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
 93  
 94     public void addCallingInCityRecords(CallRecord callRecord) {
 95         callingInCityRecords.add(callRecord);
 96     }
 97  
 98     public void addCallingInProvinceRecords(CallRecord callRecord) {
 99         callingInProvinceRecords.add(callRecord);
100     }
101  
102     public void addCallingInLandRecords(CallRecord callRecord) {
103         callingInLandRecords.add(callRecord);
104     }
105  
106     public void addAnswerInCityRecords(CallRecord callRecord) {
107         answerInCityRecords.add(callRecord);
108     }
109  
110     public void aaddAnswerInProvinceRecords(CallRecord callRecord) {
111         answerInProvinceRecords.add(callRecord);
112     }
113  
114     public void addAnswerInLandRecords(CallRecord callRecord) {
115         answerInLandRecords.add(callRecord);
116     }
117  
118     public void addSendMessageRecords(MessageRecord callRecord) {
119         sendMessageRecords.add(callRecord);
120     }
121  
122     public void addReceiveMessageRecords(MessageRecord callRecord) {
123         receiveMessageRecords.add(callRecord);
124     }
125  
126     public ArrayList<CallRecord> getCallingInCityRecords() {
127         return callingInCityRecords;
128     }
129  
130     public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
131         this.callingInCityRecords = callingInCityRecords;
132     }
133  
134     public ArrayList<CallRecord> getCallingInProvinceRecords() {
135         return callingInProvinceRecords;
136     }
137  
138     public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
139         this.callingInProvinceRecords = callingInProvinceRecords;
140     }
141  
142     public ArrayList<CallRecord> getCallingInLandRecords() {
143         return callingInLandRecords;
144     }
145  
146     public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
147         this.callingInLandRecords = callingInLandRecords;
148     }
149  
150     public ArrayList<CallRecord> getAnswerInCityRecords() {
151         return answerInCityRecords;
152     }
153  
154     public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
155         this.answerInCityRecords = answerInCityRecords;
156     }
157  
158     public ArrayList<CallRecord> getAnswerInProvinceRecords() {
159         return answerInProvinceRecords;
160     }
161  
162     public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
163         this.answerInProvinceRecords = answerInProvinceRecords;
164     }
165  
166     public ArrayList<CallRecord> getAnswerInLandRecords() {
167         return answerInLandRecords;
168     }
169  
170     public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
171         this.answerInLandRecords = answerInLandRecords;
172     }
173  
174     public ArrayList<MessageRecord> getSendMessageRecords() {
175         return sendMessageRecords;
176     }
177  
178     public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
179         this.sendMessageRecords = sendMessageRecords;
180     }
181  
182     public ArrayList<MessageRecord> getReceiveMessageRecords() {
183         return receiveMessageRecords;
184     }
185  
186     public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
187         this.receiveMessageRecords = receiveMessageRecords;
188     }
189  
190 }
191  
192 class LandlinePhoneCharging extends ChargeMode {
193  
194     private double monthlyRent = 20;
195  
196     public LandlinePhoneCharging() {
197         super();
198         chargeRules.add(new LandPhoneInCityRule());
199         chargeRules.add(new LandPhoneInProvinceRule());
200         chargeRules.add(new LandPhoneInlandRule());
201     }
202  
203     @Override
204     public double calCost(UserRecords userRecords) {
205         double sumCost = 0;
206         for (ChargeRule rule : chargeRules) {
207             sumCost += rule.calCost(userRecords);
208         }
209         return sumCost;
210     }
211  
212     @Override
213     public double getMonthlyRent() {
214         return monthlyRent;
215     }
216  
217 }
218  
219 class MobilePhoneCharging extends ChargeMode {
220  
221     private double monthlyRent = 15;
222  
223     public MobilePhoneCharging() {
224         super();
225         chargeRules.add(new MobilePhoneInCityRule());
226         chargeRules.add(new MobilePhoneInProvinceRule());
227         chargeRules.add(new MobilePhoneInlandRule());
228     }
229  
230     @Override
231     public double calCost(UserRecords userRecords) {
232         double sumCost = 0;
233         for (ChargeRule rule : chargeRules) {
234             sumCost += rule.calCost(userRecords);
235         }
236         return sumCost;
237     }
238  
239     @Override
240     public double getMonthlyRent() {
241         return monthlyRent;
242     }
243  
244 }
245  
246 class MobilePhoneMassageCharging extends ChargeMode {
247  
248     private double monthlyRent = 0;
249  
250     public MobilePhoneMassageCharging() {
251         super();
252         chargeRules.add(new MobilePhoneMessageRule());
253     }
254  
255     @Override
256     public double calCost(UserRecords userRecords) {
257         double sumCost = 0;
258         for (ChargeRule rule : chargeRules) {
259             sumCost += rule.calCost(userRecords);
260         }
261         return sumCost;
262     }
263  
264     @Override
265     public double getMonthlyRent() {
266         return monthlyRent;
267     }
268  
269 }
270  
271 class Inputdeal {
272  
273     public int check(String input) {
274         if (input.matches("[u]-0791[0-9]{7,8}\\s[0]") || input.matches("[u]-1[0-9]{10}\\s[13]")) {
275             return 1;
276         } else if (input.matches("[m]-1[0-9]{10}\\s" + "1[0-9]{10}\\s" + "[0-9a-zA-Z\\s\\.,]+")) {
277             return 2;
278         }
279         return 0;
280     }
281  
282     public void writeUser(ArrayList<User> users, String input) {
283         User usernew = new User();
284         String[] inputs = input.split(" ");
285         String num = inputs[0].substring(2);
286         for (User i : users) {
287             if (i.getNumber().equals(num)) {
288                 return;
289             }
290         }
291         usernew.setNumber(num);
292         int mode = Integer.parseInt(inputs[1]);
293         if (mode == 0) {
294             usernew.setChargeMode(new LandlinePhoneCharging());
295         } else if (mode == 1) {
296             usernew.setChargeMode(new MobilePhoneCharging());
297         } else if (mode == 3) {
298             usernew.setChargeMode(new MobilePhoneMassageCharging());
299         }
300         users.add(usernew);
301     }
302  
303     public void writeRecord(ArrayList<User> users, String input) {
304         String[] inputs = input.split(" ");
305         inputs[0] = inputs[0].substring(2);
306  
307         User callu = null, answeru = null;
308  
309         String out = inputs[0];
310         String in = "";
311         if (inputs.length == 6) {
312             in = inputs[1];
313         } else if (inputs.length == 7) {
314             in = inputs[1];
315         } else if (inputs.length == 8) {
316             in = inputs[2];
317         } else {
318             in = inputs[1];
319         }
320  
321         for (User i : users) {
322             if (i.getNumber().equals(out)) {
323                 callu = i;
324             }
325             if (i.getNumber().equals(in)) {
326                 answeru = i;
327             }
328             if (callu != null && answeru != null) {
329                 break;
330             }
331         }
332  
333         if (input.charAt(0) == 'm') {
334             MessageRecord messageRecord = new MessageRecord(input);
335             if (callu != null) {
336                 callu.getUserRecords().addSendMessageRecords(messageRecord);
337                 ;
338             }
339             if (answeru != null) {
340                 callu.getUserRecords().addReceiveMessageRecords(messageRecord);
341             }
342         }
343  
344     }
345  
346 }
347  
348 abstract class CommunicationRecord {
349     protected String callingNumber;
350     protected String answerNumbe;
351  
352     public String getCallingNumber() {
353         return callingNumber;
354     }
355  
356     public void setCallingNumber(String callingNumber) {
357         this.callingNumber = callingNumber;
358     }
359  
360     public String getAnswerNumbe() {
361         return answerNumbe;
362     }
363  
364     public void setAnswerNumbe(String answerNumbe) {
365         this.answerNumbe = answerNumbe;
366     }
367  
368 }
369  
370 abstract class ChargeRule {
371  
372     abstract public double calCost(UserRecords userRecords);
373  
374 }
375  
376 class CallRecord extends CommunicationRecord {
377     private Date startTime;
378     private Date endTime;
379     private String callingAddressAreaCode;
380     private String answerAddressAreaCode;
381  
382     public String getCallType() {
383         String type = "";
384         if (callingAddressAreaCode.equals("0791")) {
385             type = type.concat("1");
386         } else if (callingAddressAreaCode.matches("^079[023456789]$") || callingAddressAreaCode.equals("0701")) {
387             type = type.concat("2");
388         } else {
389             type = type.concat("3");
390         }
391  
392         if (answerAddressAreaCode.equals("0791")) {
393             type = type.concat("1");
394         } else if (answerAddressAreaCode.matches("^079[023456789]$") || answerAddressAreaCode.equals("0701")) {
395             type = type.concat("2");
396         } else {
397             type = type.concat("3");
398         }
399  
400         return type;
401     }
402  
403     public CallRecord(String[] inputs) {
404         super();
405  
406         char type = inputs[0].charAt(0);
407  
408         String sd = null, st = null, ed = null, et = null;
409  
410         if (type == 't') {
411             if (inputs.length == 6) {
412                 sd = inputs[2];
413                 st = inputs[3];
414                 ed = inputs[4];
415                 et = inputs[5];
416                 callingAddressAreaCode = inputs[0].substring(0, 4);
417                 answerAddressAreaCode = inputs[1].substring(0, 4);
418             } else if (inputs.length == 7) {
419                 sd = inputs[3];
420                 st = inputs[4];
421                 ed = inputs[5];
422                 et = inputs[6];
423                 if (inputs[0].charAt(0) != '0') {
424                     if (inputs[2].length() == 10) {
425                         answerAddressAreaCode = inputs[2].substring(0, 3);
426                     } else {
427                         answerAddressAreaCode = inputs[2].substring(0, 4);
428                     }
429                     callingAddressAreaCode = inputs[1];
430                 } else {
431                     if (inputs[0].length() == 10) {
432                         callingAddressAreaCode = inputs[0].substring(0, 3);
433                     } else {
434                         callingAddressAreaCode = inputs[0].substring(0, 4);
435                     }
436                     answerAddressAreaCode = inputs[2];
437                 }
438             } else if (inputs.length == 8) {
439                 sd = inputs[4];
440                 st = inputs[5];
441                 ed = inputs[6];
442                 et = inputs[7];
443                 callingAddressAreaCode = inputs[1];
444                 answerAddressAreaCode = inputs[3];
445             }
446         } else if (type == 'm') {
447  
448         }
449         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
450         try {
451             startTime = simpleDateFormat.parse(sd + " " + st);
452             endTime = simpleDateFormat.parse(ed + " " + et);
453         } catch (ParseException e) {
454         }
455  
456     }
457  
458     public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
459         super();
460         this.startTime = startTime;
461         this.endTime = endTime;
462         this.callingAddressAreaCode = callingAddressAreaCode;
463         this.answerAddressAreaCode = answerAddressAreaCode;
464     }
465  
466     public Date getStartTime() {
467         return startTime;
468     }
469  
470     public void setStartTime(Date startTime) {
471         this.startTime = startTime;
472     }
473  
474     public Date getEndTime() {
475         return endTime;
476     }
477  
478     public void setEndTime(Date endTime) {
479         this.endTime = endTime;
480     }
481  
482     public String getCallingAddressAreaCode() {
483         return callingAddressAreaCode;
484     }
485  
486     public void setCallingAddressAreaCode(String callingAddressAreaCode) {
487         this.callingAddressAreaCode = callingAddressAreaCode;
488     }
489  
490     public String getAnswerAddressAreaCode() {
491         return answerAddressAreaCode;
492     }
493  
494     public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
495         this.answerAddressAreaCode = answerAddressAreaCode;
496     }
497 }
498  
499 abstract class CallChargeRule extends ChargeRule {
500  
501 }
502  
503 class LandPhoneInCityRule extends CallChargeRule {
504  
505     @Override
506     public double calCost(UserRecords userRecords) {
507         double sumCost = 0;
508         for (CallRecord call : userRecords.getCallingInCityRecords()) {
509             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
510             if (distanceS < 0) {
511                 continue;
512             }
513             double distanceM = (int) distanceS / 60;
514             if (distanceS % 60 != 0) {
515                 distanceM += 1;
516             }
517             if (call.getCallType().equals("11")) {
518                 sumCost += distanceM * 0.1;
519             } else if (call.getCallType().equals("12")) {
520                 sumCost += distanceM * 0.3;
521             } else if (call.getCallType().equals("13")) {
522                 sumCost += distanceM * 0.6;
523             }
524         }
525         return sumCost;
526     }
527  
528 }
529  
530 class LandPhoneInlandRule extends CallChargeRule {
531  
532     @Override
533     public double calCost(UserRecords userRecords) {
534         double sumCost = 0;
535         for (CallRecord call : userRecords.getCallingInLandRecords()) {
536             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
537             if (distanceS < 0) {
538                 continue;
539             }
540             double distanceM = (int) distanceS / 60;
541             if (distanceS % 60 != 0) {
542                 distanceM += 1;
543             }
544             sumCost += distanceM * 0.6;
545         }
546         return sumCost;
547     }
548  
549 }
550  
551 class LandPhoneInProvinceRule extends CallChargeRule {
552  
553     @Override
554     public double calCost(UserRecords userRecords) {
555         double sumCost = 0;
556         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
557             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
558             if (distanceS < 0) {
559                 continue;
560             }
561             double distanceM = (int) distanceS / 60;
562             if (distanceS % 60 != 0) {
563                 distanceM += 1;
564             }
565             sumCost += distanceM * 0.3;
566         }
567         return sumCost;
568     }
569  
570 }
571  
572 class MobilePhoneInCityRule extends CallChargeRule {
573  
574     @Override
575     public double calCost(UserRecords userRecords) {
576         double sumCost = 0;
577         for (CallRecord call : userRecords.getCallingInCityRecords()) {
578             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
579             if (distanceS < 0) {
580                 continue;
581             }
582             double distanceM = (int) distanceS / 60;
583             if (distanceS % 60 != 0) {
584                 distanceM += 1;
585             }
586             if (call.getCallType().equals("11")) {
587                 sumCost += distanceM * 0.1;
588             } else if (call.getCallType().equals("12")) {
589                 sumCost += distanceM * 0.2;
590             } else if (call.getCallType().equals("13")) {
591                 sumCost += distanceM * 0.3;
592             }
593  
594         }
595         return sumCost;
596     }
597  
598 }
599  
600 class MobilePhoneInlandRule extends CallChargeRule {
601  
602     @Override
603     public double calCost(UserRecords userRecords) {
604         double sumCost = 0;
605         for (CallRecord call : userRecords.getCallingInLandRecords()) {
606             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
607             if (distanceS < 0) {
608                 continue;
609             }
610             double distanceM = (int) distanceS / 60;
611             if (distanceS % 60 != 0) {
612                 distanceM += 1;
613             }
614             sumCost += distanceM * 0.6;
615         }
616         for (CallRecord call : userRecords.getAnswerInLandRecords()) {
617             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
618             if (distanceS < 0) {
619                 continue;
620             }
621             double distanceM = (int) distanceS / 60;
622             if (distanceS % 60 != 0) {
623                 distanceM += 1;
624             }
625             sumCost += distanceM * 0.3;
626         }
627         return sumCost;
628     }
629  
630 }
631  
632 class MobilePhoneInProvinceRule extends CallChargeRule {
633  
634     @Override
635     public double calCost(UserRecords userRecords) {
636         double sumCost = 0;
637         for (CallRecord call : userRecords.getCallingInProvinceRecords()) {
638             double distanceS = (-call.getStartTime().getTime() + call.getEndTime().getTime()) / 1000;
639             if (distanceS < 0) {
640                 continue;
641             }
642             double distanceM = (int) distanceS / 60;
643             if (distanceS % 60 != 0) {
644                 distanceM += 1;
645             }
646             if (call.getCallType().equals("21")) {
647                 sumCost += distanceM * 0.3;
648             } else if (call.getCallType().equals("22")) {
649                 sumCost += distanceM * 0.3;
650             } else if (call.getCallType().equals("23")) {
651                 sumCost += distanceM * 0.3;
652             }
653         }
654         return sumCost;
655     }
656  
657 }
658  
659 class MobilePhoneMessageRule extends CallChargeRule {
660  
661     @Override
662     public double calCost(UserRecords userRecords) {
663         double sumCost = 0;
664         int number = 0;
665         for (MessageRecord m : userRecords.getSendMessageRecords()) {
666             int length = m.getMessage().length();
667             if (length <= 10) {
668                 number++;
669             } else {
670                 number += length / 10;
671                 if (length % 10 != 0) {
672                     number++;
673                 }
674             }
675         }
676         if (number <= 3) {
677             sumCost = number * 0.1;
678         } else if (number <= 5) {
679             sumCost = 0.3 + 0.2 * (number - 3);
680         } else {
681             sumCost = 0.7 + 0.3 * (number - 5);
682         }
683         return sumCost;
684     }
685  
686 }
687  
688 class MessageRecord extends CommunicationRecord {
689  
690     private String message;
691  
692     public MessageRecord(String input) {
693         super();
694         this.message = input.substring(26);
695     }
696  
697     public String getMessage() {
698         return message;
699     }
700  
701     public void setMessage(String message) {
702         this.message = message;
703     }
704 }
705  
706 class User {
707  
708     private UserRecords userRecords = new UserRecords();
709     private double balance = 100;
710     private ChargeMode chargeMode;
711     private String number;
712  
713     public double calCost() {
714         return chargeMode.calCost(userRecords);
715     }
716  
717     public double calBalance() {
718         return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
719     }
720  
721     public UserRecords getUserRecords() {
722         return userRecords;
723     }
724  
725     public void setUserRecords(UserRecords userRecords) {
726         this.userRecords = userRecords;
727     }
728  
729     public ChargeMode getChargeMode() {
730         return chargeMode;
731     }
732  
733     public void setChargeMode(ChargeMode chargeMode) {
734         this.chargeMode = chargeMode;
735     }
736  
737     public String getNumber() {
738         return number;
739     }
740  
741     public void setNumber(String number) {
742         this.number = number;
743     }
744  
745 }
746  
747 class Outputtool {
748  
749     @SuppressWarnings("deprecation")
750     public void output(double out) {
751 //        java.text.DecimalFormat df=new java.text.DecimalFormat("#.##");
752 //        String a=df.format(out);
753 //        System.out.print(a);
754         BigDecimal numb = new BigDecimal(out);
755         out = numb.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
756         System.out.print(out);
757     }
758 }
View Code

 

 

 

 

8_2.编写一个类Shop(商店)、内部类InnerCoupons(内部购物券)

编写一个类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的购物券各消费一次,分别输出消费后商店剩下的牛奶箱数。

输入格式:
输入一个大于或等于3的整数。

输出格式:
使用了面值为50的购物券进行支付
牛奶还剩XX箱
使用了面值为100的购物券进行支付
牛奶还剩XX箱

输入样例:
在这里给出一组输入。例如:

5

  

输出样例:
在这里给出相应的输出。例如:

使用了面值为50的购物券进行支付
牛奶还剩4箱
使用了面值为100的购物券进行支付
牛奶还剩2箱

  

代码:

 1 import java.util.Scanner;
 2 public class Main {
 3     public static void main(String[] args) {
 4         Scanner input = new Scanner(System.in);
 5         Shop myshop = new Shop(input.nextInt());
 6         myshop.coupons50.buy();
 7         System.out.println("牛奶还剩" + myshop.getMilkCount() + "箱");
 8         myshop.coupons100.buy();
 9         System.out.println("牛奶还剩" + myshop.getMilkCount() + "箱");
10     }
11 }
12 
13 class Shop{//商店类
14     private int milkCount;//牛奶的箱数
15     class InnerCoupons{//(内部购物券)
16         int value;//购物券的面值
17 
18         public InnerCoupons(int value) {//带参数的构造方法,可以设置购物券的面值
19             this.value = value;
20         }
21         public void buy(){
22             System.out.println("使用了面值为"+ value +"的购物券进行支付");
23             milkCount = milkCount - value / 50;
24         }
25     }
26     InnerCoupons coupons50 = new InnerCoupons(50);//50元的购物券
27     InnerCoupons coupons100 = new InnerCoupons(100);//100元的购物券
28 
29     public Shop(int milkCount) {//牛奶箱数
30         this.milkCount = milkCount;
31     }
32 
33     public int getMilkCount() {//获取牛奶的箱数
34         return milkCount;
35     }
36 
37     public void setMilkCount(int milkCount) {//设置牛奶的箱数
38         this.milkCount = milkCount;
39     }
40 }
View Code

 

分析:

  这题主要成员内部类的使用,其中有点难度的就是那个50和100的购物券那个地方当时,本来是想在主函数里面设置50和100的购物券,结果一直报错,后来就放在shop类里面直接设置,然后在主函数直接调用。

 

8_3.动物发声模拟器(多态)

设计一个动物发生模拟器,用于模拟不同动物的叫声。比如狮吼、虎啸、狗旺旺、猫喵喵……。
定义抽象类Animal,包含两个抽象方法:获取动物类别getAnimalClass()、动物叫shout();
然后基于抽象类Animal定义狗类Dog、猫类Cat和山羊Goat,用getAnimalClass()方法返回不同的动物类别(比如猫,狗,山羊),用shout()方法分别输出不同的叫声(比如喵喵、汪汪、咩咩)。
最后编写AnimalShoutTest类测试,输出:
猫的叫声:喵喵
狗的叫声:汪汪
山羊的叫声:咩咩

其中,在AnimalShoutTestMain类中,用speak(Animal animal){}方法输出动物animal的叫声,在main()方法中调用speak()方法,分别输出猫、狗和山羊对象的叫声。

请在下面的【】处添加代码。

//动物发生模拟器.  请在下面的【】处添加代码。
public class AnimalShoutTest2 {
    public static void main(String[] args) {        
         Cat cat = new Cat();
         Dog dog = new Dog();        
        Goat goat = new Goat();
         speak(cat);
         speak(dog);
         speak(goat);
    }
    //定义静态方法speak()
    【】

}

//定义抽象类Animal
【】class Animal{
    【】
}
//基于Animal类,定义猫类Cat,并重写两个抽象方法
class Cat 【】{
    【】    
    【】
}
//基于Animal类,定义狗类Dog,并重写两个抽象方法
class Dog 【】{
    【】
    【】
}
//基于Animal类,定义山羊类Goat,并重写两个抽象方法
class Goat 【】{
    【】
    【】
}

输入样例:

 

输出样例:

猫的叫声:喵喵
狗的叫声:汪汪
山羊的叫声:咩咩

  

代码:

 1 //动物发生模拟器.  请在下面的【】处添加代码。
 2 public class Main{
 3     public static void main(String[] args){
 4             Cat cat = new Cat();
 5             Dog dog = new Dog();
 6             Goat goat = new Goat();
 7             speak(cat);
 8             speak(dog);
 9             speak(goat);
10         }
11         //定义静态方法speak()
12         static void speak(Animal animal){
13             System.out.println(animal.getAnimalClass() + "的叫声:" + animal.shout());
14         }
15 }
16 
17 
18 
19 
20 
21 
22 //定义抽象类Animal
23 abstract class Animal{
24     abstract String getAnimalClass();
25     abstract String shout();
26 }
27 //基于Animal类,定义猫类Cat,并重写两个抽象方法
28 class Cat extends Animal{
29 
30 
31     @Override
32     String getAnimalClass() {
33         return "猫";
34     }
35 
36     @Override
37     String shout() {
38         return "喵喵";
39     }
40 }
41 //基于Animal类,定义狗类Dog,并重写两个抽象方法
42 class Dog extends Animal{
43 
44     @Override
45     String getAnimalClass() {
46         return "狗";
47     }
48 
49     @Override
50     String shout() {
51         return "汪汪";
52     }
53 }
54 //基于Animal类,定义山羊类Goat,并重写两个抽象方法
55 class Goat extends Animal{
56 
57     @Override
58     String getAnimalClass() {
59         return "山羊";
60     }
61 
62     @Override
63     String shout() {
64         return "咩咩";
65     }
66 }
View Code

 

分析:

  这题没什么说的,比较简单。

三.踩坑心得

   其实还好但是知识点有很多盲区比如知识点总结接口的注意事项:如果多个接口含有相同的抽象方法,则直接重写一回即可如果没有覆盖重写全部的,必须是抽象类接口中有相同的默认方法必须要重写,抽象类中也要重写一个类如果直接父类的方法与接口的默认方法冲突,优先使用父类的方法。多态的注意事项有继承关系子类重写父类方法子类引用指向父类对象,子类特有方法不能直接表达出来,需要子类和父类都有。抽象类的注意事项和知识点abstract(抽象类):它是一个类,离不开extends(继承),但extends是单继承,不能继承多个类,有局限性在抽象类中可以写普通方法,抽象方法必须写在抽象类中,不能实例化抽象类,只能靠它的子类去实现它,抽象类是受约束的。使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList 体现的是适使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

四.改进建议

  我感觉还是有点难了,题目可能来说挺不错的,但是一些细节还是没处理好,比如测试点,有些就挺恶心的。

五.总结

1.函数与变量的调用上,代码耦合度高,调用关系太乱。
2.代码注释少,隔段时间就会看不懂代码,增加工作难度,习惯不好
3.字符串输入尽量用next() 代替 nextLine() ,因为next()会过滤掉无用的换行符,减少输入类型的不匹配的问题。

4.收获:通过电信计费让我更加懂得了如何使用正则表达式控制输入,及如何记录时间及计算时间间隔,会用新的方法处理不满一分钟的情况等,对类的设计也更加合理,相比从前编程的逻辑也更加清晰,类的使用更加顺手,处理类间关系时更加完善。对容器的有关用法更加熟练,使用继承关系,编写抽象方法,不同子类实现抽象方法,对这类的编写。

posted @ 2022-12-10 19:26  20207204  阅读(120)  评论(0)    收藏  举报