Blog3- 2022-6/7/8
作者:互联网
这是本学期的最后一次博客,针对于pta的第六、七、八次大作业做一个总结和分析,分为前言、设计与分析、踩坑心得、改进建议、总结五个方面。
(1)前言
这几次大作业是围绕着电信计费系统展开的,第一次是只针对于座机用户,对座机进行电信计费,不用考虑短信,也不用考虑拨打电话的所在地,相对比较容易;第二次是加上了手机计费,需要区分座机用户和手机用户,需要考虑拨打电话的所在地,和接听电话的所在地,相对比较复杂,情况也比较多;第三次作业是针对于手机用户的短信计费功能,需要考虑每条短信的长度和短信的总数,不是很难。这三个电信计费作业的思路很接近,也不像前几次的四边形五边形那样有那么多的计算,重要的是分好类逐一进行,在最后还要对输出的手机号码进行排序,按电话号码的大小顺序输出。详细的请看设计与分析。
除了这三个大作业以外,还有几道小作业,分别是写一个动物发声模拟器,写一个商店类和内部购物券,按学号大小输出同学信息,多态的测试以及找到并输出员工信息。这几道题都比较简单,每道题都是考察一两个知识点,写起来也很快,就不过多赘述了。
(2)设计与分析
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
以上四项内容之间以一个英文空格分隔
输出格式:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,
单位元)。假设每个用户初始余额是100元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
我的代码如下:
import java.text.ParseException; import java.util.Scanner; import java.text.SimpleDateFormat; import java.util.Date; public class Main { public static void main(String[] args) throws ParseException { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); String []s = new String[10]; for(int i=0;i<10;i++) { s[i] = input.nextLine(); } for(int i=0;i<9;i++) { if(s[i].charAt(0) == 'u') { String Unumber = s[i].substring(2, 14); for(int j=i+1;j<10;j++) { if(s[j].charAt(0) == 't') { String Tnumber = s[j].substring(2, 14); if(Unumber.equals(Tnumber)) { CallRecord callRecord = new CallRecord(s[j]); callRecord.eachcost(); } } } } } } } class CallRecord { private String startTime; private String endTime; private String callingArea; private String answerArea; private String callingNum; private String AnswerNum; public CallRecord(String s) { this.callingArea = s.substring(2, 6); this.callingNum = s.substring(2, 14); this.answerArea = s.substring(15, 19); this.AnswerNum = s.substring(15, 27); this.startTime = s.substring(28, 44); this.endTime = s.substring(45); } public String getCallingNum() { return callingNum; } public void setCallingNum(String callingNum) { this.callingNum = callingNum; } public String getAnswerNum() { return AnswerNum; } public void setAnswerNum(String answerNum) { AnswerNum = answerNum; } public String getStartTime() { return startTime; } public void setStartTime(String stateTime) { this.startTime = stateTime; } public String getEndTime() { return endTime; } public void setEndTime(String endTime) { this.endTime = endTime; } public String getCallingArea() { return callingArea; } public void setCallingArea(String callingArea) { this.callingArea = callingArea; } public String getAnswerArea() { return answerArea; } public void setAnswerArea(String answerArea) { this.answerArea = answerArea; } //计算通话时长 public double getTime() throws ParseException { SimpleDateFormat s = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");//注意大小写 Date start = s.parse(startTime); Date end = s.parse(endTime); long minute = (end.getTime() - start.getTime())/(1000 * 60); double time = (double) Math.ceil(minute); return time; } public void eachcost() throws ParseException { double allTime = this.getTime(); if(this.answerArea.equals("0791")) { InCity inCity = new InCity(allTime); System.out.println(this.callingNum + " "+ inCity.allcost(getTime()) +" "+ inCity.balance(getTime())); } else if(this.answerArea.equals("0701") || this.answerArea.equals("0790") || this.answerArea.equals("0792") || this.answerArea.equals("0793") || this.answerArea.equals("0794") || this.answerArea.equals("0795") || this.answerArea.equals("0796") || this.answerArea.equals("0797") || this.answerArea.equals("0798") || this.answerArea.equals("0799")) { InProvince inProvince = new InProvince(allTime); System.out.println(this.callingNum + " "+ inProvince.allcost(getTime()) +" "+ inProvince.balance(getTime())); } else { InLand inLand = new InLand(allTime); System.out.println(this.callingNum + " "+ inLand.allcost(getTime()) +" "+ inLand.balance(getTime())); } } } class InCity { private double time; public InCity(double allTime) { this.time = allTime; } public double getTime() { return time; } public void setTime(double time) { this.time = time; } public double allcost(double time) { return 0.1 * time; } public double balance(double time) { return 80-0.1 * time; } } class InLand { private double time; public InLand(double time) { this.time = time; } public double getTime() { return time; } public void setTime(double time) { this.time = time; } public double allcost(double time) { return 0.6 * time; } public double balance(double time) { return 80-0.6 * time; } } class InProvince { private double time; public InProvince(double time) { this.time = time; } public double getTime() { return time; } public void setTime(double time) { this.time = time; } public double allcost(double time) { return 0.3 * time; } public double balance(double time) { return 80-0.3 * time; } }
我的类图如下:
这道题看起来感觉很简单,但是我的思路有一些混乱,我能看明白老师发的参考类图,也明白每个类各自的功能是什么,但是当我写的时候,我不太知道怎样能把他们串起来。
就拿一个用户的例子来说,当这个用户开户以后,需要有一个他的通讯记录本,里面用来存放他所有的通话记录,再对每一条通话记录进行解析,取出所有的信息,再逐一计费,我当时也明白这个思路,但是我写的时候不知道该怎样实现将通话记录归到那个用户的通讯记录本里面,我一直在想那么多的记录怎样去找谁是哪个户主的记录,所以刚开始那几天一直没有什么进展,到后面我按照我的想法去尝试时,却一直存在数组越界这个问题,当时我先按行读取每条记录,再对这行的数据进行拆分,用到charAt这个函数,但是这里却一直报错,现在明白对于按行读取的数组,charAt是不能乱用的,但是当时一直不明白为什么,改来改去也一直报错,导致这道题的得分很低。
不是时间问题,是我一直找不出来问题,一直卡在那里。
我想要使用chaiAt功能根据第一个字符是什么来判断是开户还是记录,再根据记录数据的解析将记录分到市内、省内、国内这三个不同的类里,每个类的计费方式不同,分别算出每条记录的通话费用以后,再根据拨打的电话号码找到它所对应的户主,遍历通话记录累加单条费用进行计算。在时间的计算上,采用Java自带的Data类,很方便和准确,但是要注意不足一分钟时要按一分钟计算。
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。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
输入格式增加手机接打电话以及收发短信的格式,手机接打电话的信息除了号码之外需要额外记录拨打/接听的地点的区号,比如:
座机打手机:
t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:
t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
我的代码如下:
import java.text.ParseException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Scanner; import java.text.SimpleDateFormat; import java.util.Date; public class Main { public static void main(String[] args) throws ParseException { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); User user; CallRecord callRecord; ArrayList<User> userList = new ArrayList(); DecimalFormat df = new DecimalFormat("0.00"); String day1; String day2; String time1; String time2; String callNumber; String answerNumber; String answerArea; String callArea; int choice; String s = ""; while (!s.equals("end")) { s = input.next(); if (s.charAt(0) == 'u' && (s.length() == 13 || s.length() == 14)) { choice = input.nextInt(); user = new User(s, choice); userList.add(user); } else if (s.charAt(0) == 't' && (s.length() == 13 || s.length() == 14)) { callRecord = new CallRecord(); if (s.charAt(2) == '0') { answerNumber = input.next(); if (answerNumber.charAt(0) == '0') { day1 = input.next(); time1 = input.next(); day2 = input.next(); time2 = input.next(); for (User users : userList) { if (users.getNumber().equals(s.substring(2))) { callRecord.setCallNumber(s.substring(2)); callRecord.setCallArea(s.substring(2, 6)); callRecord.setAnswerNumber(answerNumber); callRecord.setAnswerArea(answerNumber.substring(0, 4)); callRecord.setStartTime(day1 +" "+ time1); callRecord.setEndTime(day2 +" "+ time2); users.getUserRecords().addInto(callRecord); } } } else if (answerNumber.charAt(0) == '1') { answerArea = input.next(); day1 = input.next(); time1 = input.next(); day2 = input.next(); time2 = input.next(); for (User users : userList) { if (users.getNumber().equals(s.substring(2))) { callRecord.setCallNumber(s.substring(2)); callRecord.setCallArea(s.substring(2, 6)); callRecord.setAnswerNumber(answerNumber); callRecord.setAnswerArea(answerArea); callRecord.setStartTime(day1 +" " + time1); callRecord.setEndTime(day2 +" " + time2); users.getUserRecords().addInto(callRecord); } } } } else if (s.charAt(2) == '1') { callArea = input.next(); answerNumber = input.next(); answerArea = input.next(); day1 = input.next(); time1 = input.next(); day2 = input.next(); time2 = input.next(); for (User users : userList) { if (users.getNumber().equals(s.substring(2))) { callRecord.setCallNumber(s.substring(2)); callRecord.setCallArea(callArea); callRecord.setAnswerNumber(answerNumber); callRecord.setAnswerArea(answerArea); callRecord.setStartTime(day1 +" "+ time1); callRecord.setEndTime(day2 + " "+time2); users.getUserRecords().addInto(callRecord); } } } } } for(User us : userList) { System.out.println(us.getNumber() + " " + Double.valueOf(df.format(us.Costs())) + " " + Double.valueOf(df.format(us.Balances()))); } } } class User { private double balance; private String number; private double acost = 0; UserRecords userRecords = new UserRecords(); public User(String s, int choice) { if(choice == 0) { this.balance = 80; this.number = s.substring(2); } else if(choice == 1) { this.balance = 85; this.number = s.substring(2); } } public double getBalance() { return balance; } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public double Costs() throws ParseException { userRecords.AllCost(); this.acost = userRecords.cost/2; return this.acost; } public double Balances() throws ParseException { balance = balance - this.acost/2; return balance; } } class UserRecords { private ArrayList<CallRecord> PhocallPhoCity = new ArrayList<CallRecord>(); private ArrayList<CallRecord> PhocallPhoProvince = new ArrayList<CallRecord>(); private ArrayList<CallRecord> PhocallPhoLand = new ArrayList<CallRecord>(); private ArrayList<CallRecord> PhocallMobCity = new ArrayList<CallRecord>(); private ArrayList<CallRecord> PhocallMobProvince = new ArrayList<CallRecord>(); private ArrayList<CallRecord> PhocallMobLand = new ArrayList<CallRecord>(); private ArrayList<CallRecord> MobcallMobCity = new ArrayList<CallRecord>(); private ArrayList<CallRecord> MobcallMobProvince = new ArrayList<CallRecord>(); private ArrayList<CallRecord> MobcallMobLand = new ArrayList<CallRecord>(); private ArrayList<CallRecord> ProvinceMobcallMob = new ArrayList<CallRecord>(); private ArrayList<CallRecord> LandMobcallMob = new ArrayList<CallRecord>(); double cost = 0; public ArrayList<CallRecord> getProvinceMobcallMob() { return ProvinceMobcallMob; } public void setProvinceMobcallMob(ArrayList<CallRecord> provinceMobcallMob) { ProvinceMobcallMob = provinceMobcallMob; } public ArrayList<CallRecord> getLandMobcallMob() { return LandMobcallMob; } public void setLandMobcallMob(ArrayList<CallRecord> landMobcallMob) { LandMobcallMob = landMobcallMob; } public ArrayList<CallRecord> getPhocallPhoCity() { return PhocallPhoCity; } public void setPhocallPhoCity(ArrayList<CallRecord> phocallPhoCity) { PhocallPhoCity = phocallPhoCity; } public ArrayList<CallRecord> getPhocallPhoProvince() { return PhocallPhoProvince; } public void setPhocallPhoProvince(ArrayList<CallRecord> phocallPhoProvince) { PhocallPhoProvince = phocallPhoProvince; } public ArrayList<CallRecord> getPhocallPhoLand() { return PhocallPhoLand; } public void setPhocallPhoLand(ArrayList<CallRecord> phocallPhoLand) { PhocallPhoLand = phocallPhoLand; } public ArrayList<CallRecord> getPhocallMobCity() { return PhocallMobCity; } public void setPhocallMobCity(ArrayList<CallRecord> phocallMobCity) { PhocallMobCity = phocallMobCity; } public ArrayList<CallRecord> getPhocallMobProvince() { return PhocallMobProvince; } public void setPhocallMobProvince(ArrayList<CallRecord> phocallMobProvince) { PhocallMobProvince = phocallMobProvince; } public ArrayList<CallRecord> getPhocallMobLand() { return PhocallMobLand; } public void setPhocallMobLand(ArrayList<CallRecord> phocallMobLand) { PhocallMobLand = phocallMobLand; } public ArrayList<CallRecord> getMobcallMobCity() { return MobcallMobCity; } public void setMobcallMobCity(ArrayList<CallRecord> mobcallMobCity) { MobcallMobCity = mobcallMobCity; } public ArrayList<CallRecord> getMobcallMobProvince() { return MobcallMobProvince; } public void setMobcallMobProvince(ArrayList<CallRecord> mobcallMobProvince) { MobcallMobProvince = mobcallMobProvince; } public ArrayList<CallRecord> getMobcallMobLand() { return MobcallMobLand; } public void setMobcallMobLand(ArrayList<CallRecord> mobcallMobLand) { MobcallMobLand = mobcallMobLand; } public void addInto(CallRecord callRecord) { if (callRecord.getCallNumber().charAt(0) == '0') { if (callRecord.getAnswerNumber().charAt(0) == '0') { if (callRecord.getAnswerArea() == "0791") { PhocallPhoCity.add(callRecord); } else if (callRecord.getAnswerArea().equals("0701") || ((callRecord.getAnswerArea().substring(0, 3).equals("079") && callRecord.getAnswerArea().charAt(3) <= '9' && callRecord.getAnswerArea().charAt(3) >= '0'))) { PhocallPhoProvince.add(callRecord); } else { PhocallPhoLand.add(callRecord); } } else if (callRecord.getAnswerNumber().charAt(0) == '1') { if (callRecord.getAnswerArea() == "0791") { PhocallMobCity.add(callRecord); } else if (callRecord.getAnswerArea().equals("0701") || ((callRecord.getAnswerArea().substring(0, 3).equals("079") && callRecord.getAnswerArea().charAt(3) <= '9' && callRecord.getAnswerArea().charAt(3) >= '0'))) { PhocallMobProvince.add(callRecord); } else { PhocallMobLand.add(callRecord); } } } else if (callRecord.getCallNumber().charAt(0) == '1') { if (callRecord.getCallArea() == "0791") { if (callRecord.getAnswerArea() == "0791") { MobcallMobCity.add(callRecord); } else if (callRecord.getAnswerArea().equals("0701") || ((callRecord.getAnswerArea().substring(0, 3).equals("079") && callRecord.getAnswerArea().charAt(3) <= '9' && callRecord.getAnswerArea().charAt(3) >= '0'))) { MobcallMobProvince.add(callRecord); } else { MobcallMobLand.add(callRecord); } } else if (callRecord.getCallArea().equals("0701") || ((callRecord.getAnswerArea().substring(0, 3).equals("079") && callRecord.getAnswerArea().charAt(3) <= '9' && callRecord.getAnswerArea().charAt(3) >= '0'))) { ProvinceMobcallMob.add(callRecord); } else { LandMobcallMob.add(callRecord); } } } public void AllCost() throws ParseException { for (CallRecord callRecords : PhocallPhoCity) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : PhocallPhoProvince) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : PhocallPhoLand) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : PhocallMobCity) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : PhocallMobProvince) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : PhocallMobLand) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : MobcallMobCity) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : MobcallMobProvince) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : MobcallMobLand) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : ProvinceMobcallMob) { cost = cost + callRecords.calcost(); } for (CallRecord callRecords : LandMobcallMob) { cost = cost + callRecords.calcost(); } } } class CallRecord { private String callNumber; private String answerNumber; private String callArea; private String answerArea; private String startTime; private String endTime; private double cost; public String getCallNumber() { return callNumber; } public void setCallNumber(String callNumber) { this.callNumber = callNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } public String getCallArea() { return callArea; } public void setCallArea(String callArea) { this.callArea = callArea; } public String getAnswerArea() { return answerArea; } public void setAnswerArea(String answerArea) { this.answerArea = answerArea; } public String getStartTime() { return startTime; } public void setStartTime(String startTime) { this.startTime = startTime; } public String getEndTime() { return endTime; } public void setEndTime(String endTime) { this.endTime = endTime; } public double calcost() throws ParseException { SimpleDateFormat s = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");// 注意大小写 Date start = s.parse(startTime); Date end = s.parse(endTime); long minute = end.getTime() - start.getTime(); long Seconds = minute / 1000 % 60; long Hours = minute / (60 * 60 * 1000) % 24; long Minutes = minute / (60 * 1000) % 60; int m; m = (int) (Hours * 60 + Minutes); if (Seconds != 0) { m = m + 1; } if (this.getCallNumber().charAt(0) == '0') { if (this.getAnswerNumber().charAt(0) == '0') { if (this.getAnswerArea() == "0791") { this.cost = m * 0.1; } else if (this.getAnswerArea().equals("0701") || ((this.getAnswerArea().substring(0, 3).equals("079") && this.getAnswerArea().charAt(3) <= '9' && this.getAnswerArea().charAt(3) >= '0'))) { this.cost = m * 0.3; } else { this.cost = m * 0.6; } } else if (this.getAnswerNumber().charAt(0) == '1') { if (this.getAnswerArea() == "0791") { this.cost = m * 0.1; } else if (this.getAnswerArea().equals("0701") || ((this.getAnswerArea().substring(0, 3).equals("079") && this.getAnswerArea().charAt(3) <= '9' && this.getAnswerArea().charAt(3) >= '0'))) { this.cost = m * 0.3; } else { this.cost = m * 0.6; } } } else if (this.getCallNumber().charAt(0) == '1') { if (this.getCallArea() == "0791") { if (this.getAnswerArea() == "0791") { this.cost = m * 0.1; } else if (this.getAnswerArea().equals("0701") || ((this.getAnswerArea().substring(0, 3).equals("079") && this.getAnswerArea().charAt(3) <= '9' && this.getAnswerArea().charAt(3) >= '0'))) { this.cost = m * 0.2; } else { this.cost = m * 0.3; } } else if (this.getAnswerArea().equals("0701") || ((this.getAnswerArea().substring(0, 3).equals("079") && this.getAnswerArea().charAt(3) <= '9' && this.getAnswerArea().charAt(3) >= '0'))) { this.cost = m * 0.3; } else { this.cost = m * 0.6; } } return this.cost; } }
我的类图如下:
这道题是在上一道座机题目的基础上进行修改的,增加了手机的功能,在做座机计费题目时,因为座机是固定位置的,所以座机的所在地一定在南昌市内,只需要考虑接听电话的位置就好,但是对于手机而言,它也可以是在国内或省内或市内,这样的话需要考虑的情况就又多了几种,但是其实和前面判断的方法一样,所以也只是换汤不换药。但是在这里还需要区分开户的是手机和座机,因为他们的月租是不同的,所以在user类里面构造函数时可以根据传入的参数来构造不同金额的月租。
大概思路就和上一题差不多,但是由于上一次写作业时,一直被那里的数组越界卡住,所以我知道如果我还是那样写的话那我这道题肯定也会被卡住,所以我就去询问了班上同学,但是他们也没有看出来为什么会越界,因此我就请教了一下他们做这道题时的思路是怎样的,包括前面令我苦恼的怎样把记录找对人,在听了听同学的讲解后,我的代码和上一题的有了质的变化,但是当我满怀信心的提交以后,竟然过不去测试点,但我感觉大体应该是对的,虽然肯定不能全过,但是最起码也会过去一多半吧,后来发现了一些问题,在写代码时对数据分割解析进行分类,那些代码都很相似,根据区号划分类别时,粗心输错了几个数字,当我再次改正提交代码时,测试点竟然没有变化。
我调试了一些数据但还是没有发现哪里错了,最后发现是我犯了一个最愚蠢最基础的问题,那就是我在比较字符串是否一样时,我竟然一顺手写成了==,我知道应该用equals来写,但我当时竟然有些写成了==,有些写成了equals,所以通话记录进入不同的分类时是乱七八糟的,就造成了有一些数据的结果是正确的,而有一些是错误的,但是这是后话,因为我是在十二点十几分时才找出来这个问题,所以我没有改正过来,我真的要被自己恨死了。
大体思路就是将每一个用户对象都放进一个ArrayList中,每一个用户都有他所对应的不同类型的通话记录,例如拨打市内电话、省内电话、国内电话,或它自身就在省内或国内,每一条通话记录放在相同类别的ArrayList中,这些记录都是属于这个用户的,对每一条通话记录的费用进行计算后,遍历通话记录,累加每一条费用,再在用户类里进行输出,最后再对每一个用户这个元素进行排序,按自己号码的大小顺序进行输出。
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元。
每条短信信息均单独计费后累加,不是将所有信息累计后统一计费。
我的代码如下:
import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Scanner; import java.util.Collections; import java.util.Comparator; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); User user; MessageRecord messageRecord; ArrayList<User> userList = new ArrayList(); DecimalFormat df = new DecimalFormat("0.00"); String s = ""; String sendNumber; String receiveNumber; while (!s.equals("end")) { s = input.next(); if (s.charAt(0) == 'u' && s.length() == 13) { int choice = input.nextInt(); if (choice == 3) { sendNumber = s.substring(2); user = new User(sendNumber); userList.add(user); } } else if (s.charAt(0) == 'm' && s.length() == 13) { String content = ""; sendNumber = s.substring(2); receiveNumber = input.next(); String other = input.nextLine(); String[] a = other.split(" "); for (int i = 0; i < a.length; i++) { content = content + a[i] + " "; } for (User users : userList) { if (users.getNumber().equals(sendNumber)) { messageRecord = new MessageRecord(sendNumber, receiveNumber, content); users.getUserRecords().addto(messageRecord); } } } } Collections.sort(userList, new Comparator<User>() { @Override public int compare(User user1, User user2) { if (Integer.valueOf(user1.getNumber()) > Integer.valueOf(user2.getNumber())) { return 1; } else if (Integer.valueOf(user1.getNumber()) > Integer.valueOf(user2.getNumber())) { return 0; } else { return -1; } } }); for (User us : userList) { System.out.println(us.getNumber() + " " + Double.valueOf(df.format(us.Costs())) + " " + Double.valueOf(df.format(us.Balances()))); } } } class User { private double balance; private String number; private double cost; UserRecords userRecords = new UserRecords(); public User(String number) { this.number = number; this.balance = 100; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public double getCost() { return cost; } public void setCost(double cost) { this.cost = cost; } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public double Costs() { userRecords.AllCost(); this.cost = userRecords.cost; return this.cost; } public double Balances() { balance = balance - this.cost; return balance; } } class UserRecords { private ArrayList<MessageRecord> SendMessage = new ArrayList<MessageRecord>(); int howmany = 0; double cost = 0; public ArrayList<MessageRecord> getSendMessage() { return SendMessage; } public void setSendMessage(ArrayList<MessageRecord> sendMessage) { SendMessage = sendMessage; } public void addto(MessageRecord messageRecord) { SendMessage.add(messageRecord); } public double AllCost() { for(MessageRecord messageRecords : SendMessage) { howmany = howmany + messageRecords.count(); } if(howmany <= 3) { cost = howmany * 0.1; } else if(howmany > 3 && howmany <= 5) { cost = 3 * 0.1 + (howmany - 3) * 0.2; } else if(howmany > 5) { cost = 3 * 0.1 + 2 * 0.2 + (howmany - 5) * 0.3; } return cost; } } class MessageRecord { private String sendNumber; private String receiveNumber; private String content; private int order = 0; public MessageRecord(String a, String b, String c) { this.sendNumber = a; this.receiveNumber = b; this.content = c; } public String getSendNumber() { return sendNumber; } public void setSendNumber(String sendNumber) { this.sendNumber = sendNumber; } public String getReceiveNumber() { return receiveNumber; } public void setReceiveNumber(String receiveNumber) { this.receiveNumber = receiveNumber; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public int count(){ int a = content.length() - 2; if(a>=1 && a<=10) { order = order + 1; } else if(a>=11 && a<=20) { order = order + 2; } else if(a>=21 && a<=30) { order = order + 3; } else if(a>=31 && a<=40) { order = order + 4; } else if(a>=41 && a<=50) { order = order + 5; } else if(a>=51 && a<=60) { order = order + 6; } else if(a>=61 && a<=70) { order = order + 7; } else if(a>=71 && a<=80) { order = order + 8; } else if(a>=81 && a<=90) { order = order + 9; } else if(a>=91 && a<=100) { order = order + 10; } else if(a>=101 && a<=110) { order = order + 11; } else if(a>=111 && a<=120) { order = order + 12; } else if(a>=121 && a<=130) { order = order + 13; } else if(a>=131 && a<=140) { order = order + 14; } else if(a>=141 && a<=150) { order = order + 15; } else if(a>=151 && a<=160) { order = order + 16; } return order; } }
我的类图如下:
做了前两道题之后,就感觉这道题是最简单的,不需要考虑地区和时间长短,只需要考虑短信的计费,首先要注意的是如果一条短信的字符超过了十个,要按两条短信计费,以此类推;第二个要注意的是,短信内容可以有空格,所以当使用next()读取时,要注意空格地方会被分开;最后就是短信计费时,一条短信的费用会根据短信数量的不同而变化,三条和五条是一个分界点。
在读取信息时,先使用nextLine()读取全部的短信内容,然后再根据split(" ")分割,最后通过for循环将他们放进一个数组里,有几个就加几个空格,但是计算字符长度时,要减去最后结尾的那个空格。
在计算短信总数量时,将每一条短信记录都赋一个值,1或2或更多,最后对他们进行遍历,计算短信总数量。
但是最后提交时,还是有一些测试点没过,我也没明白是哪些情况没考虑到。
(3)踩坑心得
1.一定要注意,当按行读取字符串时,charAt、substring不能乱用,搞不好就出现什么数组越界了,很难改正,在能用next读取时就尽量改为next读取,这样使用这些函数时可以极大避免这些错误。
2.一定要记得检查当在比较字符串的内容是否相等时,用equals,有时候没注意,顺手可能会写成==,一定要回头检查,不能再因为这个失那么多分了。
3.做题前不要着急开始写代码,一定要花时间去思考一下类的设计方案,好的设计能够起到事半功倍的效果。在前几次写代码时没有意识到这些,看见一道题浅浅思考一下就开始写,导致越往后越复杂,写到最后已经写不下去了,但是往往这个时候已经没有时间了。
4.一定要看清题,不要忽略任何一个信息!
(4)改进建议
1.第一题的思路不太正确,有点没有体现Java的做题思想,再写的时候可以按照第二题的做题思路去写。
2.对ArrayList中用户进行排序输出的方法不对,没有达到预期效果,可以改进一下思路重新写。
3.代码尽量写的简洁清爽一些,看起来才会舒服,不要乱七八糟一大堆,要注意布局。
多用debug调试,总比肉眼看着快,感觉自己不太常用debug,因此总是需要花费好多时间找问题。
4.“==”是运算符
①如果比较的对象是基本数据类型,则比较的是其存储的值是否相等;
②如果比较的是引用数据类型,则比较的是所指向对象的地址值是否相等(是否是同一个对象)。
equals是Object的方法,用来比较两个对象的内容是否相等。
equals 方法不能用于比较基本数据类型,如果没有对 equals 方法进行重写,则相当于“==”,比较的是引用类型的变
量所指向的对象的地址值。
(5)总结
这次作业总体来说难度不大,但是自己写的过程中还是会遇到这样那样的问题,归根结底还是自己的基础知识掌握的不牢,学的不通透,但是犯错也确实是一种学习进步的方法,通过写代码发现错误改正错误会让自己的印象更加深刻,但是可能找错和改错的过程比较搞人心态,所以如果不想总体验这种心理感受,还是得多加学习多加练习,在一道道题目中熟悉知识点的运用。
接下来还有JavaFX的作业,对我而言也是一个难度挺大的作业,要抓紧深入fx的学习,争取在完成JavaFX的作业时可以顺利一些。
标签:return,String,Blog3,callRecord,public,cost,2022,ArrayList 来源: https://www.cnblogs.com/sweesheep/p/16363466.html