nchu-java 6-8次大作业总结
一、前言
1.知识点:
1.大作业六前言
第六次大作业一改往常的多边形大作业,而是电信计费类型的大作业,一开始接触的时候大概不太能够读懂题目,对比之前的,需要掌握的知识也越来越多。从无到有,从基础到深入,一步步的理解与掌握。当然,近期的大作业的难度对比之前的图形判读来说,在算法上的难度有所降低,但对我们的对学习的知识的理解与掌握的要求反而缺变的更高了,慢慢的有了一些基础框架,通过百度座机计费方式,和区号的区别,在写这到题是时候我想到了用正则表达式去解决判断格式是否正确的难题,以及学习使用SimpleDateFormate类来获取时间和时间差,之后将用户类和通讯记录类以及计费规则串联起来,通过反复的测试,最后将各个类跑了起来,这里值得一说的说我是先将用户存储进一个集合数组,再将通话记录存储进一个集合数组,之后再便利通话记录匹配用户名,找到每个用户对应的通话记录。
2.大作业七前言
第七次大作业是在上次的基础上加了一些新的需求,在做了第六次大作业的电信计费系列的座机收费后对电信计费系列的题有了基本的了解,但这题需要使用大量的正则表达式,这也很花时间在测试正则表达式的格式,这里麻烦的是有座机打座机,座机打手机,手机打座机,手机打手机,所以这里需要大量的判断去处理这些问题,这里还有一个难点就是漫游计费,其实是正则表达式去对区号先将用户存储进一个集合数组,再将通话记录存储进一个集合数组,之后再便利通话记录匹配用户名,找到每个用户对应的通话记录。
3.大作业八前言
第八次大作业相较之前相对容易了一些,由于只有短信计费,所以思考的方面也少了一些,主要难点还是在理解电信计费系列题目的类图,并编写正确的正则表达式完成字符串的筛选。
2.题量与难度:
题目的数量与以往相当,从第六次作业到第八次,通过具体的题目要求,逐步引导我们从面向过程的思维过渡到面向对象的思维。除此之外,这几次作业更注重培养我们简化代码的能力,将即繁杂又重复的代码转化为简洁清晰的代码是这几次作业注重的要点,总之,通过这三次练习,我明白了如何去更好的排序算法的运用。改善代码能使得系统具有较好的可复用性。 进一步深入理解面向对象设计原则中的“单一职责”原则和“开-闭”原则。在 ArrayList 工具类的使用,进一步掌握接口在面向对象程序设计中的作用。明白了各实体类之间的关系,尤其是一对多的组合关系,对实体类的设计要做到单一职责原则,且不能缺少规定的实体类。以及在“合成复用原则”及“单一职责原则”基础上,尽量对上次作业的程 序进行重构。
二、设计与分析
第六次作业
电信计费系列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.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
HashMap<String,User> map = new HashMap<String,User>();
while (true) {
String s = input.nextLine();
if (s.equals("end")) {
break;
} else {
if (s.matches("u-[0-9]{11,12}\\s0")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
User user = new User(100, s2[1]);
ChargeMode chargeMode = new LandlinePhoneCharging();
ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();
chargeRules.add(new LandPhonelnCityRule());
chargeRules.add(new LandPhonelnProvinceRule());
chargeRules.add(new LandPhonelnLandRule());
chargeMode.setChargeRules(chargeRules);
user.setChargeMode(chargeMode);
map.put(s2[1], user);
}
if (s.matches("t-[0-9]{11,12}\\s[0-9]{10,12}\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
if (map.containsKey(s2[1])) {
User user = map.get(s2[1]);
CallRecord callRecord = new CallRecord();
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
Date time1 = simpleDateFormat.parse(s1[2] + " " + s1[3]);
Date time2 = simpleDateFormat.parse(s1[4] + " " + s1[5]);
callRecord.setStartTime(time1);
callRecord.setEndTime(time2);
callRecord.setCallingAddressAreaCode(s2[1].substring(0, 4));
callRecord.setAnswerAddressAreaCode(s1[1].substring(0, 4));
callRecord.setCallingNumber(s2[1]);
callRecord.setAnswerNumber(s1[1]);
if (s1[1].substring(0, 3).equals("079") || s1[1].substring(0, 4).equals("0701")) {
if (s1[1].substring(0, 4).equals("0791")) {
user.userRecords.addCallinglnCityRecords(callRecord);
} else {
user.userRecords.addCallinglnProvinceRecords(callRecord);
}
} else {
user.userRecords.addCallinglnLandRecords(callRecord);
}
} catch (Exception ji) {
}
}
}
}
}
for (User value : map.values()) {
System.out.printf("%s %.1f %.1f\n",value.getNumber(),value.calCost(),value.calBalance());
}
}
}
class User{
UserRecords userRecords = new UserRecords();
double balance = 100;
ChargeMode chargeMode;
String number;
public double calCost(){
double sum=chargeMode.calCost(userRecords);
return sum;
}
public double calBalance(){
return balance-chargeMode.calCost(userRecords)-chargeMode.getMonthlyRent();
}
User(double balance, String number) {
this.balance = balance;
this.number = number;
}
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;
}
}
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();
}
class LandlinePhoneCharging extends ChargeMode{
double monthlyRent = 20;
@Override
public double calCost(UserRecords userRecords){
double sum=0;
sum+=getChargeRules().get(0).calCost(userRecords.getCallinglnCityRecords());
sum+=getChargeRules().get(1).calCost(userRecords.getCallinglnProvinceRecords());
sum+=getChargeRules().get(2).calCost(userRecords.getCallinglnLandRecords());
return sum;
}
@Override
public double getMonthlyRent() {
return monthlyRent;
}
}
class UserRecords{
ArrayList<CallRecord> callinglnCityRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnProvinceRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnLandRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> answerlnCityRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> answerlnProvinceRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> answerlnLandRecords = new ArrayList<CallRecord>();
ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
void addCallinglnCityRecords(CallRecord callRecord) {
callinglnCityRecords.add(callRecord);
}
void addCallinglnProvinceRecords(CallRecord callRecord) {
callinglnProvinceRecords.add(callRecord);
}
void addCallinglnLandRecords(CallRecord callRecord) {
callinglnLandRecords.add(callRecord);
}
void addAnswerlnCityRecords(CallRecord answerRecord) {
answerlnCityRecords.add(answerRecord);
}
void addAnswerlnProvinceRecords(CallRecord answerRecord) {
answerlnProvinceRecords.add(answerRecord);
}
void addAnswerlnLandRecords(CallRecord answerRecord) {
answerlnLandRecords.add(answerRecord);
}
void addSendMessageRecords(MessageRecord sendMessageRecord) {
sendMessageRecords.add(sendMessageRecord);
}
void addReceiveMessageRecords(MessageRecord receiveMessageRecord) {
receiveMessageRecords.add(receiveMessageRecord);
}
public ArrayList<CallRecord> getCallinglnCityRecords() {
return callinglnCityRecords;
}
public void setCallinglnCityRecords(ArrayList<CallRecord> callinglnCityRecords) {
this.callinglnCityRecords = callinglnCityRecords;
}
public ArrayList<CallRecord> getCallinglnProvinceRecords() {
return callinglnProvinceRecords;
}
public void setCallinglnProvinceRecords(ArrayList<CallRecord> callinglnProvinceRecords) {
this.callinglnProvinceRecords = callinglnProvinceRecords;
}
public ArrayList<CallRecord> getCallinglnLandRecords() {
return callinglnLandRecords;
}
public void setCallinglnLandRecords(ArrayList<CallRecord> callinglnLandRecords) {
this.callinglnLandRecords = callinglnLandRecords;
}
public ArrayList<CallRecord> getAnswerlnCityRecords() {
return answerlnCityRecords;
}
public void setAnswerlnCityRecords(ArrayList<CallRecord> answerlnCityRecords) {
this.answerlnCityRecords = answerlnCityRecords;
}
public ArrayList<CallRecord> getAnswerlnProvinceRecords() {
return answerlnProvinceRecords;
}
public void setAnswerlnProvinceRecords(ArrayList<CallRecord> answerlnProvinceRecords) {
this.answerlnProvinceRecords = answerlnProvinceRecords;
}
public ArrayList<CallRecord> getAnswerlnLandRecords() {
return answerlnLandRecords;
}
public void setAnswerlnLandRecords(ArrayList<CallRecord> answerlnLandRecords) {
this.answerlnLandRecords = answerlnLandRecords;
}
public ArrayList<MessageRecord> getSendMessageRecords() {
return sendMessageRecords;
}
public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
this.sendMessageRecords = sendMessageRecords;
}
public ArrayList<MessageRecord> getReceiveMessageRecords() {
return receiveMessageRecords;
}
public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
this.receiveMessageRecords = receiveMessageRecords;
}
}
abstract class CommunicationRecord{
String callingNumber;
String answerNumber;
abstract String getCallingNumber();
abstract void setCallingNumber(String callingNumber);
abstract String getAnswerNumber();
abstract void setAnswerNumber(String answerNumber);
}
class CallRecord extends CommunicationRecord{
Date startTime;
Date endTime;
String callingAddressAreaCode;
String 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;
}
@Override
String getCallingNumber() {
return null;
}
@Override
void setCallingNumber(String callingNumber) {
}
@Override
String getAnswerNumber() {
return null;
}
@Override
void setAnswerNumber(String answerNumber) {
}
}
class MessageRecord extends CommunicationRecord{
String message;
String getMessage() {
return null;
}
void setMessage(String message) {
}
@Override
String getCallingNumber() {
return null;
}
@Override
void setCallingNumber(String callingNumber) {
}
@Override
String getAnswerNumber() {
return null;
}
@Override
void setAnswerNumber(String answerNumber) {
}
}
abstract class ChargeRule{
abstract public double calCost(ArrayList<CallRecord> callRecords);
}
abstract class CallChargeRule extends ChargeRule{
abstract public double calCost(ArrayList<CallRecord> callRecords);
}
class LandPhonelnCityRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.1*((double)(second / 60)+1.0);
}else{
sum += 0.1*(double)(second / 60);
}
}
return sum;
}
}
class LandPhonelnProvinceRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.3*((double)(second / 60)+1.0);
}else{
sum += 0.3*(double)(second / 60);
}
}
return sum;
}
}
class LandPhonelnLandRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.6*((double)(second / 60)+1.0);
}else{
sum += 0.6*(double)(second / 60);
}
}
return sum;
}
}
代码的类图:
代码圈复杂度:
第六次大作业关键就是对题目的理解,主要的就是正则表达式的书写,而且可以去网站上学习了一下正则表达式,正则表达式这部分去判断格式还是很难写,在做题时,由于本题的代码量很大,总是出现错误,一般性的都是括号,空格和答案不一样,还有就是程序,程序报错主要原因也有,经常忘记添加 } ,以及 ; 这两个符号,一不留神就出错,然后检查半天才发现,还有就是,在命名数组的时候,因为喜欢用shuzu1,或者shuzu2之类的命名方式,导致出现数组越界的报错,这种情况在实际代码修改中,又不好处理,经常不知道是哪个数组,刚开始看类图不知道咋样将所以类串联起来,导致思考了很久不知道怎么开始,但后面硬着头皮根据类图去把一些基础的类创建起来,慢慢的有了一些基础框架,通过百度座机计费方式,和区号的区别,在写这到题是时候我想到了用正则表达式去解决判断格式是否正确的难题,以及学习使用SimpleDateFormate类来获取时间和时间差,之后将用户类和通讯记录类以及计费规则串联起来,通过反复的测试,最后将各个类跑了起来,这里值得一说的说我是先将用户存储进一个集合数组,再将通话记录存储进一个集合数组,之后再便利通话记录匹配用户名,找到每个用户对应的通话记录。
对用户类的设计:
对于计算费用的设计,市内国内等都是同样的思路:
第七次作业
电信计费系列2-手机+座机计费
实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
1、针对市内座机用户采用的计费方式(与电信计费系列1内容相同):
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
假设本市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
2、针对手机用户采用实时计费方式:
月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟;
注:被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
输入:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,含手机和座机用户
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题在电信计费系列1基础上增加类型1-手机实时计费。
手机设置0或者座机设置成1,此种错误可不做判断。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
输入格式增加手机接打电话以及收发短信的格式,手机接打电话的信息除了号码之外需要额外记录拨打/接听的地点的区号,比如:
座机打手机:
t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:
t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
HashMap<String,User> map = new HashMap<String,User>();
HashMap<String,User> map1 = new HashMap<String,User>();
ArrayList<String> list = new ArrayList<>();
ArrayList<String> list1 = new ArrayList<>();
while (true) {
String s = input.nextLine();
if (s.equals("end")) {
break;
} else {
if (s.matches("u-[0-9]{11}\\s(0|1)")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
User user = new User(100, s2[1]);
ChargeMode chargeMode = new MobilePhoneCharging();
ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();
chargeRules.add(new MobilePhonelnCityToCityRule());
chargeRules.add(new MobilePhonelnCityToProvinceRule());
chargeRules.add(new MobilePhonelnCityToLandRule());
chargeRules.add(new MobilePhonelnProvinceToCityRule());
chargeRules.add(new MobilePhonelnProvinceToProvinceRule());
chargeRules.add(new MobilePhonelnProvinceToLandRule());
chargeRules.add(new MobilePhonelnLandToCityRule());
chargeRules.add(new MobilePhonelnLandToProvinceRule());
chargeRules.add(new MobilePhonelnLandToLandRule());
chargeRules.add(new MobliePhonelnLandAnswerRule());
chargeMode.setChargeRules(chargeRules);
user.setChargeMode(chargeMode);
if(!map1.containsKey(s2[1])) {
map1.put(s2[1], user);
list1.add(s2[1]);
}
} else if (s.matches("u-[0-9]{11,12}\\s(0|1)")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
User user = new User(100, s2[1]);
ChargeMode chargeMode = new LandlinePhoneCharging();
ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();
chargeRules.add(new LandPhonelnCityRule());
chargeRules.add(new LandPhonelnProvinceRule());
chargeRules.add(new LandPhonelnLandRule());
chargeMode.setChargeRules(chargeRules);
user.setChargeMode(chargeMode);
if(!map.containsKey(s2[1])) {
map.put(s2[1], user);
list.add(s2[1]);
}
} else if (s.matches("t-[0-9]{11,12}\\s[0-9]{10,12}\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
if (map.containsKey(s2[1])) {
User user = map.get(s2[1]);
CallRecord callRecord = new CallRecord();
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
Date time1 = simpleDateFormat.parse(s1[2] + " " + s1[3]);
Date time2 = simpleDateFormat.parse(s1[4] + " " + s1[5]);
callRecord.setStartTime(time1);
callRecord.setEndTime(time2);
callRecord.setCallingAddressAreaCode(s2[1].substring(0, 4));
callRecord.setAnswerAddressAreaCode(s1[1].substring(0, 4));
callRecord.setCallingNumber(s2[1]);
callRecord.setAnswerNumber(s1[1]);
if (s1[1].substring(0, 3).equals("079") || s1[1].substring(0, 4).equals("0701")) {
if (s1[1].substring(0, 4).equals("0791")) {
user.userRecords.addCallinglnCityRecords(callRecord);
} else {
user.userRecords.addCallinglnProvinceRecords(callRecord);
}
} else {
user.userRecords.addCallinglnLandRecords(callRecord);
}
} catch (Exception ji) {
}
}
} else if (s.matches("t-[0-9]{10,12}\\s[0-9]{10,12}\\s[0-9]{3,4}\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
if (map.containsKey(s2[1]) || map1.containsKey(s1[1])) {
User user = null;
if (map.containsKey(s2[1])) {
user = map.get(s2[1]);
}
User user1 = null;
if (map1.containsKey(s1[1])) {
user1 = map1.get(s1[1]);
}
CallRecord callRecord = new CallRecord();
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
Date time1 = simpleDateFormat.parse(s1[3] + " " + s1[4]);
Date time2 = simpleDateFormat.parse(s1[5] + " " + s1[6]);
callRecord.setStartTime(time1);
callRecord.setEndTime(time2);
callRecord.setCallingAddressAreaCode(s2[1].substring(0, 4));
callRecord.setAnswerAddressAreaCode(s1[2]);
callRecord.setCallingNumber(s2[1]);
callRecord.setAnswerNumber(s1[1]);
if (s1[2].substring(0, 3).equals("079") || s1[2].substring(0, 4).equals("0701")) {
if (s1[2].substring(0, 4).equals("0791")) {
if (map.containsKey(s2[1])) user.userRecords.addCallinglnCityRecords(callRecord);
} else {
if (map.containsKey(s2[1])) user.userRecords.addCallinglnProvinceRecords(callRecord);
}
} else {
if (map.containsKey(s2[1])) user.userRecords.addCallinglnLandRecords(callRecord);
if (map1.containsKey(s1[1])) user1.userRecords.addCallinglnLandAnswerRecords(callRecord);
}
} catch (Exception ji) {
}
}
} else if (s.matches("t-[0-9]{10,12}\\s[0-9]{3,4}\\s[0-9]{10,12}\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
if (map1.containsKey(s2[1]) || map.containsKey(s1[2])) {
User user = null;
if (map1.containsKey(s2[1])) {
user = map1.get(s2[1]);
}
User user1 = null;
if (map.containsKey(s1[2])) {
user1 = map.get(s1[2]);
}
CallRecord callRecord = new CallRecord();
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
Date time1 = simpleDateFormat.parse(s1[3] + " " + s1[4]);
Date time2 = simpleDateFormat.parse(s1[5] + " " + s1[6]);
callRecord.setStartTime(time1);
callRecord.setEndTime(time2);
callRecord.setCallingAddressAreaCode(s1[1]);
callRecord.setAnswerAddressAreaCode(s1[2].substring(0, 4));
callRecord.setCallingNumber(s2[1]);
callRecord.setAnswerNumber(s1[2]);
if (s1[1].substring(0, 3).equals("079") || s1[1].equals("0701")) {
if (s1[1].equals("0791")) {
if (map1.containsKey(s2[1])) user.userRecords.addCallinglnCityToCityRecords(callRecord);
} else {
if (map1.containsKey(s2[1])) user.userRecords.addCallinglnProvinceToCityRecords(callRecord);
}
} else {
if (map1.containsKey(s2[1])) user.userRecords.addCallinglnLandToCityRecords(callRecord);
}
} catch (Exception ji) {
}
}
} else if (s.matches("t-[0-9]{10,12}\\s[0-9]{3,4}\\s[0-9]{10,12}\\s[0-9]{3,4}\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.([1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\.2\\.29))\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
if (map1.containsKey(s2[1]) || map.containsKey(s1[2])) {
User user = null;
if (map1.containsKey(s2[1])) {
user = map1.get(s2[1]);
}
User user1 = null;
if (map1.containsKey(s1[2])) {
user1 = map1.get(s1[2]);
}
CallRecord callRecord = new CallRecord();
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
Date time1 = simpleDateFormat.parse(s1[4] + " " + s1[5]);
Date time2 = simpleDateFormat.parse(s1[6] + " " + s1[7]);
callRecord.setStartTime(time1);
callRecord.setEndTime(time2);
callRecord.setCallingAddressAreaCode(s1[1]);
callRecord.setAnswerAddressAreaCode(s1[3]);
callRecord.setCallingNumber(s2[1]);
callRecord.setAnswerNumber(s1[2]);
if (s1[1].substring(0, 3).equals("079") || s1[1].substring(0, 4).equals("0701")) {
if (s1[1].substring(0, 4).equals("0791")) {
if (s1[3].substring(0, 3).equals("079") || s1[3].substring(0, 4).equals("0701")) {
if (s1[3].substring(0, 4).equals("0791")) {
if (map1.containsKey(s2[1])) user.userRecords.addCallinglnCityToCityRecords(callRecord);
} else {
if (map1.containsKey(s2[1])) user.userRecords.addCallinglnCityToProvinceRecords(callRecord);
}
} else {
if (map1.containsKey(s2[1])) user.userRecords.addCallinglnCityToLandRecords(callRecord);
if (map1.containsKey(s1[2])) user1.userRecords.addCallinglnLandAnswerRecords(callRecord);
}
} else {
if (map1.containsKey(s2[1])) user.userRecords.addCallinglnProvinceToCityRecords(callRecord);
if (!s1[3].substring(0, 3).equals("079") && !s1[3].substring(0, 4).equals("0701")) {
if (map1.containsKey(s1[2])) user1.userRecords.addCallinglnLandAnswerRecords(callRecord);
}
}
} else {
if (map1.containsKey(s2[1])) user.userRecords.addCallinglnLandToCityRecords(callRecord);
if (!s1[3].substring(0, 3).equals("079") && !s1[3].substring(0, 4).equals("0701")) {
if (map1.containsKey(s1[2])) user1.userRecords.addCallinglnLandAnswerRecords(callRecord);
}
}
} catch (Exception ji) {
}
}
}
}
}
Collections.sort(list);
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
User value = map.get(s);
System.out.printf("%s %.1f %.1f\n",value.getNumber(),value.calCost(),value.calBalance());
}
Collections.sort(list1);
Iterator<String> it1 = list1.iterator();
while (it1.hasNext()) {
String s = it1.next();
User value = map1.get(s);
System.out.printf("%s %.1f %.1f\n",value.getNumber(),value.calCost(),value.calBalance());
}
}
}
class User{
UserRecords userRecords = new UserRecords();
double balance = 100;
ChargeMode chargeMode;
String number;
public double calCost(){
double sum=chargeMode.calCost(userRecords);
return sum;
}
public double calBalance(){
return balance-chargeMode.calCost(userRecords)-chargeMode.getMonthlyRent();
}
User(double balance, String number) {
this.balance = balance;
this.number = number;
}
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;
}
}
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();
}
class MobilePhoneCharging extends ChargeMode{
double monthlyRent = 15;
@Override
double calCost(UserRecords userRecords) {
double sum=0;
sum+=getChargeRules().get(0).calCost(userRecords.getCallinglnCityToCityRecords());
sum+=getChargeRules().get(1).calCost(userRecords.getCallinglnCityToProvinceRecords());
sum+=getChargeRules().get(2).calCost(userRecords.getCallinglnCityToLandRecords());
sum+=getChargeRules().get(3).calCost(userRecords.getCallinglnProvinceToCityRecords());
sum+=getChargeRules().get(4).calCost(userRecords.getCallinglnProvinceToProvinceRecords());
sum+=getChargeRules().get(5).calCost(userRecords.getCallinglnProvinceToLandRecords());
sum+=getChargeRules().get(6).calCost(userRecords.getCallinglnLandToCityRecords());
sum+=getChargeRules().get(7).calCost(userRecords.getCallinglnLandToProvinceRecords());
sum+=getChargeRules().get(8).calCost(userRecords.getCallinglnLandToLandRecords());
sum+=getChargeRules().get(9).calCost(userRecords.getCallinglnLandAnswerRecords());
return sum;
}
@Override
double getMonthlyRent() {
return monthlyRent;
}
}
class LandlinePhoneCharging extends ChargeMode{
double monthlyRent = 20;
@Override
public double calCost(UserRecords userRecords){
double sum=0;
sum+=getChargeRules().get(0).calCost(userRecords.getCallinglnCityRecords());
sum+=getChargeRules().get(1).calCost(userRecords.getCallinglnProvinceRecords());
sum+=getChargeRules().get(2).calCost(userRecords.getCallinglnLandRecords());
return sum;
}
@Override
public double getMonthlyRent() {
return monthlyRent;
}
}
class UserRecords{
ArrayList<CallRecord> callinglnCityToCityRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnCityToProvinceRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnCityToLandRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnProvinceToCityRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnProvinceToProvinceRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnProvinceToLandRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnLandToCityRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnLandToProvinceRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnLandToLandRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnLandAnswerRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnCityRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnProvinceRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> callinglnLandRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> answerlnCityRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> answerlnProvinceRecords = new ArrayList<CallRecord>();
ArrayList<CallRecord> answerlnLandRecords = new ArrayList<CallRecord>();
ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
void addCallinglnCityRecords(CallRecord callRecord) {
callinglnCityRecords.add(callRecord);
}
void addCallinglnProvinceRecords(CallRecord callRecord) {
callinglnProvinceRecords.add(callRecord);
}
void addCallinglnLandRecords(CallRecord callRecord) {
callinglnLandRecords.add(callRecord);
}
void addAnswerlnCityRecords(CallRecord answerRecord) {
answerlnCityRecords.add(answerRecord);
}
void addAnswerlnProvinceRecords(CallRecord answerRecord) {
answerlnProvinceRecords.add(answerRecord);
}
void addAnswerlnLandRecords(CallRecord answerRecord) {
answerlnLandRecords.add(answerRecord);
}
void addSendMessageRecords(MessageRecord sendMessageRecord) {
sendMessageRecords.add(sendMessageRecord);
}
void addReceiveMessageRecords(MessageRecord receiveMessageRecord) {
receiveMessageRecords.add(receiveMessageRecord);
}
public ArrayList<CallRecord> getCallinglnCityRecords() {
return callinglnCityRecords;
}
public void setCallinglnCityRecords(ArrayList<CallRecord> callinglnCityRecords) {
this.callinglnCityRecords = callinglnCityRecords;
}
public ArrayList<CallRecord> getCallinglnProvinceRecords() {
return callinglnProvinceRecords;
}
public void setCallinglnProvinceRecords(ArrayList<CallRecord> callinglnProvinceRecords) {
this.callinglnProvinceRecords = callinglnProvinceRecords;
}
public ArrayList<CallRecord> getCallinglnLandRecords() {
return callinglnLandRecords;
}
public void setCallinglnLandRecords(ArrayList<CallRecord> callinglnLandRecords) {
this.callinglnLandRecords = callinglnLandRecords;
}
public ArrayList<CallRecord> getAnswerlnCityRecords() {
return answerlnCityRecords;
}
public void setAnswerlnCityRecords(ArrayList<CallRecord> answerlnCityRecords) {
this.answerlnCityRecords = answerlnCityRecords;
}
public ArrayList<CallRecord> getAnswerlnProvinceRecords() {
return answerlnProvinceRecords;
}
public void setAnswerlnProvinceRecords(ArrayList<CallRecord> answerlnProvinceRecords) {
this.answerlnProvinceRecords = answerlnProvinceRecords;
}
public ArrayList<CallRecord> getAnswerlnLandRecords() {
return answerlnLandRecords;
}
public void setAnswerlnLandRecords(ArrayList<CallRecord> answerlnLandRecords) {
this.answerlnLandRecords = answerlnLandRecords;
}
public ArrayList<MessageRecord> getSendMessageRecords() {
return sendMessageRecords;
}
public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
this.sendMessageRecords = sendMessageRecords;
}
public ArrayList<MessageRecord> getReceiveMessageRecords() {
return receiveMessageRecords;
}
public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
this.receiveMessageRecords = receiveMessageRecords;
}
public ArrayList<CallRecord> getCallinglnCityToCityRecords() {
return callinglnCityToCityRecords;
}
public ArrayList<CallRecord> getCallinglnCityToProvinceRecords() {
return callinglnCityToProvinceRecords;
}
public ArrayList<CallRecord> getCallinglnCityToLandRecords() {
return callinglnCityToLandRecords;
}
public ArrayList<CallRecord> getCallinglnProvinceToCityRecords() {
return callinglnProvinceToCityRecords;
}
public ArrayList<CallRecord> getCallinglnProvinceToProvinceRecords() {
return callinglnProvinceToProvinceRecords;
}
public ArrayList<CallRecord> getCallinglnProvinceToLandRecords() {
return callinglnProvinceToLandRecords;
}
public ArrayList<CallRecord> getCallinglnLandToCityRecords() {
return callinglnLandToCityRecords;
}
public ArrayList<CallRecord> getCallinglnLandToProvinceRecords() {
return callinglnLandToProvinceRecords;
}
public ArrayList<CallRecord> getCallinglnLandToLandRecords() {
return callinglnLandToLandRecords;
}
public ArrayList<CallRecord> getCallinglnLandAnswerRecords() {
return callinglnLandAnswerRecords;
}
public void addCallinglnLandAnswerRecords(CallRecord callRecord) {
callinglnLandAnswerRecords.add(callRecord);
}
public void addCallinglnCityToCityRecords(CallRecord callRecord) {
callinglnCityToCityRecords.add(callRecord);
}
public void addCallinglnCityToProvinceRecords(CallRecord callRecord) {
callinglnCityToProvinceRecords.add(callRecord);
}
public void addCallinglnCityToLandRecords(CallRecord callRecord) {
callinglnCityToLandRecords.add(callRecord);
}
public void addCallinglnProvinceToCityRecords(CallRecord callRecord) {
callinglnProvinceToCityRecords.add(callRecord);
}
public void addCallinglnProvinceToProvinceRecords(CallRecord callRecord) {
callinglnProvinceToProvinceRecords.add(callRecord);
}
public void addCallinglnProvinceToLandRecords(CallRecord callRecord) {
callinglnProvinceToLandRecords.add(callRecord);
}
public void addCallinglnLandToCityRecords(CallRecord callRecord) {
callinglnLandToCityRecords.add(callRecord);
}
public void addCallinglnLandToProvinceRecords(CallRecord callRecord) {
callinglnLandToProvinceRecords.add(callRecord);
}
public void addCallinglnLandToLandRecords(CallRecord callRecord) {
callinglnLandToLandRecords.add(callRecord);
}
}
abstract class CommunicationRecord{
String callingNumber;
String answerNumber;
abstract String getCallingNumber();
abstract void setCallingNumber(String callingNumber);
abstract String getAnswerNumber();
abstract void setAnswerNumber(String answerNumber);
}
class CallRecord extends CommunicationRecord{
Date startTime;
Date endTime;
String callingAddressAreaCode;
String 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;
}
@Override
String getCallingNumber() {
return null;
}
@Override
void setCallingNumber(String callingNumber) {
}
@Override
String getAnswerNumber() {
return null;
}
@Override
void setAnswerNumber(String answerNumber) {
}
}
class MessageRecord extends CommunicationRecord{
String message;
String getMessage() {
return null;
}
void setMessage(String message) {
}
@Override
String getCallingNumber() {
return null;
}
@Override
void setCallingNumber(String callingNumber) {
}
@Override
String getAnswerNumber() {
return null;
}
@Override
void setAnswerNumber(String answerNumber) {
}
}
abstract class ChargeRule{
abstract public double calCost(ArrayList<CallRecord> callinglnCityRecords);
}
abstract class CallChargeRule extends ChargeRule{
abstract public double calCost(ArrayList<CallRecord> callRecords);
}
class LandPhonelnCityRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.1 * ((double)(second / 60)+1.0);
}else{
sum += 0.1 * (double)(second / 60);
}
}
return sum;
}
}
class LandPhonelnProvinceRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.3 * ((double)(second / 60)+1.0);
}else{
sum += 0.3 * (double)(second / 60);
}
}
return sum;
}
}
class LandPhonelnLandRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.6 * ((double)(second / 60)+1.0);
}else{
sum += 0.6 * (double)(second / 60);
}
}
return sum;
}
}
class MobilePhonelnCityToCityRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.1 * ((double)(second / 60)+1.0);
}else{
sum += 0.1 * (double)(second / 60);
}
}
return sum;
}
}
class MobilePhonelnCityToProvinceRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.2 * ((double)(second / 60)+1.0);
}else{
sum += 0.2 * (double)(second / 60);
}
}
return sum;
}
}
class MobilePhonelnCityToLandRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.3 * ((double)(second / 60)+1.0);
}else{
sum += 0.3 * (double)(second / 60);
}
}
return sum;
}
}class MobilePhonelnProvinceToCityRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.3 * ((double)(second / 60)+1.0);
}else{
sum += 0.3 * (double)(second / 60);
}
}
return sum;
}
}
class MobilePhonelnProvinceToProvinceRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.3 * ((double)(second / 60)+1.0);
}else{
sum += 0.3 * (double)(second / 60);
}
}
return sum;
}
}
class MobilePhonelnProvinceToLandRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.3 * ((double)(second / 60)+1.0);
}else{
sum += 0.3 * (double)(second / 60);
}
}
return sum;
}
}
class MobilePhonelnLandToProvinceRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.6 * ((double)(second / 60)+1.0);
}else{
sum += 0.6 * (double)(second / 60);
}
}
return sum;
}
}
class MobilePhonelnLandToLandRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.6 * ((double)(second / 60)+1.0);
}else{
sum += 0.6 * (double)(second / 60);
}
}
return sum;
}
}
class MobilePhonelnLandToCityRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.6 * ((double)(second / 60)+1.0);
}else{
sum += 0.6 * (double)(second / 60);
}
}
return sum;
}
}
class MobliePhonelnLandAnswerRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum=0;
for (int i = 0; i < callRecords.size(); i++) {
long time1 = callRecords.get(i).getStartTime().getTime();
long time2 = callRecords.get(i).getEndTime().getTime();
long second = (time2 - time1) / 1000;
if (second % 60 != 0) {
sum += 0.3 * ((double)(second / 60)+1.0);
}else{
sum += 0.3 * (double)(second / 60);
}
}
return sum;
}
}
代码类图:
圈复杂度:
这道电信计费对代码的考察不仅是算法,语法知识的掌握与运用也是考察的一部分,当然通过电信计费让我更加懂得了如何使用正则表达式控制输入,也学会了许多新的知识与内容,及如何记录时间及计算时间间隔,最关键的则是类之间的关联与使用,而且通过这次作业我写代码的逻辑也更加清晰明了了,特别是对类图的理解,与辨别类图上类与类之间的关系也更加明白了。在本次代码中我对容器的有关用法更加熟练,使用继承关系,编写抽象方法,不同子类实现抽象方法,这样可以对复杂的代码进行一个很好的简化作用,在出错修改时也更加的方便。
本次作业对于正则表达式的设计,其主要作用是判断输入的是否合法:
第八次作业
电信计费系列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。
本题只考虑短信计费,不考虑通信费用以及月租费。
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
HashMap<String,User> map = new HashMap<String,User>();
HashMap<String,User> map1 = new HashMap<String,User>();
ArrayList<String> list = new ArrayList<>();
ArrayList<String> list1 = new ArrayList<>();
while (true) {
String s = input.nextLine();
if (s.equals("end")) {
break;
} else {
if (s.matches("u-[0-9]{11,12}\\s3")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
User user = new User(100, s2[1]);
ChargeMode chargeMode = new MobilePhoneCharging();
ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();
chargeRules.add(new SendMessageRule());
chargeMode.setChargeRules(chargeRules);
user.setChargeMode(chargeMode);
map1.put(s2[1], user);
list1.add(s2[1]);
}
if (s.matches("m-[0-9]{11,12}\\s[0-9]{10,12}\\s([0-9]|[a-z]|[A-Z]|,|\\.|\\s)+")) {
String[] s1 = s.split("\\s");
String s2[] = s1[0].split("-");
if (map1.containsKey(s2[1])) {
User user = map1.get(s2[1]);
MessageRecord messageRecord = new MessageRecord();
String s3 = s.substring(26, s.length());
messageRecord.setMessage(s3);
user.userRecords.addSendMessageRecords(messageRecord);
}
}
}
}
Collections.sort(list);
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
User value = map.get(s);
System.out.printf("%s %.1f %.1f\n",value.getNumber(),value.calCost(),value.calBalance());
}
Collections.sort(list1);
Iterator<String> it1 = list1.iterator();
while (it1.hasNext()) {
String s = it1.next();
User value = map1.get(s);
System.out.printf("%s %.1f %.1f\n",value.getNumber(),value.calCost(),value.calBalance());
}
}
}
class User{
UserRecords userRecords = new UserRecords();
double balance = 100;
ChargeMode chargeMode;
String number;
public double calCost(){
double sum=chargeMode.calCost(userRecords);
return sum;
}
public double calBalance(){
return balance-chargeMode.calCost(userRecords)-chargeMode.getMonthlyRent();
}
User(double balance, String number) {
this.balance = balance;
this.number = number;
}
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;
}
}
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();
}
class MobilePhoneCharging extends ChargeMode{
double monthlyRent = 0;
@Override
double calCost(UserRecords userRecords) {
double sum=0;
sum+=getChargeRules().get(0).calCost1(userRecords.getSendMessageRecords() );
return sum;
}
@Override
double getMonthlyRent() {
return monthlyRent;
}
}
public double getMonthlyRent() {
return monthlyRent;
}
}
class UserRecords{
ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
public ArrayList<MessageRecord> getSendMessageRecords() {
return sendMessageRecords;
}
public void addSendMessageRecords(MessageRecord message){
sendMessageRecords.add(message);
}
public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) {
this.sendMessageRecords = sendMessageRecords;
}
public ArrayList<MessageRecord> getReceiveMessageRecords() {
return receiveMessageRecords;
}
public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) {
this.receiveMessageRecords = receiveMessageRecords;
}
}
abstract class CommunicationRecord{
String callingNumber;
String answerNumber;
abstract String getCallingNumber();
abstract void setCallingNumber(String callingNumber);
abstract String getAnswerNumber();
abstract void setAnswerNumber(String answerNumber);
}
class CallRecord extends CommunicationRecord{
Date startTime;
Date endTime;
String callingAddressAreaCode;
String 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;
}
String getCallingNumber() {
return null;
}
void setCallingNumber(String callingNumber) {
}
String getAnswerNumber() {
return null;
}
void setAnswerNumber(String answerNumber) {
}
}
class MessageRecord extends CommunicationRecord{
String message;
String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
String getCallingNumber() {
return null;
}
void setCallingNumber(String callingNumber) {
}
String getAnswerNumber() {
return null;
}
void setAnswerNumber(String answerNumber) {
}
}
abstract class ChargeRule{
abstract public double calCost1(ArrayList<MessageRecord> messageRecords);
abstract public double calCost(ArrayList<CallRecord> callinglnCityRecords);
}
abstract class MessageChargeRule extends ChargeRule{
abstract public double calCost1(ArrayList<MessageRecord> messageRecords);
}
class SendMessageRule extends MessageChargeRule{
public double calCost(ArrayList<CallRecord> callinglnCityRecords) {
return 0;
}
public double calCost1(ArrayList<MessageRecord> messageRecords) {
double sum=0;
double l=0;
for (int i = 0; i < messageRecords.size(); i++) {
if(messageRecords.get(i).message.length()%10!=0) {
l+=messageRecords.get(i).message.length()/10+1;
}else{
l+=messageRecords.get(i).message.length()/10;
}
}
if(l<=3){
sum = 0.1*l;
}else{
if(l<=5){
sum=0.3+(l-3)*0.2;
}else{
sum = 0.7+(l-5)*0.3;
}
}
return sum;
}
}
abstract class CallChargeRule extends ChargeRule{
abstract public double calCost(ArrayList<CallRecord> callRecords);
}
代码类图:
圈复杂度:
本次作业算是一次小放水了【doge】,本题作为本学期最后一次的电信计费系列题目,只需要实现短信计费即可,相比于前两次的电信计费题目都更简单一些,因为这次作业并没有以之前两次的作业作为基础,因此代码的复杂程度也小了很少,总的代码也变少了,这里只需要用一个正则表达式来判断格式的正确与否,本次作业增加了一些跟需求有关的类,例如短信计费规则类,短信的计费类,因为本题针对手机用户收发短信进行计费。总体来说短信对于电话来说相对的简单一些,需要判断的情况也没有电话那么复杂,需要注意的就是短信条数的统计,短信计费是通过发送短信的条数进行的。
三、踩坑心得
1.刚开始写题的时候我想到了用正则表达式去解决判断格式是否正确的难题,以及学习使用SimpleDateFormate类来获取时间和时间差,之后将用户类和通讯记录类以及计费规则串联起来,通过反复的测试,最后将各个类跑了起来,这里值得一说的说我是先将用户存储进一个集合数组,再将通话记录存储进一个集合数组,之后再便利通话记录匹配用户名,找到每个用户对应的通话记录。
2.然后就是正则表达式,写好一个正则表达式真的很重要,它可以帮你判断很多东西,你只需要写出一个抽象的东西然后匹配所有符合他的字符串。
3.本次作业逻辑一定要清晰,电信计费的大作业就是需要很好的逻辑,我觉得只要逻辑清晰就写的挺好,就有了思路,按照那个思路就可以很快的写出来;
4.计算信息计费的时候要一条一条的算钱,我开始是先直接计算有几条信息,然后再计算每条信息的信息量,但是出了很大的问题,就还是要一条一条的算钱的好。
四、改进建议
在这三次作业我认为我需要去更多的了解类的设计和有关正则的方式。我在最后一题使用的合法性判断很杂是混合在各个功能中的,这样不仅大程度的提高了代码的复杂度而且可读性很低,大概只有我自己能弄的清楚的程度。老师在课上介绍了正则的方法去限定合法性,我还需要对其更深的了解直到能够熟练运用。具体要做的改进首先是用正则的方法写合法测试,再将多次项的分类作为一个类,此类中含整数项判断函数、一次项判断函数和多次项判断函数,主函数在进行筛选时就可以直接调用类中的函数,这样可以大幅的的减少重复代码,减少查重降低复杂度。
在作业中正则表达式还是有疏漏的,还得改一改,用法也是很灵活的,要好好学会如何使用。其次类的关系要厘清,有一个良好的类图关系,可以使逻辑更加清晰,使项目更容易完成。最后一点就是代码中可以创建一个切割方法进行字符串的切割,这样就不用每次都写一遍,使代码变得过于复杂对第二次作业我认为我函数内的代码行数还是太长,而且不是很清晰明了,希望自己以后条件判断还是多用switch case的条件语句,少用if else语句,让自己的代码变得更可读一些。类似的性质也可以做成类函数,就不会让代码那么长一串,用相应的英文函数名表示就明白多了。
五、总结
经过一学期的学习,总的自我总结就是个人能力不足,思考逻辑时不清晰,使用语法时不熟练,代码重构时不知道头绪,个人能力有待提高。在这学期里练习的PTA题目集、超星作业让我成长了很多,也学到了很多,但也出现过不少问题,在解决问题的过程中也有很多时候因为解决不了而着急,现在看来发现自己在这个过程中学到了很多,比如说三角形,四边形,五边形问题和电信收费系列这俩类题目给我留下了很深的印象,举例就是当类和对象聚合在一张大图时会导致我对它们之间的关系理不清,这说明我还需要多加练习,应用需要更加熟练。而且在写一些算法的时候因该要多写一些备注不然自己看的时候或者别人看的时候要思考很久这一段代码是干嘛的做什么用的。本学期老师上课讲的很清楚,解释的也很到位,最后就是要是能花点时间给我们讲讲大作业的题目集就好了。代码要更加完善,用更加巧妙地方法,这几次都是因为代码长度超出限制导致无法继续提交,证明我的代码还是有问题的。
再有就是自己在编程过程中需要养成更好的习惯,首先要习惯用面向对象的思维去思考问题、设计算法;其次,代码的书写要规范、美观、简略,这也方便自己查找错误,避免了很多不必要的麻烦。三次作业逐步引导我从面向对象程序设计的思维过渡到面向对象的程序设计思维我认为Java中的类和C语言中的函数有些联系,Java中的类就好像把好几个函数包在一个大函数里,然后主函数可以去调用这个大函数,但是它们之间的区别又是很明显的Java中的类是有性质和方法的是可以拥有实体的,C语言中的函数并不能。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界