这几次的pta作业上了难度,我在编码的过程中遇到了不少困难,也让我的代码能力在苦痛中有所提升。
这几次的作业是迭代的,所以只要第一次写好了,后面的几次都会很容易,但是我在第一次作业的设计中有不少不好的地方,导致我第二次的作业写的很是痛苦,这让我学会了在下次写代码时
一定一定要先做好设计再进行编码,不然整个程序都会出现一定的差错,做到写一步,想十步。
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.math.RoundingMode; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; abstract class CallChargeRule extends ChargeRule{ public double calCost(ArrayList<CallRecord> callRecords){ return 1; } } class CallRecord extends CommunicationRecord{ private Date startTime; private Date endTime; private String callingAddressAreaCode; private String answerAddressAreaCode; public 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 void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } abstract class ChargeMode { private ArrayList<ChargeRule> chargeRules=new ArrayList<>(); private LandPhoneInProvinceRule lp = new LandPhoneInProvinceRule(); private LandPhoneInCityRule lc= new LandPhoneInCityRule(); private LandPhoneInlandRule ll= new LandPhoneInlandRule(); public ChargeMode() { chargeRules.add(lc); chargeRules.add(lp); chargeRules.add(ll); } public ArrayList<ChargeRule> getChargeRules() { return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } public double calCost(UserRecords userRecords){ return 1; } public double getMonthlyRent(){ return 1; } } abstract class ChargeRule { public double calCost(ArrayList<CallRecord> callRecords){ return 1; } } abstract class CommunicationRecord { protected String callingNum; protected String answerNumber; public String getCallingNum() { return callingNum; } public void setCallingNum(String callingNum) { this.callingNum = callingNum; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } class LandlinePhoneCharging extends ChargeMode{ private double monthlyRent=20; @Override public double calCost(UserRecords userRecords) { double num1,num2,num3,sum; num1=getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords()); num2=getChargeRules().get(1).calCost(userRecords.getCallingInProvinceRecords()); num3=getChargeRules().get(2).calCost(userRecords.getCallingInLandRecords()); sum=num1+num2+num3; return sum; } public double getMonthlyRent() { return monthlyRent; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.1; } } class LandPhoneInlandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.6; } } class LandPhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.3; } } public class Main { public static void main(String[] args) throws ParseException { int flag=0; int flags; String strss="07((9[0-9])|01)"; SimpleDateFormat sf=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); ArrayList<User> users=new ArrayList<>(); ArrayList<String []> userRecord = new ArrayList<>(); ArrayList<CallRecord> callRecords = new ArrayList<>(); LandPhoneInlandRule landPhoneInlandRule=new LandPhoneInlandRule(); LandPhoneInCityRule landPhoneInCityRule=new LandPhoneInCityRule(); LandPhoneInProvinceRule landPhoneInProvinceRule=new LandPhoneInProvinceRule(); LandlinePhoneCharging landlinePhoneCharging=new LandlinePhoneCharging(); landlinePhoneCharging.getChargeRules().add(landPhoneInCityRule); landlinePhoneCharging.getChargeRules().add(landPhoneInProvinceRule); landlinePhoneCharging.getChargeRules().add(landPhoneInlandRule); Scanner in = new Scanner(System.in); String str; StringBuilder sb = new StringBuilder(); while (true) { str = in.nextLine(); if (str.equals("end") == true) { break; } sb.append(str + "\n"); } String strNew = sb.toString(); String strs[] = strNew.split("\n"); for(int i = 0;i<strs.length;i++) { String strs2[] = strs[i].split("\\s+"); if(flag1(strs[i])){ String s; s=strs2[0].substring(2); User user=new User(); user.setNumber(s); users.add(user); }else if(flag2(strs[i])){ Date date1 = sf.parse(strs2[2]+" "+strs2[3]); Date date2 = sf.parse(strs2[4]+" "+strs2[5]); for (User user:users ) { if(user.getNumber().equals(strs2[0].substring(2))){ if(strs2[1].substring(0,4).equals("0791")){ flags=1; }else if(isInProvince(strs2[1].substring(0,4))){ flags=2; }else { flags=3; } if(flags==1){ user.getUserRecords().addCallingInCityRecords(date1,date2,strs2[0].substring(2,6),strs2[1].substring(0,4)); }else if(flags==2){ user.getUserRecords().addCallingInProvinceRecords(date1,date2,strs2[0].substring(2,6),strs2[1].substring(0,4)); }else { user.getUserRecords().addCallingInLandRecords(date1,date2,strs2[0].substring(2,6),strs2[1].substring(0,4)); } } } } } for(int i=0;i<users.size();i++){ for(int j=i+1;j<users.size();j++){ if(users.get(i).getNumber().equals(users.get(j).getNumber())) users.remove(i); } } for(User a: users){ a.calBalance(); } ArrayList<String> s = new ArrayList<>(); for(int i = 0;i<users.size();i++){ s.add(users.get(i).getNumber()); } Collections.sort(s); for(int i = 0;i< users.size();i++){ for(int j = 0;j < users.size();j++){ if(s.get(i).equals(users.get(j).getNumber())){ System.out.println(users.get(j).getNumber()+" "+Format(users.get(j).calCost())+" "+Format(users.get(j).getBalance())); } } } } public static boolean flag1(String str) { String regstr = "[u]-0791[0-9]{7,8}\\s[0]"; return str.matches(regstr); } public static boolean flag2(String str) { String regstr = "[t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s" + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?" + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s" + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.(" + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"; return str.matches(regstr); } public static String Format(double a) { DecimalFormat formater = new DecimalFormat("0.0"); formater.setRoundingMode(RoundingMode.DOWN); return formater.format(a); } public static boolean isInProvince(String s){ if(s.equals("0790")||s.equals("0792")||s.equals("0793")||s.equals("0794")||s.equals("0795")||s.equals("0796")||s.equals("0797")||s.equals("0798")||s.equals("0799")||s.equals("0701")){ return true; }else return false; } } class MessageRecord extends CommunicationRecord{ private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } class User { private UserRecords userRecords=new UserRecords(); private double balance=100; private ChargeMode chargeMode = new LandlinePhoneCharging(); private String number; public double calBalance(){ balance = balance -calCost()-chargeMode.getMonthlyRent(); return balance; } public double calCost(){ return 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; } } class UserRecords { private ArrayList<CallRecord> callingInCityRecords = new ArrayList<>(); private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<>(); private ArrayList<CallRecord> callingInLandRecords = new ArrayList<>(); private ArrayList<CallRecord> answerInCityRecords = new ArrayList<>(); private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<>(); private ArrayList<CallRecord> answerInLandRecords = new ArrayList<>(); private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<>(); private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>(); public void addCallingInCityRecords(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode){ CallRecord callRecord=new CallRecord(startTime,endTime, callingAddressAreaCode, answerAddressAreaCode); callRecord.setStartTime(startTime); callRecord.setEndTime(endTime); callRecord.setCallingAddressAreaCode(callingAddressAreaCode); callRecord.setAnswerAddressAreaCode(answerAddressAreaCode); callingInCityRecords.add(callRecord); } public void addCallingInProvinceRecords(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode){ CallRecord callRecord=new CallRecord(startTime,endTime, callingAddressAreaCode, answerAddressAreaCode); callRecord.setStartTime(startTime); callRecord.setEndTime(endTime); callRecord.setCallingAddressAreaCode(callingAddressAreaCode); callRecord.setAnswerAddressAreaCode(answerAddressAreaCode); callingInProvinceRecords.add(callRecord); } public void addCallingInLandRecords(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode){ CallRecord callRecord=new CallRecord(startTime,endTime, callingAddressAreaCode, answerAddressAreaCode); callRecord.setStartTime(startTime); callRecord.setEndTime(endTime); callRecord.setCallingAddressAreaCode(callingAddressAreaCode); callRecord.setAnswerAddressAreaCode(answerAddressAreaCode); callingInLandRecords.add(callRecord); } public void addAnswerInCityRecords(CallRecord answerRecord){ } public void addAnswerInProvinceRecords(CallRecord answerRecord){ } public void addAnswerInLandRecords(CallRecord answerRecord){ } public void addSendMessageRecords(MessageRecord sendMessageRecord){ } public void addReceiveMessageRecords(MessageRecord receiveMessageRecord){ } 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<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } }
7-1 电信计费系列2-手机+座机计费
实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
1、针对市内座机用户采用的计费方式(与电信计费系列1内容相同):
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
假设本市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
2、针对手机用户采用实时计费方式:
月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,
市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟;
注:被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市
手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,
同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
输入:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,含手机和座机用户
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题在电信计费系列1基础上增加类型1-手机实时计费。
手机设置0或者座机设置成1,此种错误可不做判断。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
输入格式增加手机接打电话以及收发短信的格式,手机接打电话的信息除了号码之外需要
额外记录拨打/接听的地点的区号,比如:
座机打手机:
t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:
t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
源码:
import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Scanner; abstract class CallChargeRule extends ChargeRule{ public double calCost(ArrayList<CallRecord> callRecords){ return 1; } } class CallRecord extends CommunicationRecord{ private Date startTime; private Date endTime; private String callingAddressAreaCode; private String answerAddressAreaCode; public 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 void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } abstract class ChargeMode { ArrayList<ChargeRule> 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(); } abstract class ChargeRule { public double calCost(ArrayList<CallRecord> callRecords){ return 1; } } abstract class CommunicationRecord { protected String callingNumber; protected String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNum) { this.callingNumber = callingNum; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } class LandlinePhoneCharging extends ChargeMode{ private double monthlyRent=20; LandPhoneInCityRule lc = new LandPhoneInCityRule(); LandPhoneInlandRule ll = new LandPhoneInlandRule(); LandPhoneInProvinceRule lp = new LandPhoneInProvinceRule(); @Override public double calCost(UserRecords userRecords) { return lc.calCost(userRecords.getCallingInCityRecords())+ll.calCost(userRecords.getCallingInLandRecords())+lp.calCost(userRecords.getCallingInProvinceRecords()); } public double getMonthlyRent() { return monthlyRent; } } class LandPhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.1; } } class LandPhoneInlandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.6; } } class LandPhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.3; } } public class Main { public static void main(String[] args) throws ParseException { int sum=0; SimpleDateFormat sf=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); ArrayList<User> users=new ArrayList<>(); ArrayList<CallRecord> callRecords = new ArrayList<>(); Scanner in = new Scanner(System.in); String str; StringBuilder sb = new StringBuilder(); while (true) { str = in.nextLine(); if (str.equals("end") == true) { break; } sb.append(str + "\n"); } String strNew = sb.toString(); String strs[] = strNew.split("\n"); for(int i = 0;i<strs.length;i++) { String strs2[] = strs[i].split("\\s+"); if(flag1(strs[i])||flag2(strs[i])){ String s; s=strs2[0].substring(2); User user=new User(); user.setNumber(s); users.add(user); }else if(flag3(strs[i])){ Date date1 = sf.parse(strs2[strs2.length-4]+" "+strs2[strs2.length-3]); Date date2 = sf.parse(strs2[strs2.length-2]+" "+strs2[strs2.length-1]); if(strs2[0].charAt(2)=='0'){ CallRecord callRecord; if(strs2[1].charAt(0)=='1'){ callRecord = new CallRecord(date1,date2,strs2[0].substring(2, 6), strs2[2]); } else{ callRecord = new CallRecord(date1,date2, strs2[0].substring(2, 6), strs2[1].substring(0, 4)); } callRecord.setCallingNumber(strs2[0].substring(2)); callRecord.setAnswerNumber(strs2[1]); callRecords.add(callRecord); } else{ CallRecord callRecord; if(strs2[2].charAt(0)=='1'){ callRecord = new CallRecord(date1,date2,strs2[1], strs2[3]); } else{ callRecord = new CallRecord(date1,date2,strs2[1],strs2[2].substring(0, 4)); } callRecord.setCallingNumber(strs2[0].substring(2)); callRecord.setAnswerNumber(strs2[2]); callRecords.add(callRecord); } sum=sum+1; } } for(int m=0;m< users.size();m++) { for (int i = 0; i < users.size(); i++) { for (int j = i + 1; j < users.size(); j++) { if (users.get(i).getNumber().equals(users.get(j).getNumber())) users.remove(i); } } } for(int i = 0;i <sum;i++){ for (User user:users ) { if(user.getNumber().equals(callRecords.get(i).getCallingNumber())){ if(callRecords.get(i).getCallingAddressAreaCode().equals("0791")){ if(callRecords.get(i).getAnswerAddressAreaCode().equals("0791")){ user.getUserRecords().addCallingInCityRecords(callRecords.get(i)); } else if(isInProvince(callRecords.get(i).getAnswerAddressAreaCode())){ user.getUserRecords().addCallingInProvinceRecords(callRecords.get(i)); } else{ user.getUserRecords().addCallingInLandRecords(callRecords.get(i)); } } else if(isInProvince(callRecords.get(i).getCallingAddressAreaCode())){ user.getUserRecords().addCallingInProvinceRecordsRoaming(callRecords.get(i)); } else{ user.getUserRecords().addCallingInLandRecordsRoaming(callRecords.get(i)); } } else if(user.getNumber().equals(callRecords.get(i).getAnswerNumber())){ if(!isInProvince(callRecords.get(i).getAnswerAddressAreaCode())&&!callRecords.get(i).getAnswerAddressAreaCode().equals("0791")){//省外漫游接听 user.getUserRecords().addAnswerInLandRecordsRoaming(callRecords.get(i)); } } } } for(int i = 0;i < users.size();i++){ if(users.get(i).getNumber().charAt(0)=='1'){ users.get(i).setChargeMode(new TelephoneCharging()); users.get(i).calBalance(); } else{ users.get(i).setChargeMode(new LandlinePhoneCharging()); users.get(i).calBalance(); } } ArrayList<String> s = new ArrayList<>(); for(int i = 0;i<users.size();i++){ s.add(users.get(i).getNumber()); } Collections.sort(s); for(int i = 0;i< users.size();i++){ for(int j = 0;j < users.size();j++){ if(s.get(i).equals(users.get(j).getNumber())){ System.out.println(users.get(j).getNumber()+" "+Format(users.get(j).calCost())+" "+Format(users.get(j).getBalance())); } } } } public static boolean flag1(String str) { String regstr = "u-0791\\d{7,8}\\s0";//座机 return str.matches(regstr); } public static boolean flag2(String str) { String regstr = "u-1\\d{10}\\s1";//手机 return str.matches(regstr); } public static boolean flag3(String str) { String regstr = "(([t]-0791[0-9]{7,8}\\s)|(t-1\\d{10}\\s0(\\d{2,3})\\s))" + "((0[0-9]{9,11}\\s)|(1\\d{10}\\s0(\\d{2,3})\\s))" + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?" + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s" + "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.(" + "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"; return str.matches(regstr); } public static String Format(double a) { DecimalFormat formater = new DecimalFormat("0.0"); formater.setRoundingMode(RoundingMode.DOWN); return formater.format(a); } public static boolean isInProvince(String s){ if(s.equals("0790")||s.equals("0792")||s.equals("0793")||s.equals("0794")||s.equals("0795")||s.equals("0796")||s.equals("0797")||s.equals("0798")||s.equals("0799")||s.equals("0701")){ return true; }else return false; } } class MessageRecord extends CommunicationRecord{ private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } class PhoneInCityRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.1; } } class PhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.3; } } class PhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.2; } } class RoamingAnswerRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.3; } } class RoamingPhoneInLandRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.6; } } class RoamingPhoneInProvinceRule extends CallChargeRule{ @Override public double calCost(ArrayList<CallRecord> callRecords) { long second=0; long minute=0; double sum=0; for(int i=0;i<callRecords.size();i++){ callRecords.get(i); second=(callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; minute=second/60; if(second%60!=0){ minute=minute+1; } sum=sum+minute; } return sum*0.3; } } class TelephoneCharging extends ChargeMode{ private double monthlyRent=15; private PhoneInCityRule CR = new PhoneInCityRule(); private PhoneInProvinceRule PR = new PhoneInProvinceRule(); private PhoneInLandRule LR = new PhoneInLandRule(); private RoamingPhoneInProvinceRule RPR = new RoamingPhoneInProvinceRule(); private RoamingPhoneInLandRule RLR = new RoamingPhoneInLandRule(); private RoamingAnswerRule RAR = new RoamingAnswerRule(); @Override public double calCost(UserRecords userRecords) { return CR.calCost(userRecords.getCallingInCityRecords())+ PR.calCost(userRecords.getCallingInProvinceRecords())+ LR.calCost(userRecords.getCallingInLandRecords())+ RPR.calCost(userRecords.getCallingInProvinceRecordsRoaming())+ RLR.calCost(userRecords.getCallingInLandRecordsRoaming())+ RAR.calCost(userRecords.getAnswerInLandRecordsRoaming()); } public double getMonthlyRent() { return monthlyRent; } } class User { private UserRecords userRecords=new UserRecords(); private double balance=100; private ChargeMode chargeMode = new LandlinePhoneCharging(); private String number; public double calBalance(){ balance = balance -calCost()-chargeMode.getMonthlyRent(); return balance; } public double calCost(){ return 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; } } class UserRecords { private ArrayList<CallRecord> callingInCityRecords = new ArrayList<>(); private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<>(); private ArrayList<CallRecord> callingInLandRecords = new ArrayList<>(); private ArrayList<CallRecord> callingInProvinceRecordsRoaming = new ArrayList<>(); private ArrayList<CallRecord> callingInLandRecordsRoaming = new ArrayList<>(); private ArrayList<CallRecord> answerInCityRecords = new ArrayList<>(); private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<>(); private ArrayList<CallRecord> answerInLandRecords = new ArrayList<>(); private ArrayList<CallRecord> answerInLandRecordsRoaming = new ArrayList<>(); private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<>(); private ArrayList<MessageRecord> receiveMessageRecords = 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 addReceiveMessageRecords(MessageRecord receiveMessageRecord){ receiveMessageRecords.add(receiveMessageRecord); } public void addCallingInProvinceRecordsRoaming(CallRecord callRecord){ callingInProvinceRecordsRoaming.add(callRecord); } public void addCallingInLandRecordsRoaming(CallRecord callRecord){ callingInLandRecordsRoaming.add(callRecord); } public void addAnswerInLandRecordsRoaming(CallRecord callRecord){ answerInLandRecordsRoaming.add(callRecord); } 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<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } public ArrayList<CallRecord> getCallingInProvinceRecordsRoaming() { return callingInProvinceRecordsRoaming; } public ArrayList<CallRecord> getCallingInLandRecordsRoaming() { return callingInLandRecordsRoaming; } public ArrayList<CallRecord> getAnswerInLandRecordsRoaming() { return answerInLandRecordsRoaming; } }
7-1 电信计费系列3-短信计费
实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
1、接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。
2、如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。
本题只针对类型3-手机短信计费。
2、逐行输入本月某些用户的短信信息,短信的格式:
m-主叫号码,接收号码,短信内容 (短信内容只能由数字、字母、空格、英文逗号、英文句号组成)
m-18907910010 13305862264 welcome to jiangxi.
m-13305862264 18907910010 thank you.
假设每个用户初始余额是100元。
每条短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、
开户号码非南昌市的号码、自己给自己打电话等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。
本题只考虑短信计费,不考虑通信费用以及月租费。
源码:
import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.ParseException; import java.util.*; import java.util.ArrayList; import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; abstract class ChargeMode { ArrayList<ChargeRule> 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(); } abstract class ChargeRule { public double calCost(ArrayList<MessageRecord> messageRecords){ return 1; } } abstract class CommunicationRecord { protected String callingNumber; protected String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNum) { this.callingNumber = callingNum; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } public class Main { public static void main(String[] args) { ArrayList<String[]> messageRecordOR = new ArrayList<>(); ArrayList<MessageRecord> messageRecords = new ArrayList<>(); ArrayList<User> users = new ArrayList<>(); Scanner in = new Scanner(System.in); String str=in.nextLine(); String strU = "u-1\\d{10}\\s3"; String strM = "m-1\\d{10}\\s1\\d{10}\\s[[A-Z][a-z][0-9]\\s,.]+"; while(!str.equals("end")){ String strs[] = str.split("\\s"); if (str.matches(strU)) { String s; s = strs[0].substring(2); User user = new User(); user.setNumber(s); users.add(user); } if (str.matches(strM)) { String[] s = new String[3]; s[0]=strs[0]; s[1]=strs[1]; s[2]=str.substring(26); for (User user:users){ if(user.getNumber().equals(s[0].substring(2))) { user.getUserRecords().addSendMessageRule(s[2]); } } } str = in.nextLine(); } for (int i = 0; i < users.size(); i++) { for (int j = i + 1; j < users.size(); j++) { if (users.get(i).getNumber().equals(users.get(j).getNumber())) users.remove(i); } } for (int i = 0; i < messageRecordOR.size(); i++) { for (User user:users){ if(user.getNumber().equals(messageRecords.get(i).getCallingNumber())) { user.getUserRecords().addSendMessageRule(messageRecordOR.get(i)[2]); } } } for(User a: users){ a.calBalance(); } for(int i=0;i<users.size()-1;i++){ for(int j=i+1;j<users.size();j++){ if(Double.parseDouble(users.get(i).getNumber())>Double.parseDouble(users.get(j).getNumber())){ User con; con = users.get(i); users.set(i,users.get(j)); users.set(j,con); } } } for(int i=0;i< users.size();i++){ System.out.printf(users.get(i).getNumber()+" "); System.out.printf("%.1f %.1f\n",users.get(i).calCost(),users.get(i).getBalance()); } } } abstract class MessageChargeRule extends ChargeRule{ public double calCost(ArrayList<MessageRecord> messageRecords){ return 1; } } class MessageCharging extends ChargeMode{ private SendMessageRule sendMessageRule=new SendMessageRule(); public double calCost(UserRecords userRecords) { return sendMessageRule.calCost(userRecords.getSendMessageRecords()); } @Override public double getMonthlyRent() { return 0; } } class MessageRecord extends CommunicationRecord{ private String message; public MessageRecord(String message) { this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } class SendMessageRule extends MessageChargeRule{ public double calCost(ArrayList<MessageRecord> messageRecords) { double sum=0; for(int i=0;i<messageRecords.size();i++){ messageRecords.get(i); String s=messageRecords.get(i).getMessage(); int a=s.length(); if(a<=10){ sum=sum+1; }else { sum=sum+a/10; if(a%10!=0){ sum=sum+1; } } } if(sum<=3){ return sum*0.1; }else if(sum<=5){ return 3*0.1+(sum-3)*0.2; }else return 0.7+(sum-5)*0.3; } } class User { private UserRecords userRecords=new UserRecords(); private double balance=100; private ChargeMode chargeMode = new MessageCharging(); private String number; public double calBalance(){ balance = balance -calCost(); return balance; } public double calCost(){ return 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; } } class UserRecords { private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<>(); private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>(); public void addSendMessageRule(String s){ MessageRecord messageRecord=new MessageRecord(s); messageRecord.setMessage(s); sendMessageRecords.add(messageRecord); } public void addReceiveMessageRecords(MessageRecord receiveMessageRecord){ receiveMessageRecords.add(receiveMessageRecord); } public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } }
1、我使用的StringBulider-流动字符串的写法,但是在一系列的编码后,我代码的编写难度被我自己搞高了,我没有把每个信息存储到arrylist里而是一个for循环里的字符串数组的分配,导致我每一步的操作都收到了不少限制。
但是第一次作业时只有对座机的分析,导致我的代码写的十分没有技术性,没有将每个数据细化进行分割存储,这让我第二题设计的十分挣扎。
2、没有将重复的数据进行删除
在没有加上上述代码时,我的结果会出现重复开户的情况。
3、在计算金额时没有一次计算一次而是加起来计算,造成了错误,应当将每一次的时长单独计算,下面为改正后的代码
4、创建了对象没有加入进arrylist中
一开始我没有进行add操作,导致我记录的内容没有被存储,非常的可笑。
5、排序的错误
这是我一开始的排序
这是我改进后的
上面的代码是利用了java内置的collection类的排序字符串的方法,但是我在输出的时候用到了字符串进行四舍五入的方法,虽然在第一次和第二次是对的,但是我在第三次出现了差错。其实这个错误我在第一次就发现了,
当时是99.6输出了为了99.5,但是可能是检查点没有,所以侥幸通过,但是第三次出现了错误,一开始我还没有意识到是这里的问题,将整个代码都基本上改了一遍,我改了有3个多小时还是差4分,当时整个人都要抓狂了,
但是我在最后随手将这个换成了将字符串转化成数字后的排序法,就对了,我真是服了,所以下次遇到问题一定要解决一下,不然会乱了大局啊。
1、我对类图的理解不够深入导致我在进行编码的过程中遇到了层层障碍,所以下次一定要先看懂类图再编码;
2、我的设计能力确实有待提升;
3、虽然老师要求我们写注释,但是我总是以为以后的自己能看懂,导致我间断性写代码时很是难受,还要理解上次的代码再进行编程;
4、一定要先设计再编码,一定要先设计再编码,一定要先设计再编码,重要的事情说三遍!
通过这次迭代作业,我个人感觉我的java编程能力确实有所提升,虽然痛苦,但是写完代码然后通过的快乐也是支撑我写下去的动力。所以还要多加练习,练习出真知啊。
希望我在编码的路上越走越远!