对近期题目集总结分析3
前言:对这次题目集阐述一下自己的看法,这几次的题目集主要考察我们近期对java知识点的学习情况,题目量虽然不多,但是难度从难到易;本次题目集主要考察我们对多类的运用,重点考查实现电信计费代码的编写。还有多态继承的测试运用。
电信计费系列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元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
代码实现
import java.lang.reflect.Array; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Scanner; public class Main { public static int check(String s) { if(s.equals("0791"))return 1; else if(s.equals("0790") || s.equals("0792") || s.equals("0793") || s.equals("0794")|| s.equals("0795")|| s.equals("0796") || s.equals("0797")|| s.equals("0798")|| s.equals("0799")|| s.equals("0701"))return 2; else return 3; } public static void main (String [] args) { Scanner in = new Scanner(System.in); Scanner sc = new Scanner(System.in); DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); ArrayList<User>users = new ArrayList<>(); String s; while(true) { s = in.nextLine(); if(s.charAt(0) != 'u')break; else { String [] ss = s.split(" "); String phoneNumber = ss[0].substring(2); User user = new User(phoneNumber); user.setChargeMode(new LandlinePhoneCharging()); users.add(user); } } Arrays.sort(new ArrayList[]{users}); s = s.substring(2); String [] ss = s.split(" "); String startTime; String endTime; Date StartTime,EndTime; for(User user : users) { if(user.getNumber().equals(ss[0])) { String call = ss[0].substring(0, 4); String receive = ss[1].substring(0, 4); startTime = ss[2] + " " + ss[3]; endTime = ss[4] + " " + ss[5]; //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { continue; } // CallRecord callRecord = new CallRecord(); if(check(receive)== 1) { user.getUserRecords().addCallingInCityRecord(new CallRecord(StartTime, EndTime, call, receive)); }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime,call,receive)); else user.getUserRecords().addCallingInLandRecord(new CallRecord(StartTime, EndTime,call,receive)); } } while(true) { s = in.nextLine(); if(s.equals("end"))break; s = s.substring(2); String [] sss = s.split(" "); String sstartTime; String eendTime; Date SStartTime,EEndTime; for(User user : users) { if(user.getNumber().equals(sss[0])) { String call = sss[0].substring(0, 4); String receive = sss[1].substring(0, 4); sstartTime = sss[2] + " " + sss[3]; eendTime = sss[4] + " " + sss[5]; //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode try { SStartTime = dateFormat.parse(sstartTime); } catch (ParseException e) { continue; } try { EEndTime = dateFormat.parse(eendTime); } catch (ParseException e) { continue; } // CallRecord callRecord = new CallRecord(); if(check(receive) == 1) { user.getUserRecords().addCallingInCityRecord(new CallRecord(SStartTime, EEndTime, call, receive)); }else if(check(receive) == 2)user.getUserRecords().addCallingInProvinceRecord(new CallRecord(SStartTime, EEndTime,call,receive)); else user.getUserRecords().addCallingInLandRecord(new CallRecord(SStartTime, EEndTime,call,receive)); } } } for(User user : users) { System.out.printf("%s %.1f %.1f\n",user.getNumber(),user.calCost(),user.calBalance()); } //String time = s.substring(s.length() - ) } } abstract class CallChargeRule extends ChargeRule{ abstract double calCost(ArrayList<CallRecord>callRecords); } class CallRecord extends CommunicationRecord{ Date startTime; Date endTime; String callingAddressAreaCode; String answerAddressAreaCode; public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { this.startTime = startTime; this.endTime = endTime; this.callingAddressAreaCode = callingAddressAreaCode; this.answerAddressAreaCode = answerAddressAreaCode; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } abstract class ChargeMode { ArrayList<ChargeRule> chargeRules = new ArrayList<>(); public ArrayList<ChargeRule> getChargeRules() { return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } abstract double calCost(UserRecords userRecords); abstract double getMonthlyRent(); } abstract class ChargeRule { abstract double calCost(ArrayList<CallRecord> callRecords); } class CommunicationRecord { String callingNumber; String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } class LandlinePhoneCharging extends ChargeMode{ double monthlyRent = 20; public LandlinePhoneCharging() { getChargeRules().add(new LandPhoneCityRule()); getChargeRules().add(new LandPhoneLandRule()); getChargeRules().add(new LandPhoneProvinceRule()); } @Override double calCost(UserRecords userRecords) { double cost = 0; cost = getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) + getChargeRules().get(1).calCost(userRecords.getCallingInLandRecord()) + getChargeRules().get(2).calCost(userRecords.getCallingInProvinceRecord()); return cost; } @Override public double getMonthlyRent() { return monthlyRent; } } class LandPhoneCityRule extends CallChargeRule{ @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord land : callRecords) { double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - land.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.1 * sumTimeMinutes; } return cost; } } class LandPhoneLandRule extends CallChargeRule{ @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord land : callRecords) { double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - land.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.6 * sumTimeMinutes; } return cost; } } class LandPhoneProvinceRule extends CallChargeRule{ @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord land : callRecords) { double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - land.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.3 * sumTimeMinutes; } return cost; } } class MessageRecord extends CommunicationRecord{ String message ; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } class B{private static double pointToLine(double x1, double y1, double x2, double y2, double x0, double y0) { double space = 0; double a, b, c; a = lineSpace(x1, y1, x2, y2);// 线段的长度 b = lineSpace(x1, y1, x0, y0);// (x1,y1)到点的距离 c = lineSpace(x2, y2, x0, y0);// (x2,y2)到点的距离 if (c <= 0.000001 || b <= 0.000001) { space = 0; return space; } if (a <= 0.000001) { space = b; return space; } if (c * c >= a * a + b * b) { space = b; return space; } if (b * b >= a * a + c * c) { space = c; return space; } double p = (a + b + c) / 2;// 半周长 double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积 space = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高) return space; } // 计算两点之间的距离 private static double lineSpace(double x1, double y1, double x2, double y2) { double lineLength = 0; lineLength = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); return lineLength; } public static double ESP = 0.001; public static boolean isChonghe(float a, float b,float c, float d){ return ( a==c && b==d); } public static boolean islegal(float a, float c) { //是否垂直与x // System.out.println("Slope does not exist"); return !(Math.abs(a - c) < ESP); } public static float xielv(float a, float b, float c, float d) { //计算斜率 if (b == d) return 0; return (float)((float)(d - b) / (float)(c - a)); } public static void getIntersectPoint(float a, float b,float c, float d,float aa, float bb,float cc, float dd){ float A1=b-d; float B1=c-a; float C1=(float)A1*a+(float)B1*b; float A2=bb-dd; float B2=cc-aa; float C2=(float)A2*aa+B2*bb; float det_k=(float)A1*B2-A2*B1; float a1= (float)B2/det_k; float b1=(float)-1*B1/det_k; float c1=(float)-1*A2/det_k; float d1=(float)A1/det_k; float x=(float)a1*C1+b1*C2; float y=(float)c1*C1+d1*C2; if(x==0.0)x=Math.abs(x); if(y==0.0)y=Math.abs(y); System.out.print(x + "," + y); System.out.print(" "); if( ( ((x>a&&x<c) && (y>b&&y<d)) && ((x>aa&&x<cc) && (y>bb&&y<dd)) ) )System.out.print("true"); else System.out.print("false"); } public static void prtXunHuan(float a){ if((a*1000 % 10) !=0)System.out.printf("%.6f",a); else System.out.print(a); }} class A{ public static double ESP = 0.001; public static boolean isChonghe(float a, float b,float c, float d){ return ( a==c && b==d); } public static boolean islegal(float a, float c) { //是否垂直与x // System.out.println("Slope does not exist"); return !(Math.abs(a - c) < ESP); } public static float xielv(float a, float b, float c, float d) { //计算斜率 if (b == d) return 0; return (float)((float)(d - b) / (float)(c - a)); } public static void getIntersectPoint(float a, float b,float c, float d,float aa, float bb,float cc, float dd){ float A1=b-d; float B1=c-a; float C1=(float)A1*a+(float)B1*b; float A2=bb-dd; float B2=cc-aa; float C2=(float)A2*aa+B2*bb; float det_k=(float)A1*B2-A2*B1; float a1= (float)B2/det_k; float b1=(float)-1*B1/det_k; float c1=(float)-1*A2/det_k; float d1=(float)A1/det_k; float x=(float)a1*C1+b1*C2; float y=(float)c1*C1+d1*C2; if(x==0.0)x=Math.abs(x); if(y==0.0)y=Math.abs(y); System.out.print(x + "," + y); System.out.print(" "); if( ( ((x>a&&x<c) && (y>b&&y<d)) && ((x>aa&&x<cc) && (y>bb&&y<dd)) ) )System.out.print("true"); else System.out.print("false"); }} class User { UserRecords userRecords = new UserRecords(); double balance = 100; ChargeMode chargeMode; String number; public User(String number) { this.number = number; } double calBalance() { return getBalance() - calCost() - chargeMode.getMonthlyRent(); } double calCost(){ return chargeMode.calCost(userRecords); } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } class UserRecords { ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>callingInLandRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>answerInCityRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>answerInProvinceRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>answerInLandRecords = new ArrayList<CallRecord>(); ArrayList<MessageRecord>sendMessageRecords = new ArrayList<MessageRecord>(); ArrayList<MessageRecord>receiveMessageRecords = new ArrayList<MessageRecord>(); public void addCallingInCityRecord(CallRecord callRecord) { callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecord(CallRecord callRecord) { callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecord(CallRecord callRecord) { callingInLandRecords.add(callRecord); } public void answerInCityRecord(CallRecord callRecord) { answerInCityRecords.add(callRecord); } public void answerInProvinceRecord(CallRecord callRecord) { answerInProvinceRecords.add(callRecord); } public void answerInLandRecord(CallRecord callRecord) { answerInLandRecords.add(callRecord); } public void addSendMessageRecords(MessageRecord sendMessageRecord) { sendMessageRecords.add(sendMessageRecord); } public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) { receiveMessageRecords.add(receiveMessageRecord); } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public ArrayList<CallRecord> getCallingInProvinceRecord() { return callingInProvinceRecords; } public ArrayList<CallRecord> getCallingInLandRecord() { return callingInLandRecords; } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public ArrayList<MessageRecord> getSendMessageRecord() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecord() { return receiveMessageRecords; } }
代码实现 根据所给类图进行类的编写 对输入的数据进行提取,调用类进行计算,运用正则表达式处理用户输入数据。
多态测试
定义容器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位。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String str = new String(); int i = in.nextInt(); Cube cu[] = new Cube[i]; Cylinder cy[] = new Cylinder[i]; int a = 0,b = 0; double S=0 , V=0 ; for (int j = 0; j < i; j++) { str = in.next(); if (str.equalsIgnoreCase("cube")) { double y = in.nextDouble(); cu[a] = new Cube(y); a++; } else if (str.equalsIgnoreCase("cylinder")) { double r = in.nextDouble(); double h = in.nextDouble(); cy[b] = new Cylinder(r,h); b++; } } S+=Container.sumofArea(cu) ; V+=Container.sumofVolume(cu) ; S+=Container.sumofArea(cy) ; V+=Container.sumofVolume(cy) ; System.out.println(String.format("%.2f",S)); System.out.println(String.format("%.2f",V)); } } interface Container{ double pi=3.1415926; double area(); double volume(); static double sumofArea(Container c[]){ double S = 0 ; int i = 0 ; while(c[i]!=null) { S+=c[i].area(); i++; } return S ; } static double sumofVolume(Container c[]){ double V = 0 ; int i = 0 ; while(c[i]!=null) { V+=c[i].volume(); i++; } return V; } } class Cube implements Container{ double a ; public Cube(double a) { this.a = a; } public double area(){ return 6*a*a; } @Override public double volume() { return a*a*a; } } class Cylinder implements Container{ double r ; double h ; public Cylinder(double r ,double h) { this.r = r; this.h = h ; } public double area(){ return 2*pi*r*r+2*pi*r*h ; } @Override public double volume() { return pi*r*r*h; } }
代码实现 运用接口调用多类提取数据进行运算。
电信计费系列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)。
注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class Main { static boolean checkString(String str) { //月份:((((20)\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\d|3[01]))|(((19|20)\d{2}).(0?[469]|11).(0?[1-9]|[12]\d|30))|(((19|20)\d{2}).0?2.(0?[1-9]|1\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] //座机打座机 //座机打手机 t-0[0-9]{10,11} 1[0-9]{10} [0-9]{3,4} if(str.matches("t-0[0-9]{10,11} 0[0-9]{9,11} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]")) return true; else if(str.matches("t-0[0-9]{10,11} 1[0-9]{10} [0-9]{3,4} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]")) return true; else if(str.matches("t-1[0-9]{10} [0-9]{3,4} 0[0-9]{9,11} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]")) return true; else if(str.matches("t-1[0-9]{10} [0-9]{3,4} 1[0-9]{10} [0-9]{3,4} ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] ((((20)\\d{2}).(0?[13578]|1[02]).(0?[1-9]|[12]\\d|3[01]))|(((19|20)\\d{2}).(0?[469]|11).(0?[1-9]|[12]\\d|30))|(((19|20)\\d{2}).0?2.(0?[1-9]|1\\d|2[0-8]))) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]")) return true; //手机打座机 //手机打手机 //if(str.matches()) else return false; } static boolean checkFirst(String s) { if(s.matches("u-0[0-9]{10,11} [0-1]")) return true; if(s.matches("u-1[0-9]{10} [0-1]"))return true; return false; } public static boolean checkillegal(String[] s) { for (int i = 0; i <= 1; i++) { if (s[i].length() < 7) return true; for (int j = 0; j < s[i].length(); i++) { if (s[i].charAt(j) < '0' || s[i].charAt(j) > '9') return true; } } return false; } public static int checkCode(String s) { if (s.equals("0791")) return 1;//市内 else if (s.equals("0790") || s.equals("0792") || s.equals("0793") || s.equals("0794") || s.equals("0795") || s.equals("0796") || s.equals("0797") || s.equals("0798") || s.equals("0799") || s.equals("0701")) return 2;//省内 else return 3;//国内 } public static void main(String[] args) { Scanner in = new Scanner(System.in); DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); ArrayList<User> users = new ArrayList<>(); String [] s = new String[100]; int i = 0; while(true) { s[i] = in.nextLine(); if(s[i].equals("end"))break; i ++; } for(int j = 0;j < i;j ++) { if(s[j].charAt(0) == 'u') { if (s[j].equals("")) continue; if (checkFirst(s[j]) == false) continue; String[] ss = s[j].split(" "); String phoneNumber = ss[0].substring(2); boolean f = false; for (User user : users) if (user.getNumber().equals(phoneNumber)) { f = true; break; } if (f) continue; User user = new User(phoneNumber); if (s[j].charAt(s[j].length() - 1) == '0')user.setChargeMode(new LandlinePhoneCharging()); else user.setChargeMode(new MobilePhoneCharging()); users.add(user); } } for(int j = 0;j < i;j ++) { if(s[j].equals(""))continue; if(s[j].charAt(0) == 't') { if (checkString(s[j]) == true) { s[j] = s[j].substring(2); String[] ss = s[j].split(" "); String startTime; String endTime; Date StartTime = null, EndTime = null; boolean haveEfficient = false; for (User user : users) { if (user.getNumber().equals(ss[0])) { haveEfficient = true; if (ss.length == 6) { String call = ss[0].substring(0, 4); String receive = ss[1].substring(0, 4); startTime = ss[2] + " " + ss[3]; endTime = ss[4] + " " + ss[5]; //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { continue; } if (checkCode(receive) == 1) {String n = in.next();float num = in.nextInt(); float a = in.nextInt(),b = in.nextInt(); int c = in.nextInt(),d = in.nextInt(); c = in.nextInt();d = in.nextInt(); c = in.nextInt();d = in.nextInt(); System.out.printf("中国银行欢迎您的到来!\n" + "您的余额有%.1f元。\n" + "您的密码错误!\n" + "您的余额不足!\n" + "请取走钞票,您的余额还有%.1f元。\n" + "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);} else if (checkCode(receive) == 2) user.getUserRecords().addCallingInProvinceRecord(new CallRecord(StartTime, EndTime, call, receive)); else { float a = in.nextInt(),b = in.nextInt(); int c = in.nextInt(),d = in.nextInt(); c = in.nextInt();d = in.nextInt(); c = in.nextInt();d = in.nextInt(); System.out.printf("中国银行欢迎您的到来!\n" + "您的余额有%.1f元。\n" + "您的密码错误!\n" + "您的余额不足!\n" + "请取走钞票,您的余额还有%.1f元。\n" + "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);} }else if(ss.length == 8) { String call = ss[1]; String receive = ss[3]; startTime = ss[4] + " " + ss[5]; endTime = ss[6] + " " + ss[7]; //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { continue; } if(checkCode(call) == 1 && checkCode(receive) == 1) {String n = in.next();float num = in.nextInt(); float a = in.nextInt(),b = in.nextInt(); int c = in.nextInt(),d = in.nextInt(); c = in.nextInt();d = in.nextInt(); c = in.nextInt();d = in.nextInt(); System.out.printf("中国银行欢迎您的到来!\n" + "您的余额有%.1f元。\n" + "您的密码错误!\n" + "您的余额不足!\n" + "请取走钞票,您的余额还有%.1f元。\n" + "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);}else if(checkCode(call) == 1 && checkCode(receive) == 2) {String n = in.next();float num = in.nextInt(); float a = in.nextInt(),b = in.nextInt(); int c = in.nextInt(),d = in.nextInt(); c = in.nextInt();d = in.nextInt(); c = in.nextInt();d = in.nextInt(); System.out.printf("中国银行欢迎您的到来!\n" + "您的余额有%.1f元。\n" + "您的密码错误!\n" + "您的余额不足!\n" + "请取走钞票,您的余额还有%.1f元。\n" + "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);}else if(checkCode(call) == 1 && checkCode(receive) == 3){ user.getUserRecords().getMobilePhoneCityCallLand().add(new CallRecord(StartTime, EndTime, call, receive)); ///判断接听电话的有没有开户 for(User user1 : users) { if(user1.getNumber().equals(ss[2]) == true) { user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); break; } } }else if(checkCode(call) == 2){ user.getUserRecords().getMobilePhoneProvincialRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive)); if(checkCode(receive) == 3) { for(User user1 : users) { if(user1.getNumber().equals(ss[2]) == true) { user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); break; } } } }else if(checkCode(call) == 3){ user.getUserRecords().getMobilePhoneDomesticRoamingCall().add(new CallRecord(StartTime, EndTime, call, receive)); if(checkCode(receive) == 3) { for(User user1 : users) { if(user1.getNumber().equals(ss[2]) == true) { user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); break; } } } } }else if(ss.length == 7) { if(ss[0].charAt(0) == '1')//手机打座机 {String n = in.next();float num = in.nextInt(); float a = in.nextInt(),b = in.nextInt(); int c = in.nextInt(),d = in.nextInt(); c = in.nextInt();d = in.nextInt(); c = in.nextInt();d = in.nextInt(); System.out.printf("中国银行欢迎您的到来!\n" + "您的余额有%.1f元。\n" + "您的密码错误!\n" + "您的余额不足!\n" + "请取走钞票,您的余额还有%.1f元。\n" + "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);}else//座机打手机 { String call = ss[0].substring(0, 4); String receive = ss[2]; startTime = ss[3] + " " + ss[4]; endTime = ss[5] + " " + ss[6]; //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { continue; } if(checkCode(receive) == 1) { user.getUserRecords().getCallingInCityRecords().add(new CallRecord(StartTime, EndTime, call, receive)); }else if(checkCode(receive) == 2) { user.getUserRecords().getCallingInProvinceRecord().add(new CallRecord(StartTime, EndTime, call, receive)); } else if (checkCode(receive) == 3) { user.getUserRecords().getCallingInLandRecord().add(new CallRecord(StartTime, EndTime, call, receive)); for(User user1 : users) if(user1.getNumber().equals(ss[1]) == true) { user1.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); break; } } } } } } if(haveEfficient == false) { if(ss.length == 8) {String n = in.next();float num = in.nextInt(); float a = in.nextInt(),b = in.nextInt(); int c = in.nextInt(),d = in.nextInt(); c = in.nextInt();d = in.nextInt(); c = in.nextInt();d = in.nextInt(); System.out.printf("中国银行欢迎您的到来!\n" + "您的余额有%.1f元。\n" + "您的密码错误!\n" + "您的余额不足!\n" + "请取走钞票,您的余额还有%.1f元。\n" + "请收好您的证件和物品,欢迎您下次光临!\n",b,b-d);}else if(ss.length == 7 && ss[0].charAt(0) == '0') { String call = ss[0].substring(0,4); String receive = ss[2]; startTime = ss[3] + " " + ss[4]; endTime = ss[5] + " " + ss[6]; try { StartTime = dateFormat.parse(startTime); } catch (ParseException e) { // continue; } try { EndTime = dateFormat.parse(endTime); } catch (ParseException e) { // continue; } //Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode ///判断接听电话的有没有开户 for(User user : users) if(user.getNumber().equals(ss[1])) if (checkCode(receive) == 3) { user.getUserRecords().getMobilePhoneRoamingAnsweringOutsideProvince().add(new CallRecord(StartTime, EndTime, call, receive)); } } } } } } //座机打座机 座机打手机 手机打座机 手机打手机 TreeMap<String, User> treeMap = new TreeMap<>(); for (User user : users) { treeMap.put(user.getNumber(), user); } Iterator<User> t = treeMap.values().iterator(); while (t.hasNext()) { User user = t.next(); System.out.println(user.number + " " + user.calCost() + " " + user.calBalance()); } } private static double pointToLine(double x1, double y1, double x2, double y2, double x0, double y0) { double space = 0; double a, b, c; a = lineSpace(x1, y1, x2, y2);// 线段的长度 b = lineSpace(x1, y1, x0, y0);// (x1,y1)到点的距离 c = lineSpace(x2, y2, x0, y0);// (x2,y2)到点的距离 if (c <= 0.000001 || b <= 0.000001) { space = 0; return space; } if (a <= 0.000001) { space = b; return space; } if (c * c >= a * a + b * b) { space = b; return space; } if (b * b >= a * a + c * c) { space = c; return space; } double p = (a + b + c) / 2;// 半周长 double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积 space = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高) return space; } // 计算两点之间的距离 private static double lineSpace(double x1, double y1, double x2, double y2) { double lineLength = 0; lineLength = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); return lineLength; } public static double ESP = 0.001; public static boolean isChonghe(float a, float b,float c, float d){ return ( a==c && b==d); } public static boolean islegal(float a, float c) { //是否垂直与x // System.out.println("Slope does not exist"); return !(Math.abs(a - c) < ESP); } public static float xielv(float a, float b, float c, float d) { //计算斜率 if (b == d) return 0; return (float)((float)(d - b) / (float)(c - a)); } public static void getIntersectPoint(float a, float b,float c, float d,float aa, float bb,float cc, float dd){ float A1=b-d; float B1=c-a; float C1=(float)A1*a+(float)B1*b; float A2=bb-dd; float B2=cc-aa; float C2=(float)A2*aa+B2*bb; float det_k=(float)A1*B2-A2*B1; float a1= (float)B2/det_k; float b1=(float)-1*B1/det_k; float c1=(float)-1*A2/det_k; float d1=(float)A1/det_k; float x=(float)a1*C1+b1*C2; float y=(float)c1*C1+d1*C2; if(x==0.0)x=Math.abs(x); if(y==0.0)y=Math.abs(y); System.out.print(x + "," + y); System.out.print(" "); if( ( ((x>a&&x<c) && (y>b&&y<d)) && ((x>aa&&x<cc) && (y>bb&&y<dd)) ) )System.out.print("true"); else System.out.print("false"); } public static void prtXunHuan(float a){ if((a*1000 % 10) !=0)System.out.printf("%.6f",a); else System.out.print(a); } public abstract static class ChargeRule { abstract double calCost(ArrayList<CallRecord> callRecords); } public static class MobilePhoneCityCallCityRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.1 * sumTimeMinutes; } return cost; } } public static class MobilePhoneCharging extends ChargeMode{ double monthlyRent = 15; public MobilePhoneCharging () { getChargeRules().add(new MobilePhoneCityCallCityRule()); getChargeRules().add(new MobilePhoneCityCallProvinceRule()); getChargeRules().add(new MobilePhoneCityCallLandRule()); getChargeRules().add(new MobilePhoneDomesticRoamingCallRule()); getChargeRules().add(new MobilePhoneProvincialRoamingCallRule()); getChargeRules().add(new MobilePhoneRoamingAnsweringOutsideProvinceRule()); } @Override double calCost(UserRecords userRecords) { double cost = 0; cost = getChargeRules().get(0).calCost(userRecords.getMobilePhoneCityCallCity()) + getChargeRules().get(1).calCost(userRecords.getMobilePhoneCityCallProvince()) + getChargeRules().get(2).calCost(userRecords.getMobilePhoneCityCallLand()) + getChargeRules().get(3).calCost(userRecords.getMobilePhoneDomesticRoamingCall()) + getChargeRules().get(4).calCost(userRecords.getMobilePhoneProvincialRoamingCall()) + getChargeRules().get(5).calCost(userRecords.getMobilePhoneRoamingAnsweringOutsideProvince()); return cost; } @Override public double getMonthlyRent() { return monthlyRent; } } public abstract static class CallChargeRule extends ChargeRule { abstract double calCost(ArrayList<CallRecord> callRecords); } public static class MobilePhoneProvincialRoamingCallRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.3 * sumTimeMinutes; } return cost; } } public static class MessageRecord extends CommunicationRecord { String message ; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } public static class LandlinePhoneCharging extends ChargeMode { double monthlyRent = 20; public LandlinePhoneCharging() { getChargeRules().add(new LandPhoneCityRule()); getChargeRules().add(new LandPhoneLandRule()); getChargeRules().add(new LandPhoneProvinceRule()); } @Override double calCost(UserRecords userRecords) { double cost = 0; cost = getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()) + getChargeRules().get(1).calCost(userRecords.getCallingInLandRecord()) + getChargeRules().get(2).calCost(userRecords.getCallingInProvinceRecord()); return cost; } @Override public double getMonthlyRent() { return monthlyRent; } } public static class MobilePhoneCityCallProvinceRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.2 * sumTimeMinutes; } return cost; } } public static class CommunicationRecord { String callingNumber; String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } public static class LandPhoneLandRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord land : callRecords) { double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - land.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.6 * sumTimeMinutes; } return cost; } } public static class User { UserRecords userRecords = new UserRecords(); double balance = 100; ChargeMode chargeMode; String number; public User(String number) { this.number = number; } double calBalance() { return getBalance() - calCost() - chargeMode.getMonthlyRent(); } double calCost(){ return chargeMode.calCost(userRecords); } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } public static class CallRecord extends CommunicationRecord { Date startTime; Date endTime; String callingAddressAreaCode; String answerAddressAreaCode; public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { this.startTime = startTime; this.endTime = endTime; this.callingAddressAreaCode = callingAddressAreaCode; this.answerAddressAreaCode = answerAddressAreaCode; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } public static class MobilePhoneCityCallLandRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.3 * sumTimeMinutes; } return cost; } } public static class UserRecords { ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>callingInLandRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>answerInCityRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>answerInProvinceRecords = new ArrayList<CallRecord>(); ArrayList<CallRecord>answerInLandRecords = new ArrayList<CallRecord>(); ArrayList<MessageRecord>sendMessageRecords = new ArrayList<MessageRecord>(); ArrayList<MessageRecord>receiveMessageRecords = new ArrayList<MessageRecord>(); ArrayList<CallRecord> mobilePhoneCityCallCity = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneCityCallProvince = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneCityCallLand = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneDomesticRoamingCall = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneProvincialRoamingCall = new ArrayList<CallRecord>(); ArrayList<CallRecord> mobilePhoneRoamingAnsweringOutsideProvince = new ArrayList<CallRecord>(); public void addMobilePhoneCityCallCity(CallRecord callRecord){mobilePhoneCityCallCity.add(callRecord);}; public void addMobilePhoneCityCallProvince(CallRecord callRecord){mobilePhoneCityCallProvince.add(callRecord);}; public void addMobilePhoneCityCallLand(CallRecord callRecord){mobilePhoneCityCallLand.add(callRecord);}; public void addMobilePhoneDomesticRoamingCall(CallRecord callRecord){mobilePhoneDomesticRoamingCall.add(callRecord);}; public void addMobilePhoneProvincialRoamingCall(CallRecord callRecord){mobilePhoneProvincialRoamingCall.add(callRecord);}; public void addMobilePhoneRoamingAnsweringOutsideProvince(CallRecord callRecord){mobilePhoneRoamingAnsweringOutsideProvince.add(callRecord);}; public void addCallingInCityRecord(CallRecord callRecord) { callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecord(CallRecord callRecord) { callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecord(CallRecord callRecord) { callingInLandRecords.add(callRecord); } public void answerInCityRecord(CallRecord callRecord) { answerInCityRecords.add(callRecord); } public void answerInProvinceRecord(CallRecord callRecord) { answerInProvinceRecords.add(callRecord); } public void answerInLandRecord(CallRecord callRecord) { answerInLandRecords.add(callRecord); } public void addSendMessageRecords(MessageRecord sendMessageRecord) { sendMessageRecords.add(sendMessageRecord); } public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) { receiveMessageRecords.add(receiveMessageRecord); } public ArrayList<CallRecord> getMobilePhoneCityCallCity() { return mobilePhoneCityCallCity; } public ArrayList<CallRecord> getMobilePhoneCityCallProvince() { return mobilePhoneCityCallProvince; } public ArrayList<CallRecord> getMobilePhoneCityCallLand() { return mobilePhoneCityCallLand; } public ArrayList<CallRecord> getMobilePhoneDomesticRoamingCall() { return mobilePhoneDomesticRoamingCall; } public ArrayList<CallRecord> getMobilePhoneProvincialRoamingCall() { return mobilePhoneProvincialRoamingCall; } public ArrayList<CallRecord> getMobilePhoneRoamingAnsweringOutsideProvince() { return mobilePhoneRoamingAnsweringOutsideProvince; } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public ArrayList<CallRecord> getCallingInProvinceRecord() { return callingInProvinceRecords; } public ArrayList<CallRecord> getCallingInLandRecord() { return callingInLandRecords; } public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public ArrayList<MessageRecord> getSendMessageRecord() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecord() { return receiveMessageRecords; } } public abstract static class ChargeMode { ArrayList<ChargeRule> chargeRules = new ArrayList<>(); public ArrayList<ChargeRule> getChargeRules() { return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } abstract double calCost(UserRecords userRecords); abstract double getMonthlyRent(); } public static class MobilePhoneRoamingAnsweringOutsideProvinceRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.3 * sumTimeMinutes; } return cost; } } public static class LandPhoneProvinceRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord land : callRecords) { double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - land.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.3 * sumTimeMinutes; } return cost; } } public static class LandPhoneCityRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord land : callRecords) { double sumTimeMinutes = Math.ceil((double) (land.getEndTime().getTime() - land.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.1 * sumTimeMinutes; } return cost; } } public static class MobilePhoneDomesticRoamingCallRule extends CallChargeRule { @Override double calCost(ArrayList<CallRecord> callRecords) { double cost = 0; for(CallRecord c : callRecords) { double sumTimeMinutes = Math.ceil((double) (c.getEndTime().getTime() - c.getStartTime().getTime()) / 1000.0 / 60.0); cost += 0.6 * sumTimeMinutes; } return cost; } } }
运用正则表达式提取用户输入数据 。通过类储存用户信息。在调用uesr类进行多种运算
总结 本阶段学会运用父类继承。收悉类与类之间的关系。写代码熟练进行多种类结合调用。类的分类运用,合理进行代码框架的设计。编写代码熟练度提高。编译代码能力改善。

浙公网安备 33010602011771号