PTA-电信计费
一、前言
1.难度分析
此次博客围绕6-8次PTA题目集(电信计费),难度在电信计费的三道题目上,主要是内容太多了,让人摸不着头脑,题目其实并不难(相较于前面那几道多边形的题目)。
2.题量分析
比前几次大作业要少,除了送分题就三道电信计费。
3.知识点
6-7-1 电信计费系列1-座机计费
1、月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/ 分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
2、南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
3、座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。座机号码有以下两种类型:
(1)区号:4位 电话号码:8位
(2)区号:3位 电话号码:7位
4、时间必须符合"yyyy.MM.dd HH:mm:ss"格式(如2022.1.3 10:00:25),建议使用SimpleDateFormat类编写代码。
5、每个用户初始余额是100元。计算所有已开户的用户的当月费用(精确到小数点后2位,单位元),没有开户的用户不能计算费用。
6、注意,题目提到不检查“开户号码非南昌市的号码”这种情况,也就是说用不是南昌的座机区号开通用户也是正确的(至少在这里)。除了存在4位的座机区号外,还有3位的座机区号(如北上广),区分是3位的号码长度是10位,也就是上面知识点3中的类型(2)。
7-7-1 电信计费系列2-手机+座机计费
除了座机计费的知识点或者说内容点以外,增加了“手机计费”的以下几点:
1、月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟。
个人理解:每个月要交15元月租,只有在省外接别人的电话才需要计费,市内和省内打电话都是0.3元/分钟,在省外打电话是0.6元/分钟。
2、被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3
10:05:11
个人理解:看代码说话,第一行代码表示在南昌(题目默认)开通手机用户13307912264,第二行代码表示手机用户(13307912264)在区号为020(广州)接听了来自南昌的座机(079186330022)的来电。在这种情景下南昌的座机(079186330022)要以省外拨打电话为计费标准,而手机用户(13307912264)就要以省外接听电话为计费标准,虽然手机用户是在南昌开通的,但是他漫游到了广州,对于南昌来说就是省外。
3、手机号码由11位数字构成,最高位是1。
8--1 电信计费系列3-短信计费
1、计费方式:接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。
个人理解:结合下面的计费代码来看,先计算有多少条短信,然后根据短信的条数计费。
double sumCost = 0;//计费总金额
int number = 0;//短信条数
//遍历所有的发送记录
for (MessageRecord m : userRecords.getSendMessageRecords()) {
//单条短信的字符数量
int length = m.getMessage().length();
if (length <= 10) {//字符不超过10个
number++;//算作一条
} else {//字符超过10个
number += length / 10;//先取十位数相加
if (length % 10 != 0) {//再看个位数,不为0加1
number++;
}
}
}
//按总的短信条数计费
if (number <= 3) {//0-3条0.1元/条
sumCost = number * 0.1;
} else if (number <= 5) {//3-5条0.2元/条
sumCost = 0.3 + 0.2 * (number - 3);
} else {//超过5条0.3元/条
sumCost = 0.7 + 0.3 * (number - 5);
}
return sumCost;
二、设计与分析
第6次大作业
6-7-1 电信计费系列 1-座机计费
源码
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Scanner;
import java.util.Date;
public class Main {
public static void main(String args[]){
Scanner input=new Scanner(System.in);
String s=input.nextLine();
ArrayList<User> users = new ArrayList<>();
inputDeal inputdeal=new inputDeal();
boolean flag;
while (!s.equals("end")){
if (1 == inputdeal.judge(s)) {
inputdeal.writeUser(users, s);
} else if (2 == inputdeal.judge(s)) {
inputdeal.writeRecord(users, s);
}
s=input.nextLine();
}
for(int i=0;i< users.size();i++){//冒泡排序
for(int j=0;j< users.size()-i-1;j++){
if(Double.parseDouble(users.get(j).getNumber()) > Double.parseDouble(users.get(j+1).getNumber())){
User tempu=users.get(j);
users.set(j,users.get(j+1));
users.set(j+1,tempu);
}
}
}
//System.out.println(users.size());
for(User u:users){
System.out.println(u.getNumber()+" "+Common.round(u.calCost(),2)+" "+Common.round(u.calBalance(),2));
}
}
}
class inputDeal{
public int judge(String s){
String []s1=s.split(" ");
if(s1.length==2&&(s.matches("[u]-[0][7]([9][0-9]|[0][1])[0-9]{7,8} [0-3]")|| s.matches("[u]-1[0-9]{10}\\s[1]")))
return 1;//开通用户
if(s1.length==6&&s.matches("^t\\-0\\d{9,11}\\s0\\d{9,11}((\\s\\d{4}\\.([1-9]|([1]{1}[0-2]{1}))\\.([1-9]|"
+ "([1-2]{1}[0-9]{1})|3[0-1])\\s(([0-1][0-9])|(2[0-3]))\\:([0-5][0-9])\\:([0-5][0-9])){2})")){
//System.out.print("a");
return 2;//通话记录
}
return 0;
}
public void writeUser(ArrayList<User> users, String s){
String []s1=s.split(" ");
String number=s1[0].substring(2);
boolean flag=false;
User newuser = new User();
for(User u:users){
if(u.getNumber().equals(number))
flag=true;//号码已经开过户
}
if(!flag){//没开过户的才登记
newuser.setNumber(number);
int mode=Integer.parseInt(s1[1]);
if(mode==0){//收费模式0:座机
newuser.setChargeMode(new LandlinePhoneCharging());
}
users.add(newuser);
}
}
public void writeRecord(ArrayList<User> users, String s){
String []s1=s.split(" ");
s1[0]=s1[0].replace("t-","");//将t-去掉
//初始化callRecord
CallRecord callRecord=new CallRecord(s1);
SimpleDateFormat format=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
Date startTime,endTime;
try {
startTime = format.parse(s1[2]+" "+s1[3]);
endTime = format.parse(s1[4]+" "+s1[5]);
} catch (ParseException e) {
throw new RuntimeException(e);
}
callRecord.setCallingAddressAreaCode(s1[0].substring(0,4));
callRecord.setAnswerAddressAreaCode(s1[1].substring(0,4));
callRecord.setStartTime(startTime);
callRecord.setEndTime(endTime);
callRecord.setCallingNumber(s1[0]);
callRecord.setAnswerNumber(s1[1]);
//判断是否添加记录
User callu=null,answeru=null;
for(User u:users){
if(u.getNumber().equals(s1[0])){
callu = u;
}
if (u.getNumber().equals(s1[1])) {
answeru = u;
}
if (callu != null && answeru != null) {
break;
}
}
if (callu != null) {
if (callRecord.getCallType() == 1) {
callu.getUserRecords().addCallingInCityRecords(callRecord);
} else if (callRecord.getCallType() == 2) {
callu.getUserRecords().addCallingInProvinceRecords(callRecord);
} else {
callu.getUserRecords().addCallingInLandRecords(callRecord);
}
}
if (answeru != null) {
if (callRecord.getCallType() == 1) {
answeru.getUserRecords().addAnswerInCityRecords(callRecord);
} else if (callRecord.getCallType() == 2) {
answeru.getUserRecords().addAnswerInProvinceRecords(callRecord);
} else {
answeru.getUserRecords().addAnswerInLandRecords(callRecord);
}
}
}
}
class User {
private UserRecords userRecords;
private double balance;
private ChargeMode chargeMode;
private String number;
User(){
userRecords=new UserRecords();
balance=100;
}
public double calCost(){
return chargeMode.calCost(userRecords);
}
public double calBalance(){
return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
}
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;
}
}
abstract class ChargeMode{
protected ArrayList<ChargeRule> chargeRules;
ChargeMode(){
chargeRules=new ArrayList<>();
}
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();
}
class LandlinePhoneCharging extends ChargeMode{
private double monthlyRent;
LandlinePhoneCharging(){
monthlyRent=20;
chargeRules.add(new LandPhoneInCityRule());
chargeRules.add(new LandPhoneInProvinceRule());
chargeRules.add(new LandPhoneInlandRule());
}
@Override
public double calCost(UserRecords userRecords){
double sumCost=0;
for(ChargeRule rule:chargeRules){
sumCost+=rule.calCost(userRecords);
}
return sumCost;
}
@Override
public double getMonthlyRent(){
return monthlyRent;
}
}
class UserRecords {
private ArrayList<CallRecord> callingInCityRecords;
private ArrayList<CallRecord> callingInProvinceRecords;
private ArrayList<CallRecord> callingInLandRecords;
private ArrayList<CallRecord> answerInCityRecords;
private ArrayList<CallRecord> answerInProvinceRecords;
private ArrayList<CallRecord> answerInLandRecords;
private ArrayList<MessageRecord> sendMessageRecords;
private ArrayList<MessageRecord> receiveMessageRecords;
UserRecords(){
callingInCityRecords=new ArrayList<CallRecord>();
callingInProvinceRecords=new ArrayList<CallRecord>();
callingInLandRecords=new ArrayList<CallRecord>();
answerInCityRecords=new ArrayList<CallRecord>();
answerInProvinceRecords=new ArrayList<CallRecord>();
answerInLandRecords=new ArrayList<CallRecord>();
sendMessageRecords=new 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 answerRecord){
answerInCityRecords.add(answerRecord);
}
public void addAnswerInProvinceRecords(CallRecord answerRecord){
answerInProvinceRecords.add(answerRecord);
}
public void addAnswerInLandRecords(CallRecord answerRecord){
answerInLandRecords.add(answerRecord);
}
public void addSendMessageRecords(MessageRecord sendMessageRecord){
sendMessageRecords.add(sendMessageRecord);
}
public ArrayList<MessageRecord> getSendMessageRecords() {
return sendMessageRecords;
}
public ArrayList<MessageRecord> getReceiveMessageRecords() {
return receiveMessageRecords;
}
public ArrayList<CallRecord> getCallingInCityRecords() {
return callingInCityRecords;
}
public ArrayList<CallRecord> getCallingInProvinceRecords() {
return callingInProvinceRecords;
}
public ArrayList<CallRecord> getCallingInLandRecords() {
return callingInLandRecords;
}
public ArrayList<CallRecord> getAnswerInCityRecords() {
return answerInCityRecords;
}
public ArrayList<CallRecord> getAnswerInProvinceRecords() {
return answerInProvinceRecords;
}
public ArrayList<CallRecord> getAnswerInLandRecords() {
return answerInLandRecords;
}
}
abstract class CommunicationRecord{
protected String callingNumber;
protected 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 CallRecord extends CommunicationRecord{
private Date startTime;
private Date endTime;
private String callingAddressAreaCode;
private String answerAddressAreaCode;
CallRecord(String[] inputs) {
super();
if (inputs[0].length() == 10) {
callingAddressAreaCode = inputs[0].substring(0, 3);
} else {
callingAddressAreaCode = inputs[0].substring(0, 4);
}
if (inputs[1].length() == 10) {
answerAddressAreaCode = inputs[1].substring(0, 3);
} else {
answerAddressAreaCode = inputs[1].substring(0, 4);
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
try {
startTime = simpleDateFormat.parse(inputs[2] + " " + inputs[3]);
endTime = simpleDateFormat.parse(inputs[4] + " " + inputs[5]);
} catch (ParseException e) {
}
}
CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
super();
this.startTime = startTime;
this.endTime = endTime;
this.callingAddressAreaCode = callingAddressAreaCode;
this.answerAddressAreaCode = answerAddressAreaCode;
}
public int getCallType() {
if (callingAddressAreaCode.equals(answerAddressAreaCode)) {
return 1;
}
if (callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701")) {
if (answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701")) {
return 2;
}
}
return 3;
}
public Date getStartTime(){
return this.startTime;
}
public void setStartTime(Date startTime){
this.startTime=startTime;
}
public Date getEndTime(){
return this.endTime;
}
public void setEndTime(Date endTime){
this.endTime=endTime;
}
public String getCallingAddressAreaCode(){
return this.callingAddressAreaCode;
}
public void setCallingAddressAreaCode(String callingAddressAreaCode){
this.callingAddressAreaCode=callingAddressAreaCode;
}
public String getAnswerAddressAreaCode(){
return this.answerAddressAreaCode;
}
public void setAnswerAddressAreaCode(String answerAddressAreaCode){
this.answerAddressAreaCode=answerAddressAreaCode;
}
}
class MessageRecord extends CommunicationRecord{
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
abstract class ChargeRule{
public abstract double calCost(UserRecords userRecords);
}
abstract class CallChargeRule extends ChargeRule{
public abstract double calCost(UserRecords userRecords);
}
class LandPhoneInCityRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getCallingInCityRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.1;
}
}
return SumCost;
}
}
class LandPhoneInProvinceRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getCallingInProvinceRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.3;
}
}
return SumCost;
}
}
class LandPhoneInlandRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getCallingInLandRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.6;
}
}
return SumCost;
}
}
class Common {
public static double round(double m,int n) {
return (double)Math.round(m*Math.pow(10,n))/Math.pow(10,n);
}
}
idea生成类图:

