BLOG-3
前言
最后的几次大作业都是围绕电信计费展开的,还有一些难度较小的题目。
就电信计费来说,是一个根据给出的类图来写程序的题目。所以我们只需要构建好已给的类,然后再正确补充好每个类的内容,这样我们就完成了很大一部分。但是所涉及到的类过多,难度还是挺大的对于我来说。这次大作业更加侧重点在抽象类的应用,虽然没有上次作业的关于计算的问题繁琐,但是在类中类的应用更加多。弄了挺久也没有弄出个啥。但是老师为了期末让我们的分数更高一点还是在最后降低了电信计费的难度,整个电信计费涉及到的类很多,也有很多方式比如市内接电话省外接电话之类的场景需要我们去实现相应的功能。只能说是尽力了在最后的几周。
设计与分析
7-1电信计费系列
实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
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.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Scanner;
abstract class CallChargeRule extends ChargeRule{
public abstract double calCost(ArrayList<CallRecord> callRecords);
}
class CallRecord extends CommunicationRecord{
private Date startTime;
private Date endTime;
private String callingAddressAreaCode;
private 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;
}
}
abstract class ChargeMode {
private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>();
public ArrayList<ChargeRule> getChargeRules(){
return chargeRules;
}
public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
this.chargeRules=chargeRules;
}
public abstract double calCost(UserRecords userRecords);
public abstract double getMonthlyRent();
}
abstract class ChargeRule {
}
abstract class CommunicationRecord {
private String callingNumber;//拨打电话
private 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 JudgeFormat {
public static int judge(String number) {
if( number.matches("u-0791\\d{7,9} 0") )
return 1;
else if( number.matches("u-1\\d{10} 1") )
return 2;
else if( number.matches("t-\\d{11,13} \\d{10,13} [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d") )
return 3;
else if ( number.matches("t-\\d{10,13} 1\\d{10} 0\\d{2,4} [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d") )
return 4;
else if ( number.matches("t-1\\d{10} 0\\d{3,5} 1\\d{10} 0\\d{2,4} [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d") )
return 5;/
else if( number.matches("t-1\\d{10} 0\\d{3,5} 0791\\d{7,9} [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d [1-9]\\d{3}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d") )
return 6;/
return 0;
}
}
class LandlinePhoneCharging extends ChargeMode{
private double monthlyRent=20;
@Override
public double calCost(UserRecords userRecords) {
double rent = 0;
ArrayList<CallRecord> callInCityRecords = userRecords.getCallingInCityRecords();
ArrayList<CallRecord> callInProvinceRecords = userRecords.getCallingInProvinceRecords();
ArrayList<CallRecord> callInLandRecords = userRecords.getCallingInLandRecords();
CallChargeRule landPhoneInCityRule = new LandPhoneInCityRule() ;
CallChargeRule landPhoneInProvinceRule = new LandPhoneInProvinceRule();
CallChargeRule landPhoneInLandRule = new LandPhoneInlandRule();
// CallChargeRule callChargeRule = new LandPhoneInCityRule();
rent+=landPhoneInCityRule.calCost(callInCityRecords);
// callChargeRule = new LandPhoneInProvinceRule();
rent+=landPhoneInProvinceRule.calCost(callInProvinceRecords);
// callChargeRule = new LandPhoneInlandRule();
rent+=landPhoneInLandRule.calCost(callInLandRecords);
return rent;
}
@Override
public double getMonthlyRent() {
return monthlyRent;
}
}
class LandPhoneInCityRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum = 0;
for(int i=0;i<callRecords.size();i++)
{
long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;
if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0)
min++;
sum+=0.1*min;
}
return sum;
}
}
class LandPhoneInlandRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum = 0;
for(int i=0;i<callRecords.size();i++)
{
long min=( (callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000 )/60;
if((((callRecords.get(i).getEndTime().getTime()
- callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0) {
min++;
}
sum+=0.6*min;
}
return sum;
}
}
class LandPhoneInProvinceRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum = 0;
for(int i=0;i<callRecords.size();i++)
{
long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) / 60;
if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0)
min++;
sum+=0.3*min;
}
return sum;
}
}
class MobilePhoneCharging extends ChargeMode{
private double monthlyRent=15;
@Override
public double calCost(UserRecords userRecords) {
double rent = 0;
CallChargeRule callChargeRule = new MobilePhoneInCityRule();
rent+=callChargeRule.calCost(userRecords.getCallingInCityRecords());
callChargeRule = new MobilePhoneInProvinceRule();
rent+=callChargeRule.calCost(userRecords.getCallingInProvinceRecords());
callChargeRule = new MobilePhoneInlandRule();
rent+=callChargeRule.calCost(userRecords.getCallingInLandRecords());
callChargeRule = new MobilePhoneRoamingAnswerOutProvince();
rent+=callChargeRule.calCost(userRecords.getAnswerInLandRecords());
callChargeRule = new MobilePhoneRoamingCallOutProvince();
rent+=callChargeRule.calCost(userRecords.getLcallingRecords());
rent+=callChargeRule.calCost(userRecords.getPcallingRecords());
return rent;
}
@Override
public double getMonthlyRent() {
return monthlyRent;
}
}
class MobilePhoneInCityRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum = 0;
for(int i=0;i<callRecords.size();i++)
{
long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;
if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0)
min++;
sum+=0.1*min;
}
return sum;
}
}
class MobilePhoneInlandRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum = 0;
for(int i=0;i<callRecords.size();i++)
{
long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;
if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0)
min++;
sum+=0.3*min;
}
return sum;
}
}
class MobilePhoneInProvinceRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum = 0;
for(int i=0;i<callRecords.size();i++)
{
long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;
if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0)
min++;
sum+=0.2*min;
}
return sum;
}
}
class MobilePhoneRoamingAnswerOutProvince extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum = 0;
for(int i=0;i<callRecords.size();i++)
{
long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;
if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0)
min++;
sum+=0.3*min;
}
return sum;
}
}
class MobilePhoneRoamingCallOutProvince extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum = 0;
for(int i=0;i<callRecords.size();i++)
{
long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;
if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0)
min++;
sum+=0.6*min;
}
return sum;
}
}
class MobilePhoneRoamingCallsInProvince extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
double sum = 0;
for(int i=0;i<callRecords.size();i++)
{
long min=((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000)/ 60;
if((((callRecords.get(i).getEndTime().getTime() - callRecords.get(i).getStartTime().getTime()) / 1000) % 60)!=0)
min++;
sum+=0.3*min;
}
return sum;
}
}
class User {
private UserRecords userRecords;
private double balance=100;
private ChargeMode chargeMode;
private String number;
public double calCost() {
double sum=chargeMode.calCost(userRecords);
balance-=(sum+chargeMode.getMonthlyRent());
return sum;
}
public UserRecords getUserRecords() {
return userRecords;
}
public void setUserRecords(UserRecords userRecords) {
this.userRecords = userRecords;
}
public double getBalance() {
return 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 User(ChargeMode chargeMode,String number) {
this.chargeMode=chargeMode;
this.number=number;
}
}
class UserRecords {
private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
public void addCallingInCityRecords(CallRecord callRecord) {
callingInCityRecords.add(callRecord);
}
public void addCallingInProvinceRecords(CallRecord callRecord) {
callingInProvinceRecords.add(callRecord);
}
public void addCallingInLandRecords(CallRecord callRecord) {
callingInLandRecords.add(callRecord);
}
public void addAnswerInCityRecords(CallRecord callRecord) {
answerInCityRecords.add(callRecord);
}
public void aaddAnswerInProvinceRecords(CallRecord callRecord) {
answerInProvinceRecords.add(callRecord);
}
public void addAnswerInLandRecords(CallRecord callRecord) {
answerInLandRecords.add(callRecord);
}
public void addSendMessageRecords(MessageRecord callRecord) {
sendMessageRecords.add(callRecord);
}
public void addReceiveMessageRecords(MessageRecord callRecord) {
receiveMessageRecords.add(callRecord);
}
public ArrayList<CallRecord> getCallingInCityRecords() {
return callingInCityRecords;
}
public void setCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) {
this.callingInCityRecords = callingInCityRecords;
}
public ArrayList<CallRecord> getCallingInProvinceRecords() {
return callingInProvinceRecords;
}
public void setCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) {
this.callingInProvinceRecords = callingInProvinceRecords;
}
public ArrayList<CallRecord> getCallingInLandRecords() {
return callingInLandRecords;
}
public void setCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) {
this.callingInLandRecords = callingInLandRecords;
}
public ArrayList<CallRecord> getAnswerInCityRecords() {
return answerInCityRecords;
}
public void setAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) {
this.answerInCityRecords = answerInCityRecords;
}
public ArrayList<CallRecord> getAnswerInProvinceRecords() {
return answerInProvinceRecords;
}
public void setAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) {
this.answerInProvinceRecords = answerInProvinceRecords;
}
public ArrayList<CallRecord> getAnswerInLandRecords() {
return answerInLandRecords;
}
public void setAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) {
this.answerInLandRecords = answerInLandRecords;
}
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;
}
}
踩坑心得
本次大作业主要运用到的抽象类的知识较多,但是我由于对父类抽象类的知识还不够太理解,所以导致在构建整个程序的时候就废了很大的心思但是也没搞出来什么东西。而且在正则表达式这一方面仍需提高,去判断输入的格式是否正确。即使给出了类图,还是难以去书写因为包含的类过多,在我个人书写代码的时候还是避免不了冗长的代码,说明代码的重复太高了,以后也会多注意点的。
总结
这几个习题集中我取得的成绩都不太理想,主要原因是对于抽象继承的问题掌握不透彻,加上程序的构建需要考虑以及类与类之间关系,对于现在的我来说实在是无能为力了。
在习题7还是过于复杂由于不知道从何下手所以就没办法。因为自己写的还是存在不足,不是完完全全靠着自己写的代码来实现,说明我对类的设计这一块还存在许多欠缺。而且对于继承与多态难运用,主要是没有掌握好,加上的话会让我的代码更多bug了,这也是我的不足。
在接下来的学习里我更应该好好学习抽象类以及继承关系的方法,让代码的结构更清晰,。
浙公网安备 33010602011771号