总结
前言
在这几次的大作业中,完成的功能是电信计费,其中的主要知识点是对类图的理解和将类图转换成代码的能力,同时学习了Date类和SimpleDateFormat类的用法,用于规范时间,能够将String类型的字符串转换成特定格式的Date类型,这对时间的计算非常有利。只要解决了时间计算的问题后,计算费用也更简便。
这几次的题量都不多,主要是电信计费的难度,其实其难度并不比先前的多边形计算大,但最让人头大的还是格式错误、非法输入的问题,这让人无从下手,不是算法的错误,而要自己想想有哪些非法的情况,这属实难想,导致每次都没能完美的完成题目。
设计与分析
由于此次的题目中给出了相应的类图,只要照着类图将功能实现就可以了,所以在类图的设计上并没有花很大的精力,这也是这次比多边形计算简单的一个点。
通话计费代码


1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.Scanner; 4 5 public class Main { 6 7 public static void main(String[] args){ 8 Scanner in = new Scanner(System.in); 9 ArrayList<User> user = new ArrayList<User>(); 10 String input = in.nextLine(); 11 while(input.isEmpty()) { 12 input = in.nextLine(); 13 } 14 while(input.matches("u\\-1\\d{10} [1,3]")) { 15 String[] s=input.split(" "); 16 user.add(new User(s[0],s[1])); 17 input = in.nextLine(); 18 while(input.isEmpty()) { 19 input = in.nextLine(); 20 } 21 } 22 while(!input.equals("end")) { 23 if(input.matches("m-1\\d{10} 1\\d{10} ([A-Za-z]||\\,||\\d||\\.|| )+")) { 24 String[] s =input.split(" "); 25 MessageRecord record = new MessageRecord(s[0].substring(2),s[1],input.substring(26, input.length())); 26 int i; 27 for(i=0;i<user.size();i++) { 28 user.get(i).setRecords(record);; 29 } 30 31 } 32 input = in.nextLine(); 33 while(input.isEmpty()) { 34 input = in.nextLine(); 35 } 36 } 37 Collections.sort(user); 38 39 for(int i=0;i<user.size();i++) { 40 System.out.printf("%s %.1f %.1f\n",user.get(i).getN(),user.get(i).calCost(),user.get(i).calBalance()); 41 } 42 } 43 44 } 45 46 class UserRecords { 47 ArrayList<MessageRecord> sendMessageRecords= new ArrayList<MessageRecord>(); 48 ArrayList<MessageRecord> receiveMessageRecords= new ArrayList<MessageRecord>(); 49 50 public void addSendMessageRecords(MessageRecord sendMessageRecord) { 51 sendMessageRecords.add(sendMessageRecord); 52 } 53 54 public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) { 55 receiveMessageRecords.add(receiveMessageRecord); 56 } 57 58 public ArrayList<MessageRecord> getSendMessageRecords(){ 59 return sendMessageRecords; 60 } 61 62 public ArrayList<MessageRecord> getReceiveMessageRecords(){ 63 return receiveMessageRecords; 64 } 65 } 66 67 class MessageRecord { 68 String sendNumber; 69 String receiveNumber; 70 String message; 71 72 public MessageRecord() { 73 74 } 75 76 public MessageRecord(String sendNumber,String receiveNumber,String message) { 77 this.message = message; 78 this.receiveNumber = receiveNumber; 79 this.sendNumber = sendNumber; 80 } 81 82 public String getMessage() { 83 return message; 84 } 85 86 public String getreceiveNumber() { 87 return receiveNumber; 88 } 89 90 public String getsendNumber() { 91 return sendNumber; 92 } 93 } 94 95 class User implements Comparable<Object>{ 96 double balance = 100; 97 String number; 98 String type; 99 UserRecords records = new UserRecords(); 100 101 public User() { 102 103 } 104 105 public User(String s1,String s2) { 106 number = s1.substring(2); 107 type = s2; 108 } 109 110 public void setRecords(MessageRecord messageRecord) { 111 if(getN().equals(messageRecord.getsendNumber())) 112 records.addSendMessageRecords(messageRecord); 113 else if(getN().equals(messageRecord.getreceiveNumber())) 114 records.addReceiveMessageRecords(messageRecord); 115 } 116 117 public UserRecords getRecords() { 118 return records; 119 } 120 121 public void setN(String num) { 122 number = num; 123 } 124 125 public String getN() { 126 return number; 127 } 128 129 130 public double getBalance() { 131 return balance; 132 } 133 134 public double calBalance(){ 135 return getBalance() - calCost(); 136 } 137 138 public double calCost() { 139 ArrayList<MessageRecord> sendMessageRecords = getRecords().getSendMessageRecords(); 140 int i; 141 double count = 0; 142 double cost; 143 MessageRecord messagerecord = new MessageRecord(); 144 String message; 145 for(i=0;i<sendMessageRecords.size();i++) { 146 messagerecord = sendMessageRecords.get(i); 147 message = messagerecord.getMessage(); 148 count += Math.ceil(message.length()*1.0/10); 149 } 150 if(count<=3) 151 cost = 0.1*count; 152 else if(count<=5) 153 cost =0.3 + 0.2*(count-3); 154 else 155 cost =0.3+0.4+ 0.3*(count-5); 156 return cost; 157 } 158 159 @Override 160 public int compareTo(Object o) { 161 User user = (User) o; 162 return this.number.compareTo(user.number); 163 } 164 }


踩坑心得
SimpleDateFormat类能够进行时间格式的判断。
利用Date类和SimpleDateFormat类就可以定义时间并且计算出时间差,解决了时间计算的难题。
用Math.ceil()能够将为满1的数计为1,即若有小数为,则将进1位。
利用正则表达式判断格式正误。
改进建议
完善格式判断方法,将所有非法输入解决。
在加入通话记录时用了很多if来判断是用什么打什么,可以改进为,先生成记录 ,再直接将记录传入User的setRecord方法中,再进行判断是本用户接还是本用户打。
总结
首先要将所给类图的关系理清楚,明确各个类之间的关系,和其职能,这样才能更好的分工。
在判断格式正误时,利用正则表达式能更加有效。
在要涉及时间的计算或表示时,可以利用Date类和SimpleDateFormat类进行定义,能使问题轻松解决。

浙公网安备 33010602011771号