其他分享
首页 > 其他分享> > 移动业务资费问题总结

移动业务资费问题总结

作者:互联网

第三次Blog作业
本次blog对最近三次的PTA题目中的移动业务资费问题进行总结,分为三次迭代进行,第一次为针对市内座机用户采用的计费方式,第二次为针对手机和座机用户,第三次为针对短信用户。下面我将对三次迭代进行分析。   第一次:座机计费 题目要求:实现一个简单的电信计费程序:假设南昌市电信分公司针对市内座机用户采用的计费方式:月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计算。题目将大致的类图给出

 

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

代码分析:对于本次题目,我在写的过程中困扰我最久的是正则表达式,开始时我没用正则表达式,然后“含有特殊符号”的测试点就一直过不去,于是我在输入开户信息的地方加入了正则表达式,结果不理想,又在逐行输入本月某些用户的通讯信息的循环里也加入了正则表达式,有一些测试点过了,再通过后期的修改,就将“含有特殊字符”的测试点全部通过,正则表达式代码如下:

String regStr1 = "u-0791[0-9]{7,8} 0" ;
String regStr2 = "[t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s" +
"((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?" +
"[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})([48]|[2468][048]|[13579][26])|(([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]|[0-9][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})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" +
"\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])";

在循环里,我通过用空格分割每一行字符,再检测分割后的字符数组的个数来判断是开户信息还是通讯信息,循环内部代码如下:

if(arr.length == 2) {

if(arr[1].equals("0")) {
String arr2 = "u-" + arr[0];
if(line.matches("u-0791[0-9]{7,8} 0")) {
String number = arr[0];//拨打的号码
User user1 = new User();
user.add(user1);
user1.setNumber(numberCalling);
}

}

}else if(arr.length == 6) {
if(line.matches(regStr2)) {
String []arr1 = num.split(" ");
String numberAnswer = arr1[1];//接听的号码

String callingAddressAreaCode = numberCalling.substring(0,4);//拨号地点区号
String answerAddressAreaCode = numberAnswer.substring(0,4);//接通地点区号

// User user = new User();
// user.setNumber(numberCalling);

CallRecord callrecord = new CallRecord();
callrecord.setCallingAddressAreaCode(callingAddressAreaCode);
callrecord.setAnswerAddressAreaCode(answerAddressAreaCode);

SimpleDateFormat sdf = new SimpleDateFormat( "yyyy.MM.dd HH:mm:ss" );
String startTime = arr[2] + " " + arr[3];
String endTime = arr[4] + " " + arr[5];
try {
Date StartTime = sdf.parse( startTime );//将时间字符串转换为SimpleDateFormat类型
Date EndTime = sdf.parse( endTime );

callrecord.setStartTime(StartTime);
callrecord.setEndTime(EndTime);

} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

for(int j = 0; j < user.size(); j ++) {
if(numberCalling.equals(user.get(j).getNumber())) {
if(callingAddressAreaCode.equals(answerAddressAreaCode)) {
user.get(j).getUserRecords().addCallinglnCityRecords(callrecord);
}else if(answerAddressAreaCode.equals("0790")||answerAddressAreaCode.equals("0701")||
answerAddressAreaCode.equals("0791")||answerAddressAreaCode.equals("0793")
||answerAddressAreaCode.equals("0792")||answerAddressAreaCode.equals("0794")||
answerAddressAreaCode.equals("0795")||
answerAddressAreaCode.equals("0796")||answerAddressAreaCode.equals("0797")||
answerAddressAreaCode.equals("0798")||answerAddressAreaCode.equals("0799")) {
user.get(j).getUserRecords().addCallinglnProvinceRecords(callrecord);
}else {
user.get(j).getUserRecords().addCallinglnLandRecords(callrecord);
}
}
}
}


}else if(line.equals("end")) {
i = 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也要被计算省外接听漫游费:

座机呼叫座机: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

题目所给类图与第一次作业相同。

设计策略:本次作业在上一次作业的基础上,加上了几个手机类,分别是市内手机类,省内手机类,国内手机类,以及省内漫游类和省外漫游类。再对业务类里的代码进行一些增删,加上手机的内容,再改一下正则表达式。

代码分析:本次的正则表达式与上次的不同,我总共写了七个正则表达式,分别是开户手机,开户座机,座机打座机,手机打座机,座机打手机,手机打手机,以及一个判断时间的正则表达式。代码如下:

String uPattern0 = "[u]-0791[0-9]{7,8}\\s[0]";
String uPattern1 = "[u]-1[0-9]{10}\\s[1]";
String tPattern00 = "[t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s";
String tPattern01 = "[t]-0791[0-9]{7,8}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s";
String tPattern10 = "[t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "0[0-9]{9,11}\\s";
String tPattern11 = "[t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s";
String timePattern = "" +
"((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?" +
"[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})([48]|[2468][048]|[13579][26])|(([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]|[0-9][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})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" +
"\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])";

业务类的设计思路与上次没有很大区别,无非就是增加了很多行代码,这里就不细说了。

 

第三次:短信计费

题目要求:

实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
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”结束。

设计策略:这一次的作业没有涉及手机和座机,于是就省掉了很多类,光写和短信有关的类。但这一次的设计思路和前两次还是有区别的,我在User里加入了一个num变量,用来保存本用户短信的条数。

代码分析:我在循环里逐行分析代码,我用num.split(" ",3)去除了前面的电话号码,只留下了后面的短信内容,这样就避免了短信内容里有空格的情况。然后判断字符串的长度,set进User的num里,这一部分的代码如下:

if(num1 < 10) {
user.get(j).setNum(1);
}else {
if(num1 % 10 != 0) {
user.get(j).setNum(num1 / 10 + 1);
}else {
user.get(j).setNum(num1 / 10);
}
}

本题的正则表达式代码如下:

String regex1 = "^u-[1]\\d{10}\\s[3]$";
String regex2 = "^m-[1]\\d{10}\\s[1]\\d{10}\\s[\\d\\w.,\\s]+$";

 

标签:总结,10,String,answerAddressAreaCode,equals,座机,资费,计费,移动
来源: https://www.cnblogs.com/ztq-123223233/p/16380347.html