SourceMonitor的生成报表内容:

第7次大作业
7-7-1 电信计费系列 2-手机+座机计费
源码
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner input=new Scanner(System.in);
String s=input.nextLine();
ArrayList<User> users = new ArrayList<>();
inputDeal inputdeal=new inputDeal();
while (!s.equals("end")){
if (1 == inputdeal.judge(s)) {
inputdeal.writeUser(users, s);
} else if (2 == inputdeal.judge(s)) {
inputdeal.writeRecord(users, s);
}
s=input.nextLine();
}
// for(int i=0;i< users.size();i++){//冒泡排序
// for(int j=0;j< users.size()-i-1;j++){
// if(Integer.parseInt(users.get(j).getNumber()) > Integer.parseInt(users.get(j+1).getNumber())){
// User tempu=users.get(j);
// users.set(j,users.get(j+1));
// users.set(j+1,tempu);
// }
// }
// }
ArrayList<User> temp = new ArrayList<>(users);
temp.sort(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getNumber().compareTo(o2.getNumber());
}
});
//System.out.println(users.size());
for(User u:temp){
System.out.println(u.getNumber()+" "+Common.round(u.calCost(),2)+" "+Common.round(u.calBalance(),2));
}
}
}
class inputDeal{
public int judge(String s){
String []s1=s.split(" ");
if(s1.length==2&&(s.matches("[u]-[0][7]([9][0-9]|[0][1])[0-9]{7,8} [0-3]"))||s.matches("[u]-[1][0-9]{10} [0-3]"))
return 1;//开通用户
if(s.matches("(([t]-0791[0-9]{7,8}\\s0[0-9]{9,11})|([t]-0791[0-9]{7,8}\\s1[0-9]{10}\\s0[0-9]{2,3})|" +
"([t]-1[0-9]{10}\\s0[0-9]{2,3}\\s0[0-9]{9,11})|([t]-1[0-9]{10}\\s0[0-9]{2,3}\\s1[0-9]{10}\\s0[0-9]{2,3}))" +
"(\\s\\d{4}\\.([1-9]|([1]{1}[0-2]{1}))\\.([1-9]|([1-2]{1}[0-9]{1})|3[0-1])\\s(([0-1][0-9])|(2[0-3]))\\:([0-5][0-9])\\:([0-5][0-9])){2}")){
//System.out.print("a");
return 2;//通话记录
}
return 0;
}
public void writeUser(ArrayList<User> users, String s){
String []s1=s.split(" ");
String number=s1[0].substring(2);
User newUser = new User();
for(User u:users){
if(u.getNumber().equals(number))
return;//号码已经开过户
}
newUser.setNumber(number);
int mode=Integer.parseInt(s1[1]);
if(mode==0){//收费模式0:座机
newUser.setChargeMode(new LandlinePhoneCharging());
}else if(mode==1){//收费模式1:手机
newUser.setChargeMode(new MobilePhoneCharging());
}
users.add(newUser);
}
public void writeRecord(ArrayList<User> users, String s){
String []s1=s.split(" ");
s1[0]=s1[0].replace("t-","");//将t-去掉
//初始化callRecord
CallRecord callRecord=new CallRecord(s1);
//判断是否添加记录
User callu=null,answeru=null;
for(User u:users){//判断已开通的用户中是否有
if(u.getNumber().equals(callRecord.getCallingNumber())){
callu = u;
}
if (u.getNumber().equals(callRecord.getAnswerNumber())) {
answeru = u;
}
if (callu != null && answeru != null) {//减少检索次数
break;
}
}
if (callu != null) {
if (callRecord.getCallType() == 1) {
callu.getUserRecords().addCallingInCityRecords(callRecord);
} else if (callRecord.getCallType() == 2) {
callu.getUserRecords().addCallingInProvinceRecords(callRecord);
} else if (callRecord.getCallType() == 3){
callu.getUserRecords().addCallingInLandRecords(callRecord);
}else if (callRecord.getCallType() == 4) {
callu.getUserRecords().addCityCallCityRecords(callRecord);
}else if (callRecord.getCallType() == 5) {
callu.getUserRecords().addCityCallProvinceRecords(callRecord);
}else if (callRecord.getCallType() == 6) {
callu.getUserRecords().addCityCallLandRecords(callRecord);
}else if (callRecord.getCallType() == 7) {
callu.getUserRecords().addProvinceRoamingCallRecords(callRecord);
}else if (callRecord.getCallType() == 8) {
callu.getUserRecords().addLandRoamingCallRecords(callRecord);
}
}
if (answeru != null) {
if (callRecord.getCallType() == 1) {
answeru.getUserRecords().addAnswerInCityRecords(callRecord);
} else if (callRecord.getCallType() == 2) {
answeru.getUserRecords().addAnswerInProvinceRecords(callRecord);
} else if(callRecord.getCallType() == 3){
answeru.getUserRecords().addAnswerInLandRecords(callRecord);
}
if(callRecord.getReceiveType() == 1){
answeru.getUserRecords().addLandRoamingAnswerRecords(callRecord);
}
}
}
}
class User {
private UserRecords userRecords;
private double balance;
private ChargeMode chargeMode;
private String number;
User(){
userRecords=new UserRecords();
balance=100;
}
public double calCost(){
return chargeMode.calCost(userRecords);
}
public double calBalance(){
return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
}
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;
}
}
abstract class ChargeMode{
protected ArrayList<ChargeRule> chargeRules;
ChargeMode(){
chargeRules=new ArrayList<>();
}
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();
}
class LandlinePhoneCharging extends ChargeMode{
private double monthlyRent;
LandlinePhoneCharging(){
monthlyRent=20;
chargeRules.add(new LandPhoneInCityRule());
chargeRules.add(new LandPhoneInProvinceRule());
chargeRules.add(new LandPhoneInlandRule());
}
@Override
public double calCost(UserRecords userRecords){
double sumCost=0;
for(ChargeRule rule:chargeRules){
sumCost+=((CallChargeRule)rule).calCost(userRecords);
}
return sumCost;
}
@Override
public double getMonthlyRent(){
return monthlyRent;
}
}
class MobilePhoneCharging extends ChargeMode{
private double monthlyRent;
MobilePhoneCharging(){
monthlyRent=15;
chargeRules.add(new CityCallCityRule());
chargeRules.add(new CityCallProvinceRule());
chargeRules.add(new CityCallLandRule());
chargeRules.add(new ProvinceRoamingCallRule());
chargeRules.add(new LandRoamingCallRule());
chargeRules.add(new LandRoamingAnswerRule());
}
@Override
public double calCost(UserRecords userRecords){
double sumCost=0;
for(ChargeRule rule:chargeRules){
if(chargeRules.indexOf(rule)<chargeRules.size()-1)
sumCost+=((CallChargeRule)rule).calCost(userRecords);
else
sumCost+=((ReceiveChargeRule)rule).recCost(userRecords);
}
return sumCost;
}
@Override
public double getMonthlyRent(){
return monthlyRent;
}
}
class UserRecords {
//座机
private ArrayList<CallRecord> callingInCityRecords;
private ArrayList<CallRecord> callingInProvinceRecords;
private ArrayList<CallRecord> callingInLandRecords;
private ArrayList<CallRecord> answerInCityRecords;
private ArrayList<CallRecord> answerInProvinceRecords;
private ArrayList<CallRecord> answerInLandRecords;
private ArrayList<MessageRecord> sendMessageRecords;
private ArrayList<MessageRecord> receiveMessageRecords;
//手机
private ArrayList<CallRecord> cityCallCityRecords;//市内拨打市内
private ArrayList<CallRecord> cityCallProvinceRecords;//市内拨打省内
private ArrayList<CallRecord> cityCallLandRecords;//市内拨打省外
private ArrayList<CallRecord> provinceRoamingCallRecords;//省内漫游拨打
private ArrayList<CallRecord> landRoamingCallRecords;//省外漫游拨打
private ArrayList<CallRecord> landRoamingAnswerRecords;//省外漫游接听
UserRecords(){
callingInCityRecords=new ArrayList<>();
callingInProvinceRecords=new ArrayList<>();
callingInLandRecords=new ArrayList<>();
answerInCityRecords=new ArrayList<>();
answerInProvinceRecords=new ArrayList<>();
answerInLandRecords=new ArrayList<>();
sendMessageRecords=new ArrayList<>();
receiveMessageRecords=new ArrayList<>();
cityCallCityRecords=new ArrayList<>();
cityCallProvinceRecords=new ArrayList<>();
cityCallLandRecords=new ArrayList<>();
provinceRoamingCallRecords=new ArrayList<>();
landRoamingCallRecords=new ArrayList<>();
landRoamingAnswerRecords=new ArrayList<>();
}
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 answerRecord){
answerInCityRecords.add(answerRecord);
}
public void addAnswerInProvinceRecords(CallRecord answerRecord){
answerInProvinceRecords.add(answerRecord);
}
public void addAnswerInLandRecords(CallRecord answerRecord){
answerInLandRecords.add(answerRecord);
}
public void addSendMessageRecords(MessageRecord sendMessageRecord){
sendMessageRecords.add(sendMessageRecord);
}
public void addCityCallCityRecords(CallRecord callRecord){
cityCallCityRecords.add(callRecord);
}
public void addCityCallProvinceRecords(CallRecord callRecord){
cityCallProvinceRecords.add(callRecord);
}
public void addCityCallLandRecords(CallRecord callRecord){
cityCallLandRecords.add(callRecord);
}
public void addProvinceRoamingCallRecords(CallRecord callRecord){
provinceRoamingCallRecords.add(callRecord);
}
public void addLandRoamingCallRecords(CallRecord callRecord){
landRoamingCallRecords.add(callRecord);
}
public void addLandRoamingAnswerRecords(CallRecord answerRecord){
landRoamingAnswerRecords.add(answerRecord);
}
public ArrayList<MessageRecord> getSendMessageRecords() {
return sendMessageRecords;
}
public ArrayList<MessageRecord> getReceiveMessageRecords() {
return receiveMessageRecords;
}
public ArrayList<CallRecord> getCallingInCityRecords() {
return callingInCityRecords;
}
public ArrayList<CallRecord> getCallingInProvinceRecords() {
return callingInProvinceRecords;
}
public ArrayList<CallRecord> getCallingInLandRecords() {
return callingInLandRecords;
}
public ArrayList<CallRecord> getAnswerInCityRecords() {
return answerInCityRecords;
}
public ArrayList<CallRecord> getAnswerInProvinceRecords() {
return answerInProvinceRecords;
}
public ArrayList<CallRecord> getAnswerInLandRecords() {
return answerInLandRecords;
}
public ArrayList<CallRecord> getCityCallCityRecords() {
return cityCallCityRecords;
}
public ArrayList<CallRecord> getCityCallProvinceRecords() {
return cityCallProvinceRecords;
}
public ArrayList<CallRecord> getCityCallLandRecords() {
return cityCallLandRecords;
}
public ArrayList<CallRecord> getProvinceRoamingCallRecords() {
return provinceRoamingCallRecords;
}
public ArrayList<CallRecord> getLandRoamingCallRecords() {
return landRoamingCallRecords;
}
public ArrayList<CallRecord> getLandRoamingAnswerRecords() {
return landRoamingAnswerRecords;
}
}
abstract class CommunicationRecord{
protected String callingNumber;
protected 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 CallRecord extends CommunicationRecord{
private Date startTime;
private Date endTime;
private String callingAddressAreaCode;
private String answerAddressAreaCode;
private int callType;//拨打收费类型
private int receiveType;//接听收费类型
CallRecord(String[] inputs) {
super();
callType=0;//初始化
receiveType=0;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
if(inputs.length==6){//座机拨打座机
if (inputs[0].length() == 10) {//三个区号
callingAddressAreaCode = inputs[0].substring(0, 3);
} else {//四个区号
callingAddressAreaCode = inputs[0].substring(0, 4);
}
if (inputs[1].length() == 10) {
answerAddressAreaCode = inputs[1].substring(0, 3);
} else {
answerAddressAreaCode = inputs[1].substring(0, 4);
}
try {
startTime = simpleDateFormat.parse(inputs[2] + " " + inputs[3]);
endTime = simpleDateFormat.parse(inputs[4] + " " + inputs[5]);
} catch (ParseException e) {
}
if (callingAddressAreaCode.equals(answerAddressAreaCode)) {
callType=1;//市内拨打
}else if ((callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701"))&&(answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701"))) {
callType=2;//省内长途
}else {
// System.out.println("a");
callType=3;//国内长途
}
this.callingNumber=inputs[0];
this.answerNumber=inputs[1];
}
if(inputs.length==7&&inputs[1].length()>inputs[2].length()){//座机拨打手机
if (inputs[0].length() == 10) {//三个区号
callingAddressAreaCode = inputs[0].substring(0, 3);
} else {//四个区号
callingAddressAreaCode = inputs[0].substring(0, 4);
}
answerAddressAreaCode = inputs[2];
try {
startTime = simpleDateFormat.parse(inputs[3] + " " + inputs[4]);
endTime = simpleDateFormat.parse(inputs[5] + " " + inputs[6]);
} catch (ParseException e) {
}
if (callingAddressAreaCode.equals(answerAddressAreaCode)) {
callType=1;
}else if ((callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701"))&&(answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701"))) {
callType=2;
}else {
callType=3;
receiveType=1;//省外漫游接听
}
this.callingNumber=inputs[0];
this.answerNumber=inputs[1];
}
if(inputs.length==7&&inputs[1].length()<inputs[2].length()){//手机拨打座机
callingAddressAreaCode = inputs[1];
if (inputs[2].length() == 10) {
answerAddressAreaCode = inputs[2].substring(0, 3);
} else {
answerAddressAreaCode = inputs[2].substring(0, 4);
}
try {
startTime = simpleDateFormat.parse(inputs[3] + " " + inputs[4]);
endTime = simpleDateFormat.parse(inputs[5] + " " + inputs[6]);
} catch (ParseException e) {
}
if (callingAddressAreaCode.equals("0791")) {
if(answerAddressAreaCode.equals("0791"))
callType=4;//市内拨打市内
else if(answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701"))
callType=5;//市内拨打省内
else
callType=6;//市内拨打省外
}else if (callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701")) {
callType=7;//省内漫游拨打
}else {
callType=8;//省外漫游拨打
}
this.callingNumber=inputs[0];
this.answerNumber=inputs[2];
}
if(inputs.length==8){//手机拨打手机
callingAddressAreaCode = inputs[1];
answerAddressAreaCode = inputs[3];
try {
startTime = simpleDateFormat.parse(inputs[4] + " " + inputs[5]);
endTime = simpleDateFormat.parse(inputs[6] + " " + inputs[7]);
} catch (ParseException e) {
}
if (callingAddressAreaCode.equals("0791")) {
if(answerAddressAreaCode.equals("0791"))
callType=4;//市内拨打市内
else if(answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701"))
callType=5;//市内拨打省内
else
callType=6;//市内拨打省外
}else if (callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701")) {
callType=7;//省内漫游拨打
}else {
callType=8;//省外漫游拨打
}
if(!answerAddressAreaCode.matches("^079[0-9]$") && !answerAddressAreaCode.equals("0701"))
receiveType=1;//省外漫游接听
this.callingNumber=inputs[0];
this.answerNumber=inputs[2];
}
}
CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode,String callingNumber,String answerNumber) {
super();
this.startTime = startTime;
this.endTime = endTime;
this.callingAddressAreaCode = callingAddressAreaCode;
this.answerAddressAreaCode = answerAddressAreaCode;
this.callingNumber=callingNumber;
this.answerNumber=answerNumber;
}
public int getCallType() {
return this.callType;
}
public int getReceiveType() {
return this.receiveType;
}
public Date getStartTime(){
return this.startTime;
}
public void setStartTime(Date startTime){
this.startTime=startTime;
}
public Date getEndTime(){
return this.endTime;
}
public void setEndTime(Date endTime){
this.endTime=endTime;
}
public String getCallingAddressAreaCode(){
return this.callingAddressAreaCode;
}
public void setCallingAddressAreaCode(String callingAddressAreaCode){
this.callingAddressAreaCode=callingAddressAreaCode;
}
public String getAnswerAddressAreaCode(){
return this.answerAddressAreaCode;
}
public void setAnswerAddressAreaCode(String answerAddressAreaCode){
this.answerAddressAreaCode=answerAddressAreaCode;
}
}
class MessageRecord extends CommunicationRecord{
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
abstract class ChargeRule{
// public abstract double calCost(UserRecords userRecords);
// public abstract double recCost(UserRecords userRecords);
}
abstract class CallChargeRule extends ChargeRule{
public abstract double calCost(UserRecords userRecords);
}
abstract class MessageChargeRule extends ChargeRule{
public abstract double calCost(UserRecords userRecords);
}
abstract class ReceiveChargeRule extends ChargeRule{
public abstract double recCost(UserRecords userRecords);
}
class LandPhoneInCityRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getCallingInCityRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.1;
}
}
return SumCost;
}
}
class LandPhoneInProvinceRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getCallingInProvinceRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.3;
}
}
return SumCost;
}
}
class LandPhoneInlandRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getCallingInLandRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.6;
}
}
return SumCost;
}
}
class CityCallCityRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getCityCallCityRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.1;
}
}
return SumCost;
}
}
class CityCallProvinceRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getCityCallProvinceRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.2;
}
}
return SumCost;
}
}
class CityCallLandRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getCityCallLandRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.3;
}
}
return SumCost;
}
}
class ProvinceRoamingCallRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getProvinceRoamingCallRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.3;
}
}
return SumCost;
}
}
class LandRoamingCallRule extends CallChargeRule{
@Override
public double calCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getLandRoamingCallRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.6;
}
}
return SumCost;
}
}
class LandRoamingAnswerRule extends ReceiveChargeRule{
@Override
public double recCost(UserRecords userRecords){
double SumCost = 0;
for(CallRecord call:userRecords.getLandRoamingAnswerRecords()){
double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
if(distanceS>0){
double distanceM=(int)distanceS/60;
if(distanceS%60!=0)
distanceM++;
SumCost+=distanceM*0.3;
}
}
return SumCost;
}
}
class Common {
public static double round(double m,int n) {
return (double)Math.round(m*Math.pow(10,n))/Math.pow(10,n);
}
}
idea生成类图:

