(1)前言:
这几次的大作业还是比较简单的,只需要按照题目给出的类图,对应的写出相应的类,框架已经给出,你只需要填充就行了,多看几遍题目的类图,理清类之间的关联差不多就能写出了。
题量也不是太多,快的话就一天的事(指的是写一天的代码)。
知识点涉及到继承,多态,SimpleDateFormat类。
(2)设计与分析:
7-1 电信计费系列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.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;
import java.text.SimpleDateFormat;
public class Main {
public static void main(String[] args) throws ParseException {
String s ;
Scanner sc= new Scanner(System.in);
s= sc.nextLine();
Input in;
ArrayList<User> user = new ArrayList<>();
CallRecord callRecord;
while(!s.equals("end")){
in= new Input(s);
if(in.UserLegal()){
User tep= new User();
tep.setNumber(in.Usercheck()[0]);
user.add(tep);
ChargeMode chargeMode= new LandlinePhoneCharging();
chargeMode.chargeRules.add(new LandPhonelnCityRule());
chargeMode.chargeRules.add(new LandPhoneProvinceRule());
chargeMode.chargeRules.add(new LandPhonelnlandRule());
tep.serChargeMode(chargeMode);
}
else if(in.RecordLegal()){
callRecord= new CallRecord(in.getstartTime(),in.getendTime(),in.getcallingAddressAreaCode(),in.getanswerAddressAreaCode());
User tep =null;
for(User a:user)
if(a.getNumber().equals(in.getcalling()))
tep= a;
if(tep!=null){
if(judgechargemode(callRecord.getCallingAddressAreaCode(),callRecord.getAnswerAddressAreaCode())==0){
tep.userRecords.addcallinglnCityRecords(callRecord);
}
if(judgechargemode(callRecord.getCallingAddressAreaCode(),callRecord.getAnswerAddressAreaCode())==1){
tep.userRecords.addcallinglnPrivinceRecords(callRecord);
}
if(judgechargemode(callRecord.getCallingAddressAreaCode(),callRecord.getAnswerAddressAreaCode())==2){
tep.userRecords.addcallinlnLandRecords(callRecord);
}}
}
s= sc.nextLine();
}
outans(user);
}
public static ArrayList<User> Coincident(ArrayList<User> user){
for (int i = 0; i < user.size()-1; i++)
for (int j = i+1; j <user.size(); j++)
if(user.get(i).number.equals(user.get(j).number))
user.remove(i);
return user;
}
public static int calculate_minute(Date d1, Date d2){
long from = d1.getTime();
long after= d2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
public static int judgechargemode(String s1,String s2){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s2.matches(iscity))
return 0;
if(s2.matches(isprovince))
return 1;
return 2;
}
public static void outans(ArrayList<User> user){
user= Coincident(user);
java.util.Collections.sort(user);
for (User a :user)
System.out.printf("%s %.1f %.1f\n",a.number,a.chargeMode.calCost(a.userRecords),a.balance-a.chargeMode.getMonthlyRent()-a.chargeMode.calCost(a.userRecords));
}
static class User implements Comparable<User> {
UserRecords userRecords= new UserRecords();
double balance = 100;
ChargeMode chargeMode ;
String number ;
User(){
}
User(String number ){
}
double calBalance(){
return 0;
}
double calCost(){
return 0;
}
UserRecords getUserRecords(){
return userRecords;
}
void setUserRecords(UserRecords userRecords){
this.userRecords=userRecords;
}
double getBalance(){
return this.balance;
}
ChargeMode getChargeMode(){
return chargeMode;
}
void serChargeMode(ChargeMode chargeMode){
this.chargeMode=chargeMode;
}
String getNumber(){
return this.number;
}
void setNumber(String number){
this.number=number;
}
public int compareTo(User newuser){
return String.CASE_INSENSITIVE_ORDER.compare(this.number,newuser.number);
}
}
static class UserRecords{
ArrayList<CallRecord> callinglnCityRecords= new ArrayList<>();//市内拨打电话
ArrayList<CallRecord> callinglnPrivinceRecords= new ArrayList<>();//省内(不含市内)拨打电话
ArrayList<CallRecord> callinlnLandRecords= new ArrayList<>();//省外拨打电话
ArrayList<CallRecord> answerlnCityRecords= new ArrayList<>();//市内接听电话
ArrayList<CallRecord> answerlnPrivinceRecords= new ArrayList<>();//省内(不含市内)接听电话
ArrayList<CallRecord> answerlnLandRecords= new ArrayList<>();//省外接听电话的记录
ArrayList<MessageRecord> sendMessageRecords= new ArrayList<>();//发送短信
ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>();//接收短信的记录
public void addcallinglnCityRecords(CallRecord callRecord) {
callinglnCityRecords.add(callRecord);
}
public void addcallinglnPrivinceRecords(CallRecord callRecord) {
callinglnPrivinceRecords.add(callRecord);
}
public void addcallinlnLandRecords(CallRecord callRecord) {
callinlnLandRecords.add(callRecord);
}
public void addanswerlnCityRecords(CallRecord callRecord) {
answerlnCityRecords.add(callRecord);
}
public void addanswerlnPrivinceRecords(CallRecord callRecord) {
answerlnPrivinceRecords.add(callRecord);
}
public void addanswerlnLandRecords(CallRecord callRecord) {
answerlnLandRecords.add(callRecord);
}
public void addsendMessageRecords(MessageRecord callRecord) {
sendMessageRecords.add(callRecord);
}
public void addreceiveMessageRecords(MessageRecord callRecord) {
receiveMessageRecords.add(callRecord);
}
}
public abstract static class CommunicationRecord {
protected String callingNumber;
protected String answerNumber;
protected String getCallingNumber(){
return this.callingNumber;
}
public void setCallingNumber(String callingNumber){
this.callingNumber=callingNumber;
}
public String getAnswerNumber(){
return this.answerNumber;
}
public void setAnswerNumber(String answerNumber){
this.answerNumber=answerNumber;
}
}
class MessageRecord extends CommunicationRecord{
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
public abstract static class CallChargeRule extends ChargeRule{
public abstract double calCost(UserRecords records);
}
public static class CallRecord extends CommunicationRecord{
private Date startTime;
private Date endTime ;
private String callingAddressAreaCode;//拨号地点的区号
private String answerAddressAreaCode;//接听地点的区号
CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode){
this.startTime=startTime;
this.endTime=endTime;
this.callingAddressAreaCode=callingAddressAreaCode;
this.answerAddressAreaCode=answerAddressAreaCode;
}
public Date getStartTime() {
return startTime;
}
public String getAnswerAddressAreaCode() {
return answerAddressAreaCode;
}
public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
this.answerAddressAreaCode = answerAddressAreaCode;
}
public String getCallingAddressAreaCode() {
return callingAddressAreaCode;
}
public void setCallingAddressAreaCode(String callingAddressAreaCode) {
this.callingAddressAreaCode = callingAddressAreaCode;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
}
public abstract static class ChargeMode{
ArrayList<ChargeRule> chargeRules = new ArrayList<>();
public abstract double calCost(UserRecords userRecords);
public abstract double getMonthlyRent();
public ArrayList<ChargeRule> getChargeRules() {
return chargeRules;
}
public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
this.chargeRules = chargeRules;
}
}
public abstract static class ChargeRule{
abstract double calCost(UserRecords records);
}
static class Input{
String s ;
Input(String a){
this.s = a;
}
boolean UserLegal(){
String [] ss= s.split(" ");
if(ss.length!=2) return false;
String legal= "u-(0701|079\\d){1}\\d{7,8}[\\ ][0-2]";
return s.matches(legal);
}
String[] Usercheck(){
s=s.substring(2);
return s.split(" ");
}
boolean RecordLegal() throws ParseException {
String[] ss = s.split(" ");
if(ss.length!=6) return false;
String legal = "[t]-[0-9]{10,12}";
String legal1 = "\\d{10,12}";
String legal2 = "((2[0-3])|([0-1]?[0-9])):[0-5][0-9]:[0-5][0-9]";
return ss[0].matches( legal ) && ss[1].matches(legal1)
&& checktime(ss[2]) && checktime(ss[4]) && ss[3].matches(legal2) && ss[5].matches(legal2);
}
public boolean checktime(String date)
{
if(!date.matches("[1-9]\\d{3}\\.\\d{1,2}\\.\\d{1,2}")) return false;
if(!date.matches("\\d{4}\\.(\\d|[1-9]\\d)\\.(\\d|[1-9]\\d)")) return false;
String[] num = date.split("\\.");
int year = Integer.parseInt(num[0]);
int month = Integer.parseInt(num[1]);
int day = Integer.parseInt(num[2]);
if(month<1||month>12) return false;
if(day<1) return false;
int[] months={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if((year%400==0)||(year%4==0&&year%100!=0))
{
months[2]++;
}
return day <= months[month];
}
boolean isLegalDate(String s){
boolean judgeresult=true;
//1、首先使用SimpleDateFormat初步进行判断,过滤掉注入 yyyy-01-32 或yyyy-00-0x等格式
//此处可根据实际需求进行调整,如需判断yyyy/MM/dd格式将参数改掉即可
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd");
try{
//增加强判断条件,否则 诸如2022-02-29也可判断出去
format.setLenient(false);
Date date =format.parse(s);
//System.out.println(date);
}catch(Exception e){
judgeresult=false;
}
String yearStr=s.split("\\.")[0];
if(yearStr.startsWith("0")||yearStr.length()!=4){
judgeresult=false;
}
return judgeresult;
}
Date getstartTime() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d1=ss[2]+" "+ss[3];
Date date1= format.parse(d1);
return date1;
}
Date getendTime() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d2 = ss[4]+" "+ss[5];
Date date2= format.parse(d2);
return date2;
}
int calculate_minute() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d1=ss[2]+" "+ss[3];
String d2 = ss[4]+" "+ss[5];
Date date1= format.parse(d1);
Date date2= format.parse(d2);
long from = date1.getTime();
long after= date2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
String getcalling(){
String[] ss = s.split(" ");
return ss[0].substring(2);
}
String getanswer(){
String[] ss = s.split(" ");
return ss[1];
}
String getcallingAddressAreaCode(){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss[0].length()==10)
return ss[0].substring(0,3);
return ss[0].substring(0,4);
}
String getanswerAddressAreaCode(){
String[] ss = s.split(" ");
if(ss[1].length()==10)
return ss[1].substring(0,3);
return ss[1].substring(0,4);
}
}
static class LandlinePhoneCharging extends ChargeMode{
double monthlyRent =20 ;
public double calCost(UserRecords userRecords){
double sum=0;
for(ChargeRule a:chargeRules){
sum+=a.calCost(userRecords);
}
return sum;
}
public double getMonthlyRent(){
return monthlyRent;
}
}
static class LandPhonelnCityRule extends CallChargeRule{
public double calCost(UserRecords records){
double sum =0;
for(CallRecord a:records.callinglnCityRecords)
if(calculate_minute(a.getStartTime(),a.getEndTime())>=0)
sum+=calculate_minute(a.getStartTime(),a.getEndTime());
return (sum*0.1);
}
}
static class LandPhonelnlandRule extends CallChargeRule{
public double calCost (UserRecords records){
double sum =0;
for(CallRecord a:records.callinlnLandRecords)
if(calculate_minute(a.getStartTime(),a.getEndTime())>=0)
sum+=calculate_minute(a.getStartTime(),a.getEndTime());
return (sum*0.6);
}
}
static class LandPhoneProvinceRule extends CallChargeRule{
public double calCost (UserRecords records){
double sum =0;
for(CallRecord a:records.callinglnPrivinceRecords)
if(calculate_minute(a.getStartTime(),a.getEndTime())>=0)
sum+=calculate_minute(a.getStartTime(),a.getEndTime());
return (sum*0.3);
}
}
}
座机计费
类图:
SourceMonitor生成报表:
一 . 首先是对输入进行检测。
1.用户检测
boolean UserLegal(){
String [] ss= s.split(" ");
if(ss.length!=2) return false;
String legal= "u-(0701|079\\d){1}\\d{7,8}[\\ ][0-2]";
return s.matches(legal);
}
2.用户记录检测
boolean RecordLegal() throws ParseException {
String[] ss = s.split(" ");
if(ss.length!=6) return false;
String legal = "[t]-[0-9]{10,12}";
String legal1 = "\\d{10,12}";
String legal2 = "((2[0-3])|([0-1]?[0-9])):[0-5][0-9]:[0-5][0-9]";
return ss[0].matches( legal ) && ss[1].matches(legal1)
&& checktime(ss[2]) && checktime(ss[4]) && ss[3].matches(legal2) && ss[5].matches(legal2);
}
public boolean checktime(String date) //检查年月日的合理性
{
if(!date.matches("[1-9]\\d{3}\\.\\d{1,2}\\.\\d{1,2}")) return false;
if(!date.matches("\\d{4}\\.(\\d|[1-9]\\d)\\.(\\d|[1-9]\\d)")) return false;
String[] num = date.split("\\.");
int year = Integer.parseInt(num[0]);
int month = Integer.parseInt(num[1]);
int day = Integer.parseInt(num[2]);
if(month<1||month>12) return false;
if(day<1) return false;
int[] months={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if((year%400==0)||(year%4==0&&year%100!=0))
{
months[2]++;
}
return day <= months[month];
}
时间的检测也可以用SimpleDateFormat类进行检测。
boolean isLegalDate(String s){
if(!s.matches("[1-9]\\d{3}\\.\\d{1,2}\\.\\d{1,2}")) return false;
if(!s.matches("\\d{4}\\.(\\d|[1-9]\\d)\\.(\\d|[1-9]\\d)")) return false;
boolean judgeresult=true;
//1、首先使用SimpleDateFormat初步进行判断,过滤掉注入 yyyy-01-32 或yyyy-00-0x等格式
//此处可根据实际需求进行调整,如需判断yyyy/MM/dd格式将参数改掉即可
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd");
try{
//增加强判断条件,否则 诸如2022-02-29也可判断出去
format.setLenient(false);
Date date =format.parse(s);
//System.out.println(date);
}catch(Exception e){
judgeresult=false;
}
// //由于上述方法只能验证正常的日期格式,像诸如 0001-01-01、11-01-01,10001-01-01等无法校验,此处再添加校验年费是否合法
// String yearStr=s.split(".")[0];
// if(yearStr.startsWith("0")||yearStr.length()!=4){
// judgeresult=false;
// }
return judgeresult;
}
3.还有一些对输入的处理
Date getstartTime() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d1=ss[2]+" "+ss[3];
Date date1= format.parse(d1);
return date1;
}
Date getendTime() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d2 = ss[4]+" "+ss[5];
Date date2= format.parse(d2);
return date2;
}
int calculate_minute() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d1=ss[2]+" "+ss[3];
String d2 = ss[4]+" "+ss[5];
Date date1= format.parse(d1);
Date date2= format.parse(d2);
long from = date1.getTime();
long after= date2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
String getcalling(){
String[] ss = s.split(" ");
return ss[0].substring(2);
}
String getanswer(){
String[] ss = s.split(" ");
return ss[1];
}
String getcallingAddressAreaCode(){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss[0].length()==10)
return ss[0].substring(0,3);
return ss[0].substring(0,4);
}
String getanswerAddressAreaCode(){
String[] ss = s.split(" ");
if(ss[1].length()==10)
return ss[1].substring(0,3);
return ss[1].substring(0,4);
}
二 . 进行数据处理
while(!s.equals("end")){
in= new Input(s);
if(in.UserLegal()){
User tep= new User();
tep.setNumber(in.Usercheck()[0]);
user.add(tep);
ChargeMode chargeMode= new LandlinePhoneCharging();
chargeMode.chargeRules.add(new LandPhonelnCityRule());
chargeMode.chargeRules.add(new LandPhoneProvinceRule());
chargeMode.chargeRules.add(new LandPhonelnlandRule());
tep.serChargeMode(chargeMode);
}
else if(in.RecordLegal()){
callRecord= new CallRecord(in.getstartTime(),in.getendTime(),in.getcallingAddressAreaCode(),in.getanswerAddressAreaCode());
User tep =null;
for(User a:user)
if(a.getNumber().equals(in.getcalling()))
tep= a;
if(tep!=null){
if(judgechargemode(callRecord.getCallingAddressAreaCode(),callRecord.getAnswerAddressAreaCode())==0){
tep.userRecords.addcallinglnCityRecords(callRecord);
}
if(judgechargemode(callRecord.getCallingAddressAreaCode(),callRecord.getAnswerAddressAreaCode())==1){
tep.userRecords.addcallinglnPrivinceRecords(callRecord);
}
if(judgechargemode(callRecord.getCallingAddressAreaCode(),callRecord.getAnswerAddressAreaCode())==2){
tep.userRecords.addcallinlnLandRecords(callRecord);
}}
}
s= sc.nextLine();
}
数据处理
三 . 计算金额
public double calCost(UserRecords userRecords){
double sum=0;
for(ChargeRule a:chargeRules){
sum+=a.calCost(userRecords);
}
return sum;
}
在每个计费规则中都有相应的计算 在这就放市内的
public double calCost(UserRecords records){
double sum =0;
for(CallRecord a:records.callinglnCityRecords)
if(calculate_minute(a.getStartTime(),a.getEndTime())>=0)
sum+=calculate_minute(a.getStartTime(),a.getEndTime());
return (sum*0.1);
}
public static int calculate_minute(Date d1, Date d2){
long from = d1.getTime();
long after= d2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
四 .输出数据结果
public static void outans(ArrayList<User> user){
user= Coincident(user);//去重
java.util.Collections.sort(user);//排序
for (User a :user)
System.out.printf("%s %.1f %.1f\n",a.number,a.chargeMode.calCost(a.userRecords),a.balance-a.chargeMode.getMonthlyRent()-a.chargeMode.calCost(a.userRecords));
}
7-1 电信计费系列2-手机+座机计费
分数 80
作者 蔡轲
单位 南昌航空大学
实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
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.lang.reflect.Array;
import java.text.ParseException;
import java.util.*;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import static java.util.Arrays.sort;
public class Main {
public static void main(String[] args) throws ParseException {
String s ;
Scanner sc= new Scanner(System.in);
s= sc.nextLine();
Input in;
ArrayList<User> user = new ArrayList<>();
CommunicationRecord callRecord = new CallRecord();
while(!s.equals("end")){
in= new Input(s);
in.LandlinePhone(user, (CallRecord) callRecord);
s= sc.nextLine();
}
outans(user);
// u-18907910010 3
// m-18907910010 13305862264 aaaaaaaaaaaa
// m-18907910010 13305862264 aaaaaaa.
// m-18907910010 13305862264 bb,bbbb
// end
}
public static int calculate_minute(Date d1, Date d2){
long from = d1.getTime();
long after= d2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
public static int judgechargemode(String s1,String s2){
return judgechargemodes1(s1)*10+judgechargemodes2(s2);
}
public static int judgechargemodes2(String s2){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s2.matches(iscity))
return 1;
if(s2.matches(isprovince))
return 2;
return 3;
}
public static int judgechargemodes1(String s1){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s1.matches(iscity))
return 1;
if(s1.matches(isprovince))
return 2;
return 3;
}
public static void outans(ArrayList<User> user){
user= User.Coincident(user);
Collections.sort(user);
for (User a :user) {
System.out.printf("%s %.1f %.1f\n",
a.number,a.chargeMode.calCost(a.userRecords, Integer.parseInt(a.chageMode)),
a.balance-a.chargeMode.getMonthlyRent(Integer.parseInt(a.chageMode))-a.chargeMode.calCost(a.userRecords,Integer.parseInt(a.chageMode)));
}
}
}
class Input{
static String s ;
int flag=0;
Input(String a){
this.s = a;
}
void LandlinePhone(ArrayList<User> user, CallRecord callRecord) throws ParseException {
if(this.UserLegal()||this.PhoneNumberLegal()){
User tep= new User();
tep.setNumber(this.Usercheck()[0]);
user.add(tep);
ChargeMode chargeMode= new LandlinePhoneCharging();
chargeMode.chargeRules.add(new LandPhonelnCityRule());
chargeMode.chargeRules.add(new LandPhoneProvinceRule());
chargeMode.chargeRules.add(new LandPhonelnlandRule());
chargeMode.chargeRules.add(new SendMessgaeRule());
tep.serChargeMode(chargeMode);
tep.chageMode = this.getChageMode();
}
else if(this.RecordLegal()){
callRecord= new CallRecord(this.getstartTime(),this.getendTime(),this.getcallingAddressAreaCode(),this.getanswerAddressAreaCode());
User tep =null;
User tep1 = null;
user= User.Coincident(user);
for(User a:user){
if(a.getNumber().equals(this.getcalling()))
tep= a;
if(a.getNumber().equals(this.getRecord()))
tep1= a;
}
if(tep!=null) {
//System.out.println(tep.number);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 1)
tep.userRecords.addcallinglnCityRecords(callRecord);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 2)
tep.userRecords.addcallinglnPrivinceRecords(callRecord);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 3)
tep.userRecords.addcallinlnLandRecords(callRecord);
}
if(tep1 != null){
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 1)
tep1.userRecords.addanswerlnCityRecords(callRecord);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 2)
tep1.userRecords.addanswerlnPrivinceRecords(callRecord);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 3)
tep1.userRecords.addanswerlnLandRecords(callRecord);
}
}
else if(MessageLegal()){
String phone = s.substring(2,13);
String messgae = s.substring(26);
MessageRecord messageRecord = new MessageRecord();
messageRecord.setMessage(messgae);
User tep =null;
user= User.Coincident(user);
for(User a:user){
if(a.getNumber().equals(phone))
tep= a;
}
if(tep!=null) {
tep.userRecords.addsendMessageRecords(messageRecord);
}
}
}
boolean UserLegal(){
String [] ss= s.split(" ");
if(ss.length!=2) return false;
String legal= "u-(0701|079\\d){1}\\d{7,8}[\\ ][0-3]";
return s.matches(legal);
}
boolean PhoneNumberLegal(){
String [] ss= s.split(" ");
if(ss.length!=2) return false;
String legal= "u-1[3-9][\\d]{9}[\\ ][0-3]";
return s.matches(legal);
}
String[] Usercheck(){
String tep=s.substring(2);
String[] ss = tep.split(" ");
return ss;
}
boolean RecordLegal() throws ParseException {
String[] ss = s.split(" ");
//if(ss.length!=6) return false;
String PhoneLegal= "1[3-9][\\d]{9}";
String AddressAreaCode = "[0]([\\d]{2}|[\\d]{3})";
String legal = "0[\\d]{2,3}[\\d]{7,8}";
String legal2 = "((2[0-3])|([0-1]?[0-9])):[0-5][0-9]:[0-5][0-9]";
if(ss.length==6)
return (ss[0].matches("[t]-"+legal) )&& (ss[1].matches(legal))
&& checktime(ss[2]) && checktime(ss[4]) && ss[3].matches(legal2) && ss[5].matches(legal2);
if(ss.length==7&&ss[0].matches("[t]-"+PhoneLegal)) {
flag=2;
return (ss[0].matches("[t]-" + PhoneLegal)) && (ss[1].matches(AddressAreaCode)) && ss[2].matches(legal)
&& checktime(ss[3]) && checktime(ss[5]) && ss[4].matches(legal2) && ss[6].matches(legal2);
}
else if(ss.length==7&&ss[0].matches("[t]-"+legal)) {
flag= 1;
return (ss[0].matches("[t]-" + legal)) && (ss[1].matches(PhoneLegal)) && ss[2].matches(AddressAreaCode)
&& checktime(ss[3]) && checktime(ss[5]) && ss[4].matches(legal2) && ss[6].matches(legal2);
}
if(ss.length==8) {
return (ss[0].matches("[t]-" + PhoneLegal)) && (ss[1].matches(AddressAreaCode)) && ss[2].matches(PhoneLegal) && (ss[3].matches(AddressAreaCode))
&& checktime(ss[4]) && checktime(ss[6]) && ss[5].matches(legal2) && ss[7].matches(legal2);
}
return false;
}
boolean MessageLegal(){
if(s.length()<26){
return false;
}
String PhoneLegal= "1[3-9][\\d]{9}";
String messageLegal = "[\\d|\\w|\\s|\\.|\\,]{1,}";
String tep = s.substring(0,26);
String message = s.substring(26);
String ss[] = tep.split(" ");
return ss[0].matches("m-"+PhoneLegal)&& ss[1].matches(PhoneLegal) && message.matches(messageLegal);
}
boolean isLegalDate(String s){
boolean judgeresult=true;
//1、首先使用SimpleDateFormat初步进行判断,过滤掉注入 yyyy-01-32 或yyyy-00-0x等格式
//此处可根据实际需求进行调整,如需判断yyyy/MM/dd格式将参数改掉即可
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd");
try{
//增加强判断条件,否则 诸如2022-02-29也可判断出去
format.setLenient(false);
Date date =format.parse(s);
//System.out.println(date);
}catch(Exception e){
judgeresult=false;
}
// //由于上述方法只能验证正常的日期格式,像诸如 0001-01-01、11-01-01,10001-01-01等无法校验,此处再添加校验年费是否合法
// String yearStr=s.split(".")[0];
// if(yearStr.startsWith("0")||yearStr.length()!=4){
// judgeresult=false;
// }
return judgeresult;
}
public boolean checktime(String date) //检查年月日的合理性
{
if(!date.matches("[1-9]\\d{3}\\.\\d{1,2}\\.\\d{1,2}")) return false;
if(!date.matches("\\d{4}\\.(\\d|[1-9]\\d)\\.(\\d|[1-9]\\d)")) return false;
String[] num = date.split("\\.");
int year = Integer.parseInt(num[0]);
int month = Integer.parseInt(num[1]);
int day = Integer.parseInt(num[2]);
if(month<1||month>12) return false;
if(day<1) return false;
int[] months={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if((year%400==0)||(year%4==0&&year%100!=0))
{
months[2]++;
}
return day <= months[month];
}
Date getstartTime() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d1 = null;
if(ss.length==6)
d1=ss[2]+" "+ss[3];
else if(ss.length==7)
d1=ss[3]+" "+ss[4];
else if(ss.length==8)
d1=ss[4]+" "+ss[5];
Date date1= format.parse(d1);
return date1;
}
Date getendTime() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d2 = null;
if(ss.length==6)
d2 = ss[4]+" "+ss[5];
else if(ss.length==7)
d2 = ss[5]+" "+ss[6];
else if(ss.length==8)
d2 = ss[6]+" "+ss[7];
Date date2= format.parse(d2);
return date2;
}
static int calculate_minute() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d1=ss[2]+" "+ss[3];
String d2 = ss[4]+" "+ss[5];
Date date1= format.parse(d1);
Date date2= format.parse(d2);
long from = date1.getTime();
long after= date2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
String getcalling(){
String[] ss = s.split(" ");
return ss[0].substring(2);
}
String getRecord (){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss.length==8)
return ss[2];
if(ss.length==7&&flag==2)
return ss[2];
return ss[1];
}
String getChageMode(){
String[] ss = s.split(" ");
return ss[1];
}
String getcallingAddressAreaCode(){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss.length==7&&flag==2){
return ss[1];
}
if(ss.length==8){
return ss[1];
}
if (ss[0].length() == 10)
return ss[0].substring(0, 3);
return ss[0].substring(0, 4);
}
String getanswerAddressAreaCode(){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss.length==7&&flag==1){
return ss[2];
}
if(ss.length==7&&flag==2){
if(ss[2].length()==10)
return ss[2].substring(0,3);
return ss[2].substring(0,4);
}
if(ss.length==8){
return ss[3];
}
if(ss[1].length()==10)
return ss[1].substring(0,3);
return ss[1].substring(0,4);
}
public static int judgechargemode(String s1,String s2){
return judgechargemodes1(s1)*10+judgechargemodes2(s2);
}
public static int judgechargemodes2(String s2){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s2.matches(iscity))
return 1;
if(s2.matches(isprovince))
return 2;
return 3;
}
public static int judgechargemodes1(String s1){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s1.matches(iscity))
return 1;
if(s1.matches(isprovince))
return 2;
return 3;
}
public static int calculate_minute(Date d1, Date d2){
long from = d1.getTime();
long after= d2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
}
class User implements Comparable<User>{
UserRecords userRecords= new UserRecords();
double balance = 100;
ChargeMode chargeMode ;
String number ;
String chageMode ;
User(){
}
User(String number ){
}
public static ArrayList<User> Coincident(ArrayList<User> user){
for (int i = 0; i < user.size()-1; i++)
for (int j = i+1; j <user.size(); j++)
if(user.get(i).number.equals(user.get(j).number))
user.remove(i);
return user;
}
double calBalance(){
return 0;
}
double calCost(){
return 0;
}
UserRecords getUserRecords(){
return userRecords;
}
void setUserRecords(UserRecords userRecords){
this.userRecords=userRecords;
}
double getBalance(){
return this.balance;
}
ChargeMode getChargeMode(){
return chargeMode;
}
void serChargeMode(ChargeMode chargeMode){
this.chargeMode=chargeMode;
}
String getNumber(){
return this.number;
}
void setNumber(String number){
this.number=number;
}
public int compareTo(User newuser){
return String.CASE_INSENSITIVE_ORDER.compare(this.number,newuser.number);
}
}
class UserRecords{
ArrayList<CallRecord> callinglnCityRecords= new ArrayList<>();//市内拨打电话
ArrayList<CallRecord> callinglnPrivinceRecords= new ArrayList<>();//省内(不含市内)拨打电话
ArrayList<CallRecord> callinlnLandRecords= new ArrayList<>();//省外拨打电话
ArrayList<CallRecord> answerlnCityRecords= new ArrayList<>();//市内接听电话
ArrayList<CallRecord> answerlnPrivinceRecords= new ArrayList<>();//省内(不含市内)接听电话
ArrayList<CallRecord> answerlnLandRecords= new ArrayList<>();//省外接听电话的记录
ArrayList<MessageRecord> sendMessageRecords= new ArrayList<>();//发送短信
ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>();//接收短信的记录
public void addcallinglnCityRecords(CallRecord callRecord) {
callinglnCityRecords.add(callRecord);
}
public void addcallinglnPrivinceRecords(CallRecord callRecord) {
callinglnPrivinceRecords.add(callRecord);
}
public void addcallinlnLandRecords(CallRecord callRecord) {
callinlnLandRecords.add(callRecord);
}
public void addanswerlnCityRecords(CallRecord callRecord) {
answerlnCityRecords.add(callRecord);
}
public void addanswerlnPrivinceRecords(CallRecord callRecord) {
answerlnPrivinceRecords.add(callRecord);
}
public void addanswerlnLandRecords(CallRecord callRecord) {
answerlnLandRecords.add(callRecord);
}
public void addsendMessageRecords(MessageRecord callRecord) {
sendMessageRecords.add(callRecord);
}
public void addreceiveMessageRecords(MessageRecord callRecord) {
receiveMessageRecords.add(callRecord);
}
}
class CallRecord extends CommunicationRecord{
private Date startTime;
private Date endTime ;
private String callingAddressAreaCode;//拨号地点的区号
private String answerAddressAreaCode;//接听地点的区号
CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode){
this.startTime=startTime;
this.endTime=endTime;
this.callingAddressAreaCode=callingAddressAreaCode;
this.answerAddressAreaCode=answerAddressAreaCode;
}
public CallRecord() {
}
public Date getStartTime() {
return startTime;
}
public String getAnswerAddressAreaCode() {
return answerAddressAreaCode;
}
public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
this.answerAddressAreaCode = answerAddressAreaCode;
}
public String getCallingAddressAreaCode() {
return callingAddressAreaCode;
}
public void setCallingAddressAreaCode(String callingAddressAreaCode) {
this.callingAddressAreaCode = callingAddressAreaCode;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
}
abstract class ChargeMode{
ArrayList<ChargeRule> chargeRules = new ArrayList<>();
public abstract double calCost(UserRecords userRecords,int n);
public abstract double getMonthlyRent(int n);
public ArrayList<ChargeRule> getChargeRules() {
return chargeRules;
}
public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
this.chargeRules = chargeRules;
}
}
abstract class ChargeRule{
abstract double calCost(UserRecords records,int n );
}
abstract class CommunicationRecord {
protected String callingNumber;
protected String answerNumber;
protected String getCallingNumber(){
return this.callingNumber;
}
public void setCallingNumber(String callingNumber){
this.callingNumber=callingNumber;
}
public String getAnswerNumber(){
return this.answerNumber;
}
public void setAnswerNumber(String answerNumber){
this.answerNumber=answerNumber;
}
}
class LandlinePhoneCharging extends ChargeMode{
double monthlyRent =20 ;
public double calCost(UserRecords userRecords,int n){
double sum=0;
for(ChargeRule a:chargeRules){
sum+=a.calCost(userRecords,n);
}
return sum;
}
public double getMonthlyRent(int n){
if(n==0)
return monthlyRent;
else if(n==1)
return 15;
return 0;
}
}
class LandPhonelnCityRule extends ChargeRule{
public double calCost(UserRecords records,int n){
double sum =0,sum1=0,sum2=0,sum3=0;
double money=0;
if(n==0) {
for (CallRecord a : records.callinglnCityRecords)
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
money= (sum * 0.1);
}
if(n==1){
for (CallRecord a : records.callinglnCityRecords){
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==1)
sum1 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==2)
sum2 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==3)
sum3 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
money= (sum1 * 0.1)+sum2*0.3+sum3*0.6;
}
return money;
}
}
class LandPhonelnlandRule extends ChargeRule{
public double calCost (UserRecords records,int n ){
double sum =0,sum1=0,sum2=0,sum3=0;
double money=0;
if(n==0) {
for (CallRecord a : records.callinlnLandRecords)
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
money+= (sum * 0.6);
}
if(n==1){
for (CallRecord a : records.callinlnLandRecords){
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==1)
sum1 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==2)
sum2 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==3)
sum3 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
for (CallRecord a : records.answerlnLandRecords){
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
money= (sum1 * 0.3)+sum2*0.3+sum3*0.6+sum*0.3;
}
return money;
}
}
class LandPhoneProvinceRule extends ChargeRule{
public double calCost (UserRecords records,int n ){
double sum =0,sum1=0,sum2=0,sum3=0;
double money = 0;
if(n==0) {
for (CallRecord a : records.callinglnPrivinceRecords)
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
money= (sum * 0.3);
}
if(n==1){
for (CallRecord a : records.callinglnPrivinceRecords){
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==1)
sum1 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==2)
sum2 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==3)
sum3 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
money= (sum1 * 0.2)+sum2*0.3+sum3*0.6;
}
return money;
}
}
abstract class MessageChargeRule extends ChargeRule{
}
class MessageRecord extends CommunicationRecord{
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
class SendMessgaeRule extends MessageChargeRule{
@Override
double calCost(UserRecords records, int n) {
double sum =0;
int w=0;
if(n==3){
for(MessageRecord a:records.sendMessageRecords){
int num =(a.getMessage().length() + 10 - 1) / 10;
w+=num;
}
if(w>3&&w<=5)
sum+= (w-3)*0.2+0.3;
else if(w>5)
sum+= (w-5)*0.3+2*0.2+0.3;
else
sum+= w*0.1;
}
return sum;
}
}
View Code
类图
这类图是有点抽象。
SourceMonitor生成报表:
题目分析
这次的和上次的差不多就是多加了手机号的判断。
1.用户检测
要注意的是手机号的第二位只能在3-9之间(特地搜到的),这里有一个测试点。
boolean UserLegal(){
String [] ss= s.split(" ");
if(ss.length!=2) return false;
String legal= "u-(0701|079\\d){1}\\d{7,8}[\\ ][0-3]";
return s.matches(legal);
}
boolean PhoneNumberLegal(){
String [] ss= s.split(" ");
if(ss.length!=2) return false;
String legal= "u-1[3-9][\\d]{9}[\\ ][0-3]";
return s.matches(legal);
}
2.用户记录检测
有手机号和座机号的时候有两种情况,我这用一个flag来标记来区分,时间的检测和上次是一样的。
boolean RecordLegal() throws ParseException {
String[] ss = s.split(" ");
//if(ss.length!=6) return false;
String PhoneLegal= "1[3-9][\\d]{9}";
String AddressAreaCode = "[0]([\\d]{2}|[\\d]{3})";
String legal = "0[\\d]{2,3}[\\d]{7,8}";
String legal2 = "((2[0-3])|([0-1]?[0-9])):[0-5][0-9]:[0-5][0-9]";
if(ss.length==6)
return (ss[0].matches("[t]-"+legal) )&& (ss[1].matches(legal))
&& checktime(ss[2]) && checktime(ss[4]) && ss[3].matches(legal2) && ss[5].matches(legal2);
if(ss.length==7&&ss[0].matches("[t]-"+PhoneLegal)) {
flag=2;
return (ss[0].matches("[t]-" + PhoneLegal)) && (ss[1].matches(AddressAreaCode)) && ss[2].matches(legal)
&& checktime(ss[3]) && checktime(ss[5]) && ss[4].matches(legal2) && ss[6].matches(legal2);
}
else if(ss.length==7&&ss[0].matches("[t]-"+legal)) {
flag= 1;
return (ss[0].matches("[t]-" + legal)) && (ss[1].matches(PhoneLegal)) && ss[2].matches(AddressAreaCode)
&& checktime(ss[3]) && checktime(ss[5]) && ss[4].matches(legal2) && ss[6].matches(legal2);
}
if(ss.length==8) {
return (ss[0].matches("[t]-" + PhoneLegal)) && (ss[1].matches(AddressAreaCode)) && ss[2].matches(PhoneLegal) && (ss[3].matches(AddressAreaCode))
&& checktime(ss[4]) && checktime(ss[6]) && ss[5].matches(legal2) && ss[7].matches(legal2);
}
return false;
}
3.输入的处理
有两种情况,要注意判断返回。
String getcalling(){
String[] ss = s.split(" ");
return ss[0].substring(2);
}
String getRecord (){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss.length==8)
return ss[2];
if(ss.length==7&&flag==2)
return ss[2];
return ss[1];
}
String getChageMode(){
String[] ss = s.split(" ");
return ss[1];
}
String getcallingAddressAreaCode(){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss.length==7&&flag==2){
return ss[1];
}
if(ss.length==8){
return ss[1];
}
if (ss[0].length() == 10)
return ss[0].substring(0, 3);
return ss[0].substring(0, 4);
}
String getanswerAddressAreaCode(){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss.length==7&&flag==1){
return ss[2];
}
if(ss.length==7&&flag==2){
if(ss[2].length()==10)
return ss[2].substring(0,3);
return ss[2].substring(0,4);
}
if(ss.length==8){
return ss[3];
}
if(ss[1].length()==10)
return ss[1].substring(0,3);
return ss[1].substring(0,4);
}
public static int judgechargemode(String s1,String s2){
return judgechargemodes1(s1)*10+judgechargemodes2(s2);
}
public static int judgechargemodes2(String s2){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s2.matches(iscity))
return 1;
if(s2.matches(isprovince))
return 2;
return 3;
}
public static int judgechargemodes1(String s1){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s1.matches(iscity))
return 1;
if(s1.matches(isprovince))
return 2;
return 3;
}
public static int calculate_minute(Date d1, Date d2){
long from = d1.getTime();
long after= d2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
4.数据处理
手机接电话也要记录下来。
void LandlinePhone(ArrayList<User> user, CallRecord callRecord) throws ParseException {
if(this.UserLegal()||this.PhoneNumberLegal()){
User tep= new User();
tep.setNumber(this.Usercheck()[0]);
user.add(tep);
ChargeMode chargeMode= new LandlinePhoneCharging();
chargeMode.chargeRules.add(new LandPhonelnCityRule());
chargeMode.chargeRules.add(new LandPhoneProvinceRule());
chargeMode.chargeRules.add(new LandPhonelnlandRule());
chargeMode.chargeRules.add(new SendMessgaeRule());
tep.serChargeMode(chargeMode);
tep.chageMode = this.getChageMode();
}
else if(this.RecordLegal()){
callRecord= new CallRecord(this.getstartTime(),this.getendTime(),this.getcallingAddressAreaCode(),this.getanswerAddressAreaCode());
User tep =null;
User tep1 = null;
user= User.Coincident(user);
for(User a:user){
if(a.getNumber().equals(this.getcalling()))
tep= a;
if(a.getNumber().equals(this.getRecord()))
tep1= a;
}
if(tep!=null) {
//System.out.println(tep.number);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 1)
tep.userRecords.addcallinglnCityRecords(callRecord);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 2)
tep.userRecords.addcallinglnPrivinceRecords(callRecord);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 3)
tep.userRecords.addcallinlnLandRecords(callRecord);
}
if(tep1 != null){
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 1)
tep1.userRecords.addanswerlnCityRecords(callRecord);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 2)
tep1.userRecords.addanswerlnPrivinceRecords(callRecord);
if (judgechargemodes2(callRecord.getAnswerAddressAreaCode()) == 3)
tep1.userRecords.addanswerlnLandRecords(callRecord);
}
}
else if(MessageLegal()){
String phone = s.substring(2,13);
String messgae = s.substring(26);
MessageRecord messageRecord = new MessageRecord();
messageRecord.setMessage(messgae);
User tep =null;
user= User.Coincident(user);
for(User a:user){
if(a.getNumber().equals(phone))
tep= a;
}
if(tep!=null) {
tep.userRecords.addsendMessageRecords(messageRecord);
}
}
}
5.计算金额
市内的情况
public double calCost(UserRecords records,int n){
double sum =0,sum1=0,sum2=0,sum3=0;
double money=0;
if(n==0) {
for (CallRecord a : records.callinglnCityRecords)
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
money= (sum * 0.1);
}
if(n==1){
for (CallRecord a : records.callinglnCityRecords){
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==1)
sum1 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==2)
sum2 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==3)
sum3 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
money= (sum1 * 0.1)+sum2*0.3+sum3*0.6;
}
return money;
}
省内的情况
public double calCost (UserRecords records,int n ){
double sum =0,sum1=0,sum2=0,sum3=0;
double money = 0;
if(n==0) {
for (CallRecord a : records.callinglnPrivinceRecords)
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
money= (sum * 0.3);
}
if(n==1){
for (CallRecord a : records.callinglnPrivinceRecords){
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==1)
sum1 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==2)
sum2 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==3)
sum3 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
money= (sum1 * 0.2)+sum2*0.3+sum3*0.6;
}
return money;
}
省外的情况
public double calCost (UserRecords records,int n ){
double sum =0,sum1=0,sum2=0,sum3=0;
double money=0;
if(n==0) {
for (CallRecord a : records.callinlnLandRecords)
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
money+= (sum * 0.6);
}
if(n==1){
for (CallRecord a : records.callinlnLandRecords){
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==1)
sum1 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==2)
sum2 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==3)
sum3 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
for (CallRecord a : records.answerlnLandRecords){
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
money= (sum1 * 0.3)+sum2*0.3+sum3*0.6+sum*0.3;
}
return money;
}
7-1 电信计费系列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.lang.reflect.Array;
import java.text.ParseException;
import java.util.*;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import static java.util.Arrays.sort;
public class Main {
public static void main(String[] args) throws ParseException {
String s ;
Scanner sc= new Scanner(System.in);
s= sc.nextLine();
Input in;
ArrayList<User> user = new ArrayList<>();
CommunicationRecord callRecord = new CallRecord();
while(!s.equals("end")){
in= new Input(s);
in.LandlinePhone(user, (CallRecord) callRecord);
s= sc.nextLine();
}
outans(user);
}
public static int calculate_minute(Date d1, Date d2){
long from = d1.getTime();
long after= d2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
public static int judgechargemode(String s1,String s2){
return judgechargemodes1(s1)*10+judgechargemodes2(s2);
}
public static int judgechargemodes2(String s2){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s2.matches(iscity))
return 1;
if(s2.matches(isprovince))
return 2;
return 3;
}
public static int judgechargemodes1(String s1){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s1.matches(iscity))
return 1;
if(s1.matches(isprovince))
return 2;
return 3;
}
public static void outans(ArrayList<User> user){
user= User.Coincident(user);
Collections.sort(user);
for (User a :user) {
System.out.printf("%s %.1f %.1f\n",
a.number,a.chargeMode.calCost(a.userRecords, Integer.parseInt(a.chageMode)),
a.balance-a.chargeMode.getMonthlyRent(Integer.parseInt(a.chageMode))-a.chargeMode.calCost(a.userRecords,Integer.parseInt(a.chageMode)));
}
}
}
class Input{
static String s ;
int flag=0;
Input(String a){
this.s = a;
}
void LandlinePhone(ArrayList<User> user, CallRecord callRecord) throws ParseException {
if(this.UserLegal()||this.PhoneNumberLegal()){
User tep= new User();
tep.setNumber(this.Usercheck()[0]);
user.add(tep);
ChargeMode chargeMode= new LandlinePhoneCharging();
chargeMode.chargeRules.add(new LandPhonelnCityRule());
chargeMode.chargeRules.add(new LandPhoneProvinceRule());
chargeMode.chargeRules.add(new LandPhonelnlandRule());
chargeMode.chargeRules.add(new SendMessgaeRule());
tep.serChargeMode(chargeMode);
tep.chageMode = this.getChageMode();
}
else if(MessageLegal()){
String phone = s.substring(2,13);
String messgae = s.substring(26);
MessageRecord messageRecord = new MessageRecord();
messageRecord.setMessage(messgae);
User tep =null;
user= User.Coincident(user);
for(User a:user){
if(a.getNumber().equals(phone))
tep= a;
}
if(tep!=null) {
tep.userRecords.addsendMessageRecords(messageRecord);
}
}
}
boolean UserLegal(){
String [] ss= s.split(" ");
if(ss.length!=2) return false;
String legal= "u-(0701|079\\d){1}\\d{7,8}[\\ ][0-3]";
return s.matches(legal);
}
boolean PhoneNumberLegal(){
String [] ss= s.split(" ");
if(ss.length!=2) return false;
String legal= "u-1[3-9][\\d]{9}[\\ ][0-3]";
return s.matches(legal);
}
String[] Usercheck(){
String tep=s.substring(2);
String[] ss = tep.split(" ");
return ss;
}
boolean MessageLegal(){
if(s.length()<26){
return false;
}
String PhoneLegal= "1[3-9][\\d]{9}";
String messageLegal = "[\\d|\\w|\\s|\\.|\\,]{1,}";
String tep = s.substring(0,26);
String message = s.substring(26);
String ss[] = tep.split(" ");
return ss[0].matches("m-"+PhoneLegal)&& ss[1].matches(PhoneLegal) && message.matches(messageLegal);
}
public boolean checktime(String date) //检查年月日的合理性
{
if(!date.matches("[1-9]\\d{3}\\.\\d{1,2}\\.\\d{1,2}")) return false;
if(!date.matches("\\d{4}\\.(\\d|[1-9]\\d)\\.(\\d|[1-9]\\d)")) return false;
String[] num = date.split("\\.");
int year = Integer.parseInt(num[0]);
int month = Integer.parseInt(num[1]);
int day = Integer.parseInt(num[2]);
if(month<1||month>12) return false;
if(day<1) return false;
int[] months={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if((year%400==0)||(year%4==0&&year%100!=0))
months[2]++;
return day <= months[month];
}
static int calculate_minute() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] ss = s.split(" ");
String d1=ss[2]+" "+ss[3];
String d2 = ss[4]+" "+ss[5];
Date date1= format.parse(d1);
Date date2= format.parse(d2);
long from = date1.getTime();
long after= date2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
String getcalling(){
String[] ss = s.split(" ");
return ss[0].substring(2);
}
String getRecord (){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss.length==8)
return ss[2];
if(ss.length==7&&flag==2)
return ss[2];
return ss[1];
}
String getChageMode(){
String[] ss = s.split(" ");
return ss[1];
}
String getcallingAddressAreaCode(){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss.length==7&&flag==2){
return ss[1];
}
if(ss.length==8){
return ss[1];
}
if (ss[0].length() == 10)
return ss[0].substring(0, 3);
return ss[0].substring(0, 4);
}
String getanswerAddressAreaCode(){
String tep= s.substring(2);
String[] ss=tep.split(" ");
if(ss.length==7&&flag==1){
return ss[2];
}
if(ss.length==7&&flag==2){
if(ss[2].length()==10)
return ss[2].substring(0,3);
return ss[2].substring(0,4);
}
if(ss.length==8){
return ss[3];
}
if(ss[1].length()==10)
return ss[1].substring(0,3);
return ss[1].substring(0,4);
}
public static int judgechargemode(String s1,String s2){
return judgechargemodes1(s1)*10+judgechargemodes2(s2);
}
public static int judgechargemodes2(String s2){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s2.matches(iscity))
return 1;
if(s2.matches(isprovince))
return 2;
return 3;
}
public static int judgechargemodes1(String s1){
String isprovince="(079[0-9]|0701)";
String iscity="0791";
if(s1.matches(iscity))
return 1;
if(s1.matches(isprovince))
return 2;
return 3;
}
public static int calculate_minute(Date d1, Date d2){
long from = d1.getTime();
long after= d2.getTime();
int miao = (int )((after-from)/1000);
int fen = (int) Math.ceil(miao*1.0/60);
return fen;
}
}
class User implements Comparable<User>{
UserRecords userRecords= new UserRecords();
double balance = 100;
ChargeMode chargeMode ;
String number ;
String chageMode ;
User(){
}
User(String number ){
}
public static ArrayList<User> Coincident(ArrayList<User> user){
for (int i = 0; i < user.size()-1; i++)
for (int j = i+1; j <user.size(); j++)
if(user.get(i).number.equals(user.get(j).number))
user.remove(i);
return user;
}
double calBalance(){
return 0;
}
double calCost(){
return 0;
}
UserRecords getUserRecords(){
return userRecords;
}
void setUserRecords(UserRecords userRecords){
this.userRecords=userRecords;
}
double getBalance(){
return this.balance;
}
ChargeMode getChargeMode(){
return chargeMode;
}
void serChargeMode(ChargeMode chargeMode){
this.chargeMode=chargeMode;
}
String getNumber(){
return this.number;
}
void setNumber(String number){
this.number=number;
}
public int compareTo(User newuser){
return String.CASE_INSENSITIVE_ORDER.compare(this.number,newuser.number);
}
}
class UserRecords{
ArrayList<CallRecord> callinglnCityRecords= new ArrayList<>();//市内拨打电话
ArrayList<CallRecord> callinglnPrivinceRecords= new ArrayList<>();//省内(不含市内)拨打电话
ArrayList<CallRecord> callinlnLandRecords= new ArrayList<>();//省外拨打电话
ArrayList<CallRecord> answerlnCityRecords= new ArrayList<>();//市内接听电话
ArrayList<CallRecord> answerlnPrivinceRecords= new ArrayList<>();//省内(不含市内)接听电话
ArrayList<CallRecord> answerlnLandRecords= new ArrayList<>();//省外接听电话的记录
ArrayList<MessageRecord> sendMessageRecords= new ArrayList<>();//发送短信
ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>();//接收短信的记录
public void addcallinglnCityRecords(CallRecord callRecord) {
callinglnCityRecords.add(callRecord);
}
public void addcallinglnPrivinceRecords(CallRecord callRecord) {
callinglnPrivinceRecords.add(callRecord);
}
public void addcallinlnLandRecords(CallRecord callRecord) {
callinlnLandRecords.add(callRecord);
}
public void addanswerlnCityRecords(CallRecord callRecord) {
answerlnCityRecords.add(callRecord);
}
public void addanswerlnPrivinceRecords(CallRecord callRecord) {
answerlnPrivinceRecords.add(callRecord);
}
public void addanswerlnLandRecords(CallRecord callRecord) {
answerlnLandRecords.add(callRecord);
}
public void addsendMessageRecords(MessageRecord callRecord) {
sendMessageRecords.add(callRecord);
}
public void addreceiveMessageRecords(MessageRecord callRecord) {
receiveMessageRecords.add(callRecord);
}
}
class CallRecord extends CommunicationRecord{
private Date startTime;
private Date endTime ;
private String callingAddressAreaCode;//拨号地点的区号
private String answerAddressAreaCode;//接听地点的区号
CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode){
this.startTime=startTime;
this.endTime=endTime;
this.callingAddressAreaCode=callingAddressAreaCode;
this.answerAddressAreaCode=answerAddressAreaCode;
}
public CallRecord() {
}
public Date getStartTime() {
return startTime;
}
public String getAnswerAddressAreaCode() {
return answerAddressAreaCode;
}
public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
this.answerAddressAreaCode = answerAddressAreaCode;
}
public String getCallingAddressAreaCode() {
return callingAddressAreaCode;
}
public void setCallingAddressAreaCode(String callingAddressAreaCode) {
this.callingAddressAreaCode = callingAddressAreaCode;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
}
abstract class ChargeMode{
ArrayList<ChargeRule> chargeRules = new ArrayList<>();
public abstract double calCost(UserRecords userRecords,int n);
public abstract double getMonthlyRent(int n);
public ArrayList<ChargeRule> getChargeRules() {
return chargeRules;
}
public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
this.chargeRules = chargeRules;
}
}
abstract class ChargeRule{
abstract double calCost(UserRecords records,int n );
}
abstract class CommunicationRecord {
protected String callingNumber;
protected String answerNumber;
protected String getCallingNumber(){
return this.callingNumber;
}
public void setCallingNumber(String callingNumber){
this.callingNumber=callingNumber;
}
public String getAnswerNumber(){
return this.answerNumber;
}
public void setAnswerNumber(String answerNumber){
this.answerNumber=answerNumber;
}
}
class LandlinePhoneCharging extends ChargeMode{
double monthlyRent =20 ;
public double calCost(UserRecords userRecords,int n){
double sum=0;
for(ChargeRule a:chargeRules){
sum+=a.calCost(userRecords,n);
}
return sum;
}
public double getMonthlyRent(int n){
if(n==0)
return monthlyRent;
else if(n==1)
return 15;
return 0;
}
}
class LandPhonelnCityRule extends ChargeRule{
public double calCost(UserRecords records,int n){
double sum =0,sum1=0,sum2=0,sum3=0;
double money=0;
if(n==0) {
for (CallRecord a : records.callinglnCityRecords)
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
money= (sum * 0.1);
}
if(n==1){
for (CallRecord a : records.callinglnCityRecords){
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==1)
sum1 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==2)
sum2 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==3)
sum3 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
money= (sum1 * 0.1)+sum2*0.3+sum3*0.6;
}
return money;
}
}
class LandPhonelnlandRule extends ChargeRule{
public double calCost (UserRecords records,int n ){
double sum =0,sum1=0,sum2=0,sum3=0;
double money=0;
if(n==0) {
for (CallRecord a : records.callinlnLandRecords)
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
money+= (sum * 0.6);
}
if(n==1){
for (CallRecord a : records.callinlnLandRecords){
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==1)
sum1 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==2)
sum2 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==3)
sum3 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
for (CallRecord a : records.answerlnLandRecords){
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
money= (sum1 * 0.3)+sum2*0.3+sum3*0.6+sum*0.3;
}
return money;
}
}
class LandPhoneProvinceRule extends ChargeRule{
public double calCost (UserRecords records,int n ){
double sum =0,sum1=0,sum2=0,sum3=0;
double money = 0;
if(n==0) {
for (CallRecord a : records.callinglnPrivinceRecords)
sum += Main.calculate_minute(a.getStartTime(), a.getEndTime());
money= (sum * 0.3);
}
if(n==1){
for (CallRecord a : records.callinglnPrivinceRecords){
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==1)
sum1 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==2)
sum2 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
if(Main.judgechargemodes1(a.getCallingAddressAreaCode())==3)
sum3 += Main.calculate_minute(a.getStartTime(), a.getEndTime());
}
money= (sum1 * 0.2)+sum2*0.3+sum3*0.6;
}
return money;
}
}
abstract class MessageChargeRule extends ChargeRule{
}
class MessageRecord extends CommunicationRecord{
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
class SendMessgaeRule extends MessageChargeRule{
@Override
double calCost(UserRecords records, int n) {
double sum =0;
int w=0;
if(n==3){
for(MessageRecord a:records.sendMessageRecords){
int num =(a.getMessage().length() + 10 - 1) / 10;
w+=num;
}
if(w>3&&w<=5)
sum+= (w-3)*0.2+0.3;
else if(w>5)
sum+= (w-5)*0.3+2*0.2+0.3;
else
sum+= w*0.1;
}
return sum;
}
}
View Code
类图
SourceMonitor生成报表:
题目分析
这题只需要写有关短信的,还是简单的,在前面加上短信计费方式,但不要将三次题目写在一起,会代码长度超出限制的。
计费代码
double calCost(UserRecords records, int n) {
double sum =0;
int w=0;
if(n==3){
for(MessageRecord a:records.sendMessageRecords){
int num =(a.getMessage().length() + 10 - 1) / 10;
w+=num;
}
if(w>3&&w<=5)
sum+= (w-3)*0.2+0.3;
else if(w>5)
sum+= (w-5)*0.3+2*0.2+0.3;
else
sum+= w*0.1;
}
return sum;
}
(3)采坑心得:
1. 在电信计费系列1-座机计费对于时间的检测不够严谨,比如月份以0开头,这个我调试了好久,呜呜呜。
if(!date.matches("[1-9]\\d{3}\\.\\d{1,2}\\.\\d{1,2}")) return false;
if(!date.matches("\\d{4}\\.(\\d|[1-9]\\d)\\.(\\d|[1-9]\\d)")) return false;
就行了。
2.Date的getTime()函数得到的是毫秒数,转化为秒的话需要除以1000。
3.电信计费系列3-短信计费中的短信内容 (短信内容只能由数字、字母、空格、英文逗号、英文句号组成),不能只判断字符的长度。
4.手机号的第二位在3-9之间。
5.还有要对用户先去重。
(4)改进建议:
对相应题目的编码改进给出自己的见解,做到可持续改进
这几次的大作业相较之前的大作业来说整体难度有所下降,类的设计也基本都是按着题目给的类图来设计,大家的代码都大同小异。
感觉可以写一个工厂类,在里面进行判断,返回相应的类。
(5)总结:
对本阶段(10-16周)综合性总结,学到了什么,哪些地方需要进一步学习及研究,对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见。
通过这几次大作业,我对面向对象编程的思想了解的更加深刻,对类图的获取信息,进行类图的改进,到最后的实现,都是一种练习。
这几次的大作业接近现实情况,我也是对输入不合法的情况进行了很多的判断,真的是百分之80的都是不合法的输入。