SourceMonitor的生成报表内容:

第8次大作业
8-7-1 电信计费系列3-短信计费
源码
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner input=new Scanner(System.in);
String s=input.nextLine();
ArrayList<User> users = new ArrayList<>();
inputDeal inputdeal=new inputDeal();
while (!s.equals("end")){
if (1 == inputdeal.judge(s)) {
inputdeal.writeUser(users, s);
} else if (2 == inputdeal.judge(s)) {
inputdeal.writeRecord(users, s);
}
s=input.nextLine();
}
ArrayList<User> temp = new ArrayList<>(users);
temp.sort(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getNumber().compareTo(o2.getNumber());
}
});
for(User u:temp){
System.out.println(u.getNumber()+" "+Common.round(u.calCost(),2)+" "+Common.round(u.calBalance(),2));
}
}
}
class inputDeal{
public int judge(String s){
String []s1=s.split(" ");
if(s1.length==2&&s.matches("[u]-1[0-9]{10}\\s[13]"))
return 1;//开通用户
if(s.matches("[m]-1[0-9]{10}\\s" + "1[0-9]{10}\\s" + "[0-9a-zA-Z\\s\\.,]+")) {
return 2;//通话记录
}
return 0;
}
public void writeUser(ArrayList<User> users, String s){
String []s1=s.split(" ");
String number=s1[0].substring(2);
User newUser = new User();
for(User u:users){
if(u.getNumber().equals(number))
return;//号码已经开过户
}
newUser.setNumber(number);
newUser.setChargeMode((new MobileMessageCharging()));
users.add(newUser);
}
public void writeRecord(ArrayList<User> users, String s){
String []s1=s.split(" ");
String s2= s1[0].substring(0,2) ;
s1[0]=s1[0].substring(2);//将t-/m-去掉
User callu=null,answeru=null;
MessageRecord messageRecord = new MessageRecord(s);
//判断是否添加记录
for(User u:users){//判断已开通的用户中是否有
if(u.getNumber().equals(messageRecord.getCallingNumber())){
callu = u;
}
if (u.getNumber().equals(messageRecord.getAnswerNumber())) {
answeru = u;
}
if (callu != null && answeru != null) {//减少检索次数
break;
}
}
if (s2.equals("m-")) {
if (callu != null) {
// System.out.println("a");
callu.getUserRecords().addSendMessageRecords(messageRecord);
}
if (answeru != null) {
answeru.getUserRecords().addReceiveMessageRecords(messageRecord);
}
}
}
}
class User {
private UserRecords userRecords;
private double balance;
private ChargeMode chargeMode;
private String number;
User(){
userRecords=new UserRecords();
balance=100;
}
public double calCost(){
return chargeMode.calCost(userRecords);
}
public double calBalance(){
return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
}
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;
}
}
abstract class ChargeMode{
protected ArrayList<ChargeRule> chargeRules;
ChargeMode(){
chargeRules=new ArrayList<>();
}
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();
}
class MobileMessageCharging extends ChargeMode{
private double monthlyRent;
MobileMessageCharging(){
monthlyRent=0;
chargeRules.add(new SendMessageRule());
}
@Override
public double calCost(UserRecords userRecords){
double sumCost=0;
for(ChargeRule rule:chargeRules){
sumCost+=((MessageChargeRule)rule).calCost(userRecords);
}
return sumCost;
}
@Override
public double getMonthlyRent(){
return monthlyRent;
}
}
class UserRecords {
private ArrayList<MessageRecord> sendMessageRecords;
private ArrayList<MessageRecord> receiveMessageRecords;
UserRecords(){
sendMessageRecords=new ArrayList<>();
receiveMessageRecords=new ArrayList<>();
}
public void addSendMessageRecords(MessageRecord sendMessageRecord){
sendMessageRecords.add(sendMessageRecord);
}
public void addReceiveMessageRecords(MessageRecord receiveMessageRecord){
receiveMessageRecords.add(receiveMessageRecord);
}
public ArrayList<MessageRecord> getSendMessageRecords() {
return sendMessageRecords;
}
public ArrayList<MessageRecord> getReceiveMessageRecords() {
return receiveMessageRecords;
}
}
abstract class CommunicationRecord{
protected String callingNumber;
protected 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 MessageRecord extends CommunicationRecord{
private String message;
public MessageRecord(String s) {
super();
String []s1=s.split(" ");
s1[0]=s1[0].substring(2);//将t-/m-去掉
callingNumber = s1[0];
answerNumber = s1[1];
this.message = s.substring(26);
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
abstract class ChargeRule{
}
abstract class MessageChargeRule extends ChargeRule{
public abstract double calCost(UserRecords userRecords);
}
class SendMessageRule extends MessageChargeRule {
@Override
public double calCost(UserRecords userRecords) {
double sumCost = 0;
int number = 0;
for (MessageRecord m : userRecords.getSendMessageRecords()) {
int length = m.getMessage().length();
if (length <= 10) {
number++;
} else {
number += length / 10;
if (length % 10 != 0) {
number++;
}
}
}
if (number <= 3) {
sumCost = number * 0.1;
} else if (number <= 5) {
sumCost = 0.3 + 0.2 * (number - 3);
} else {
sumCost = 0.7 + 0.3 * (number - 5);
}
return sumCost;
}
}
class Common {
public static double round(double m,int n) {
return (double)Math.round(m*Math.pow(10,n))/Math.pow(10,n);
}
}
//u-18907910010 3
// m-18907910010 13305862264 aaaaaaaaaaaa
// m-18907910010 13305862264 aaaaaaa.
// m-18907910010 13305862264 bb,bbbb
// end
idea生成类图:

SourceMonitor的生成报表内容:

采坑心得
基本上没什么坑,注意座机区号有三位就行。
改进建议
电信计费题的框架都是老师给出来的,感觉没什么改进的。另外的送分题简单,大多也有框架。
总结
总的来说,第6-8次大作业是比前面的大作业轻松一个量级的,非说有什么困难的话,内容多,需要挺长的时间去理顺老师的类图框架。

浙公网安备 33010602011771号