面向对像程序设计第三次博客作业
一、前言
1、oop-2022-4的题目考察了正则表达式、容器和date的运用以及对类的设计,题量适中,总之就是按照给的类图设计类再添加对应的属性和方法即可
2、oop-2022-5的题目是建立在上一次大作业的基础上增加手机计费,第一次做座机计费会感觉麻烦,但在完成上一次大作业后就会感觉比较轻松,思路还是类似的,只是要考虑的东西变多了。
3、oop-2022-6的题目的题目跟前两次的题目有关系但又不是很有关系,因为这次的是只考虑收发短信,不需要考虑打电话之类的计费,比较简单,题量适中。
二、设计与分析
(1)第五次作业的设计分析总结
1、第一题是本次大作业的核心,主要就是要按照类图来设计类并添加方法,然后在main类运用这些构造好的方法完成整个流程即可
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Scanner;
public class LandPhoneToLandPhone {
public static void handle() throws ParseException {
Scanner input = new Scanner(System.in);
ArrayList<User> users = new ArrayList<User>();
ArrayList<CallRecord> callRecords = new ArrayList<CallRecord>();
SimpleDateFormat time = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
Date start,end;
String s = input.nextLine();
while(!s.equals("end")) {
String[] s1 = s.split(" ");
String[] s2 = s1[0].split("-");
if(s2[0].equals("u")) {
LandlinePhoneCharging llPhone = new LandlinePhoneCharging();
int flag = 0;
for(int i=0;i<users.size();i++) {
if(users.get(i).getNumber().equals(s2[1])) {
flag = 1;
}
}
if(flag==0) {
User u = new User(llPhone, s2[1]);
users.add(u);
}
}
else if(s2[0].equals("t")) {
start = time.parse(s1[2]+" "+s1[3]);
end = time.parse(s1[4]+" "+s1[5]);
String callAddress = s2[1].substring(0,4);
String receiveAddress = s1[1].substring(0, 4);
CallRecord callRecord = new CallRecord(start, end, callAddress, receiveAddress, s2[1], s1[1]);
callRecords.add(callRecord);
}
s = input.nextLine();
}
// 对用户用户进行升序排序,根据电话号码大小
Collections.sort(users, new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
double d1 = Double.parseDouble(o1.getNumber());
double d2 = Double.parseDouble(o2.getNumber());
if(d1 > d2) {
return 1;
}
return -1;
}
});
for(int i=0; i<users.size(); i++) {
UserRecords userRecords = new UserRecords();
for(int j=0; j<callRecords.size(); j++) {
if(users.get(i).getNumber().equals(callRecords.get(j).getCallingNumber())) {
if(callRecords.get(j).getAnswerAddressAreaCode().matches("0791")) {
userRecords.addCallingInCityRecords(callRecords.get(j));
}
else if(callRecords.get(j).getAnswerAddressAreaCode().matches("(079\\d)|0701")) {
userRecords.addCallingInProvinceRecords(callRecords.get(j));
}
else {
userRecords.addCallingInLandRecords(callRecords.get(j));
}
}
}
users.get(i).setUserRecords(userRecords);
}
for(User u : users) {
System.out.println(u.getNumber()+" "+String.format("%.1f", u.calCost())+" "+String.format("%.1f", u.getBalance()));
}
}
}
首先就是对字符串进行分割,然后将他们传入对应的位置,还有就是我创建了两个容器分别存储用户类和用户数据类,然后让用户数据容器里的数据传给相应的用户。再之后通过重构collection里的sort方法对用户容器里的用户们进行排序。最后按用户容器里的顺序输出计算好的费用即可。
整体代码:

1 import java.text.ParseException; 2 import java.text.SimpleDateFormat; 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 import java.util.Date; 7 import java.util.Scanner; 8 9 abstract class CallChargeRule extends ChargeRule { 10 11 public abstract double calCost(ArrayList<CallRecord> callRecords); 12 } 13 class CallRecord extends CommunicationRecord { 14 15 private Date startTime; 16 private Date endTime; 17 private String callingAddressAreaCode; 18 private String answerAddressAreaCode; 19 20 public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode, String callingNumber, String answerNumber) { 21 super(); 22 this.startTime = startTime; 23 this.endTime = endTime; 24 this.callingAddressAreaCode = callingAddressAreaCode; 25 this.answerAddressAreaCode = answerAddressAreaCode; 26 this.setCallingNumber(callingNumber); 27 this.setAnswerNumber(answerNumber); 28 } 29 public Date getStartTime() { 30 return startTime; 31 } 32 public void setStartTime(Date startTime) { 33 this.startTime = startTime; 34 } 35 public Date getEndTime() { 36 return endTime; 37 } 38 public void setEndTime(Date endTime) { 39 this.endTime = endTime; 40 } 41 public String getCallingAddressAreaCode() { 42 return callingAddressAreaCode; 43 } 44 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 45 this.callingAddressAreaCode = callingAddressAreaCode; 46 } 47 public String getAnswerAddressAreaCode() { 48 return answerAddressAreaCode; 49 } 50 public void setAnswerAddressAreaCode(String answerAddressAreaCode) { 51 this.answerAddressAreaCode = answerAddressAreaCode; 52 } 53 54 55 56 } 57 abstract class ChargeMode { 58 59 private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>(); 60 61 public abstract double calCost(UserRecords userRecords); 62 public abstract double getMonthlyRent(); 63 64 public ArrayList<ChargeRule> getChargeRules() { 65 return chargeRules; 66 } 67 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 68 this.chargeRules = chargeRules; 69 } 70 } 71 abstract class ChargeRule { 72 73 } 74 abstract class CommunicationRecord { 75 76 private String callingNumber; 77 private String answerNumber; 78 79 public String getCallingNumber() { 80 return callingNumber; 81 } 82 public void setCallingNumber(String callingNumber) { 83 this.callingNumber = callingNumber; 84 } 85 public String getAnswerNumber() { 86 return answerNumber; 87 } 88 public void setAnswerNumber(String answerNumber) { 89 this.answerNumber = answerNumber; 90 } 91 92 93 } 94 class InputData { 95 96 SimpleDateFormat sample = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 97 98 public boolean InputLandPhoneUser(String s) { 99 String s1 = "u-0791\\d{7,8} 0"; 100 String s2 = "t-\\d{11,12} \\d{11,12}( \\d{4}(.\\d\\d?){2} \\d\\d?:\\d\\d:\\d\\d){2}"; 101 102 if(s.matches(s1)) { 103 return true; 104 } 105 else if(s.matches(s2)) 106 return true; 107 else 108 return false; 109 } 110 111 112 } 113 class LandlinePhoneCharging extends ChargeMode { 114 115 private double monthlyRent = 20; 116 117 @Override 118 public double getMonthlyRent() { 119 // TODO 自动生成的方法存根 120 return monthlyRent; 121 } 122 123 @Override 124 public double calCost(UserRecords userRecords) { 125 // TODO 自动生成的方法存根 126 double cityCost,provinceCost,landCost; 127 LandPhoneInCityRule city = new LandPhoneInCityRule(); 128 LandPhoneInProvinceRule province = new LandPhoneInProvinceRule(); 129 LandPhoneInLandRule land = new LandPhoneInLandRule(); 130 131 cityCost = city.calCost(userRecords.getCallingInCityRecords()); 132 provinceCost = province.calCost(userRecords.getCallingInProvinceRecords()); 133 landCost = land.calCost(userRecords.getCallingInLandRecords()); 134 135 return cityCost+provinceCost+landCost; 136 } 137 138 } 139 class LandPhoneInCityRule extends CallChargeRule { 140 141 @Override 142 public double calCost(ArrayList<CallRecord> callRecords) { 143 // TODO 自动生成的方法存根 144 double cost = 0; 145 Date start; 146 Date end; 147 for(int i=0;i<callRecords.size();i++) { 148 start = callRecords.get(i).getStartTime(); 149 end = callRecords.get(i).getEndTime(); 150 long time = end.getTime()-start.getTime(); 151 if(time%60000!=0) 152 cost = cost + time/60000 + 1; 153 else 154 cost = cost + time/60000; 155 } 156 cost = cost*0.1; 157 return cost; 158 } 159 160 } 161 class LandPhoneInLandRule extends CallChargeRule { 162 163 @Override 164 public double calCost(ArrayList<CallRecord> callRecords) { 165 // TODO 自动生成的方法存根 166 double cost = 0; 167 Date start; 168 Date end; 169 for(int i=0;i<callRecords.size();i++) { 170 start = callRecords.get(i).getStartTime(); 171 end = callRecords.get(i).getEndTime(); 172 long time = end.getTime()-start.getTime(); 173 if(time%60000!=0) 174 cost = cost + time/60000 + 1; 175 else 176 cost = cost + time/60000; 177 } 178 cost = cost*0.6; 179 return cost; 180 } 181 182 } 183 class LandPhoneInProvinceRule extends CallChargeRule { 184 185 @Override 186 public double calCost(ArrayList<CallRecord> callRecords) { 187 // TODO 自动生成的方法存根 188 double cost = 0; 189 Date start; 190 Date end; 191 for(int i=0;i<callRecords.size();i++) { 192 start = callRecords.get(i).getStartTime(); 193 end = callRecords.get(i).getEndTime(); 194 long time = end.getTime()-start.getTime(); 195 if(time%60000!=0) 196 cost = cost + time/60000 + 1; 197 else 198 cost = cost + time/60000; 199 } 200 cost = cost*0.3; 201 return cost; 202 } 203 204 } 205 class LandPhoneToLandPhone { 206 207 public static void handle() throws ParseException { 208 Scanner input = new Scanner(System.in); 209 ArrayList<User> users = new ArrayList<User>(); 210 ArrayList<CallRecord> callRecords = new ArrayList<CallRecord>(); 211 SimpleDateFormat time = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 212 Date start,end; 213 String s = input.nextLine(); 214 215 while(!s.equals("end")) { 216 String[] s1 = s.split(" "); 217 String[] s2 = s1[0].split("-"); 218 219 if(s2[0].equals("u")) { 220 LandlinePhoneCharging llPhone = new LandlinePhoneCharging(); 221 int flag = 0; 222 for(int i=0;i<users.size();i++) { 223 if(users.get(i).getNumber().equals(s2[1])) { 224 flag = 1; 225 } 226 } 227 if(flag==0) { 228 User u = new User(llPhone, s2[1]); 229 users.add(u); 230 } 231 } 232 else if(s2[0].equals("t")) { 233 start = time.parse(s1[2]+" "+s1[3]); 234 end = time.parse(s1[4]+" "+s1[5]); 235 String callAddress = s2[1].substring(0,4); 236 String receiveAddress = s1[1].substring(0, 4); 237 238 CallRecord callRecord = new CallRecord(start, end, callAddress, receiveAddress, s2[1], s1[1]); 239 callRecords.add(callRecord); 240 } 241 s = input.nextLine(); 242 } 243 // 对用户用户进行升序排序,根据电话号码大小 244 Collections.sort(users, new Comparator<User>() { 245 @Override 246 public int compare(User o1, User o2) { 247 double d1 = Double.parseDouble(o1.getNumber()); 248 double d2 = Double.parseDouble(o2.getNumber()); 249 if(d1 > d2) { 250 return 1; 251 } 252 return -1; 253 } 254 }); 255 for(int i=0; i<users.size(); i++) { 256 UserRecords userRecords = new UserRecords(); 257 for(int j=0; j<callRecords.size(); j++) { 258 if(users.get(i).getNumber().equals(callRecords.get(j).getCallingNumber())) { 259 if(callRecords.get(j).getAnswerAddressAreaCode().matches("0791")) { 260 userRecords.addCallingInCityRecords(callRecords.get(j)); 261 } 262 else if(callRecords.get(j).getAnswerAddressAreaCode().matches("(079\\d)|0701")) { 263 userRecords.addCallingInProvinceRecords(callRecords.get(j)); 264 } 265 else { 266 userRecords.addCallingInLandRecords(callRecords.get(j)); 267 } 268 } 269 } 270 users.get(i).setUserRecords(userRecords); 271 } 272 for(User u : users) { 273 System.out.println(u.getNumber()+" "+String.format("%.1f", u.calCost())+" "+String.format("%.1f", u.getBalance())); 274 } 275 } 276 277 } 278 public class Main { 279 280 public static void main(String[] args) throws ParseException { 281 // TODO 自动生成的方法存根 282 283 LandPhoneToLandPhone.handle(); 284 } 285 286 } 287 class MessageRecord extends CommunicationRecord { 288 289 private String message; 290 291 public String getMessage() { 292 return message; 293 } 294 295 public void setMessage(String message) { 296 this.message = message; 297 } 298 299 300 301 } 302 class User { 303 304 private UserRecords userRecords;//用户记录 305 private double balance = 100;//用户余额 306 private ChargeMode chargeMode;//计费方式 307 private String number;//号码 308 309 public User(ChargeMode chargeMode, String number) { 310 this.chargeMode = chargeMode; 311 this.number = number; 312 } 313 314 public double calCost() { 315 balance = balance - (chargeMode.calCost(userRecords) + chargeMode.getMonthlyRent()); 316 return chargeMode.calCost(userRecords); 317 } 318 319 public UserRecords getUserRecords() { 320 return userRecords; 321 } 322 public void setUserRecords(UserRecords userRecords) { 323 this.userRecords = userRecords; 324 } 325 public ChargeMode getChargeMode() { 326 return chargeMode; 327 } 328 public void setChargeMode(ChargeMode chargeMode) { 329 this.chargeMode = chargeMode; 330 } 331 public String getNumber() { 332 return number; 333 } 334 public void setNumber(String number) { 335 this.number = number; 336 } 337 public double getBalance() { 338 return balance; 339 } 340 341 public void setBalance(double balance) { 342 this.balance = balance; 343 } 344 345 } 346 class UserRecords { 347 348 // 保存用户记录 349 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();//市内电话 350 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();//省内长途 351 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();//国内长途 352 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();//市内电话 353 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();//省内电话 354 private ArrayList<CallRecord> answerInlandRecords = new ArrayList<CallRecord>();//国内电话 355 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();//发信息 356 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();//收信息 357 358 // 添加市内打电话记录 359 public void addCallingInCityRecords (CallRecord callRecord) { 360 callingInCityRecords.add(callRecord); 361 } 362 // 添加省内打电话记录 363 public void addCallingInProvinceRecords (CallRecord callRecord) { 364 callingInProvinceRecords.add(callRecord); 365 } 366 // 添加国内打电话记录 367 public void addCallingInLandRecords (CallRecord callRecord) { 368 callingInLandRecords.add(callRecord); 369 } 370 // 添加市内接电话记录 371 public void addanswerInCityRecords (CallRecord answerRecord) { 372 answerInCityRecords.add(answerRecord); 373 } 374 // 添加市内接电话记录 375 public void addanswerInProvinceRecords (CallRecord answerRecord) { 376 answerInProvinceRecords.add(answerRecord); 377 } 378 // 添加市内接电话记录 379 public void addanswerInLandRecords (CallRecord answerRecord) { 380 answerInlandRecords.add(answerRecord); 381 } 382 // 添加发消息记录 383 public void addSendMessageRecords (MessageRecord sendMessageRecord) { 384 sendMessageRecords.add(sendMessageRecord); 385 } 386 // 添加收消息记录 387 public void addreceiveMessageRecords (MessageRecord receiveMessageRecord) { 388 receiveMessageRecords.add(receiveMessageRecord); 389 } 390 391 public ArrayList<CallRecord> getCallingInCityRecords() { 392 return callingInCityRecords; 393 } 394 public ArrayList<CallRecord> getCallingInProvinceRecords() { 395 return callingInProvinceRecords; 396 } 397 public ArrayList<CallRecord> getCallingInLandRecords() { 398 return callingInLandRecords; 399 } 400 public ArrayList<CallRecord> getAnswerInCityRecords() { 401 return answerInCityRecords; 402 } 403 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 404 return answerInProvinceRecords; 405 } 406 public ArrayList<CallRecord> getAnswerInlandRecords() { 407 return answerInlandRecords; 408 } 409 public ArrayList<MessageRecord> getSendMessageRecords() { 410 return sendMessageRecords; 411 } 412 public ArrayList<MessageRecord> getReceiveMessageRecords() { 413 return receiveMessageRecords; 414 } 415 416 }
2、第二题没什么难度,算法完全没难度,类的设计按照题目给的要求来即可

1 import java.util.ArrayList; 2 import java.util.Scanner; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 // TODO 自动生成的方法存根 8 9 Scanner input=new Scanner(System.in); 10 ArrayList<Container> container = new ArrayList<Container>(); 11 int num = Integer.parseInt(input.nextLine()); 12 for(int i=0;i<num;i++) { 13 String s = input.nextLine(); 14 if(s.equals("cube")) { 15 double a = Double.parseDouble(input.nextLine()); 16 Cube cube = new Cube(a); 17 container.add(cube); 18 } 19 if(s.equals("cylinder")) { 20 21 String ss = input.nextLine(); 22 String [] sss = ss.split(" "); 23 double r = Double.parseDouble(sss[0]); 24 double h = Double.parseDouble(sss[1]); 25 Cylinder cylinder = new Cylinder(r, h); 26 container.add(cylinder); 27 } 28 } 29 System.out.println(String.format("%.2f", Container.sumofArea(container))); 30 System.out.println(String.format("%.2f", Container.sumofVolume(container))); 31 } 32 33 } 34 interface Container { 35 36 public static final double pi=3.1415926; 37 38 public abstract double area(); 39 public abstract double volume(); 40 public static double sumofArea(ArrayList<Container> c) { 41 double s = 0; 42 for(int i=0;i<c.size();i++) { 43 s += c.get(i).area(); 44 } 45 return s; 46 }; 47 public static double sumofVolume(ArrayList<Container> c) { 48 double s = 0; 49 for(int i=0;i<c.size();i++) { 50 s += c.get(i).volume(); 51 } 52 return s; 53 54 }; 55 } 56 class Cube implements Container { 57 58 private double a; 59 60 public double getA() { 61 return a; 62 } 63 64 public void setA(double a) { 65 this.a = a; 66 } 67 68 @Override 69 public double area() { 70 // TODO 自动生成的方法存根 71 return 6*this.getA()*this.getA(); 72 } 73 74 @Override 75 public double volume() { 76 // TODO 自动生成的方法存根 77 return this.getA()*this.getA()*this.getA(); 78 } 79 80 public Cube(double a) { 81 super(); 82 this.a = a; 83 } 84 85 } 86 class Cylinder implements Container { 87 88 private double r; 89 private double h; 90 91 public double getR() { 92 return r; 93 } 94 95 public void setR(double r) { 96 this.r = r; 97 } 98 99 public double getH() { 100 return h; 101 } 102 103 public void setH(double h) { 104 this.h = h; 105 } 106 107 @Override 108 public double area() { 109 // TODO 自动生成的方法存根 110 return 2*pi*this.getR()*this.getR()+2*pi*this.getR()*this.getH(); 111 } 112 113 @Override 114 public double volume() { 115 // TODO 自动生成的方法存根 116 return pi*this.getR()*this.getR()*this.getH(); 117 } 118 119 public Cylinder(double r, double h) { 120 super(); 121 this.r = r; 122 this.h = h; 123 } 124 125 }
(2)第六次作业的设计分析总结
第一题就是在上一次大作业的基础上,就是增加了手机计费,所以main类还是差不多的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | public static void main(String[] args) throws ParseException { // TODO 自动生成的方法存 Scanner input = new Scanner(System. in ); //座机用户容器 ArrayList<User> LandLinePhoneUsers = new ArrayList<User>(); //手机用户容器 ArrayList<User> MobilePhoneUsers = new ArrayList<User>(); //通话记录容器 ArrayList<CallRecord> callRecords = new ArrayList<CallRecord>(); SimpleDateFormat time = new SimpleDateFormat( "yyyy.MM.dd HH:mm:ss" ); Date start,end; String s = input.nextLine(); while (!s.equals( "end" )) { if (InPutFormat.LandLinePhoneUjudge(s)) { InPutFormat.LindLinePhoneUsers(s, LandLinePhoneUsers); } else if (InPutFormat.MobilePhoneUjudge(s)) { InPutFormat.MobilePhoneUsers(s, MobilePhoneUsers); } if (InPutFormat.Recordjudge(s)) { InPutFormat.addCallRecord(s, callRecords); } s = input.nextLine(); } Collections.sort(LandLinePhoneUsers, new Comparator<User>() { // 对座机容器中的对象根据电话号码大小进行升序排序 @Override public int compare(User o1, User o2) { double d1 = Double.parseDouble(o1.getNumber()); double d2 = Double.parseDouble(o2.getNumber()); if (d1 > d2) { return 1; } return -1; } }); Collections.sort(MobilePhoneUsers, new Comparator<User>() { // 对手机用户容器里的对象根据电话号码大小进行升序排序 @Override public int compare(User o1, User o2) { double d1 = Double.parseDouble(o1.getNumber()); double d2 = Double.parseDouble(o2.getNumber()); if (d1 > d2) { return 1; } return -1; } }); InputData.saveLandUserRecords(LandLinePhoneUsers, callRecords); InputData.saveUsePhonerRecords(MobilePhoneUsers, callRecords); for (User u : LandLinePhoneUsers) { System.out.println(u.getNumber()+ " " +String.format( "%.1f" , u.calCost())+ " " +String.format( "%.1f" , u.getBalance())); } for (User u : MobilePhoneUsers) { System.out.println(u.getNumber()+ " " +String.format( "%.1f" , u.calCost())+ " " +String.format( "%.1f" , u.getBalance())); } } |
然后有所改变的地方就是我把数据分类的步骤做成了inputdata里的方法,还是根据电话号码来分类的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | /* 座机 */ public static void saveLandUserRecords(ArrayList<User> users, ArrayList<CallRecord> callRecords) { for (int i=0; i<users.size(); i++) { UserRecords userRecords = new UserRecords(); //用户记录 for (int j=0; j<callRecords.size(); j++) { // 将用户记录添加到对应的用户记录当中 if (users.get(i).getNumber().equals(callRecords.get(j).getCallingNumber())) { if (callRecords.get(j).getAnswerAddressAreaCode().matches( "0791" )) { // 打市内电话 userRecords.addCallingInCityRecords(callRecords.get(j)); } else if (callRecords.get(j).getAnswerAddressAreaCode().matches( "((079\\d)|0701)" )) { // 打省内电话 userRecords.addCallingInProvinceRecords(callRecords.get(j)); } else { // 打国内电话 userRecords.addCallingInLandRecords(callRecords.get(j)); } } if (users.get(i).getNumber().equals(callRecords.get(j).getAnswerNumber())) { if (callRecords.get(j).getCallingAddressAreaCode().matches( "0791" )) { // 市内接电话 userRecords.addanswerInCityRecords(callRecords.get(j)); } else if (callRecords.get(j).getCallingAddressAreaCode().matches( "((079\\d)|0701)" )) { // 省内接电话 userRecords.addanswerInProvinceRecords(callRecords.get(j)); } else { // 国内接电话漫游 userRecords.addanswerInLandMANYOURecords(callRecords.get(j)); } } } // 将用户记录存入对应用户中 users.get(i).setUserRecords(userRecords); } } /* 手机 */ public static void saveUsePhonerRecords(ArrayList<User> users, ArrayList<CallRecord> callRecords) { for (int i=0; i<users.size(); i++) { UserRecords userRecords = new UserRecords(); //用户记录 for (int j=0; j<callRecords.size(); j++) { if (users.get(i).getNumber().equals(callRecords.get(j).getCallingNumber())) { if (callRecords.get(j).getCallingAddressAreaCode().equals( "0791" )) { if (callRecords.get(j).getAnswerAddressAreaCode().matches( "0791" )) { // 市内打市内电话 userRecords.addCallingInCityRecords(callRecords.get(j)); } else if (callRecords.get(j).getAnswerAddressAreaCode().matches( "((079\\d)|0701)" )) { // 市内打省内电话 userRecords.addCallingInProvinceRecords(callRecords.get(j)); } else { // 市内打国内电话 userRecords.addCallingInLandRecords(callRecords.get(j)); } } else if (callRecords.get(j).getCallingAddressAreaCode().matches( "((079\\d)|0701)" )) { userRecords.addcallingInProvinceMANYOURecords(callRecords.get(j));; } else { userRecords.addcallingInLandMANYOURecords(callRecords.get(j)); } } if (users.get(i).getNumber().equals(callRecords.get(j).getAnswerNumber())) { if (callRecords.get(j).getAnswerAddressAreaCode().matches( "0791" )) { // 市内接电话 userRecords.addanswerInCityRecords(callRecords.get(j)); } else if (callRecords.get(j).getAnswerAddressAreaCode().matches( "((079\\d)|0701)" )) { // 省内接电话 userRecords.addanswerInProvinceRecords(callRecords.get(j)); } else { // 国内接电话漫游 userRecords.addanswerInLandMANYOURecords(callRecords.get(j));; } } } // 将用户记录存入对应用户中 users.get(i).setUserRecords(userRecords); } } |
整体代码:

1 import java.text.ParseException; 2 import java.text.SimpleDateFormat; 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 import java.util.Date; 7 import java.util.HashMap; 8 import java.util.Scanner; 9 10 11 public class Main { 12 13 public static void main(String[] args) throws ParseException { 14 // TODO 自动生成的方法存 15 Scanner input = new Scanner(System.in); 16 //座机用户容器 17 ArrayList<User> LandLinePhoneUsers = new ArrayList<User>(); 18 //手机用户容器 19 ArrayList<User> MobilePhoneUsers = new ArrayList<User>(); 20 //通话记录容器 21 ArrayList<CallRecord> callRecords = new ArrayList<CallRecord>(); 22 23 SimpleDateFormat time = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 24 Date start,end; 25 26 String s = input.nextLine(); 27 while(!s.equals("end")) { 28 if(InPutFormat.LandLinePhoneUjudge(s)) { 29 InPutFormat.LindLinePhoneUsers(s, LandLinePhoneUsers); 30 } 31 else if(InPutFormat.MobilePhoneUjudge(s)) { 32 InPutFormat.MobilePhoneUsers(s, MobilePhoneUsers); 33 } 34 if(InPutFormat.Recordjudge(s)) { 35 InPutFormat.addCallRecord(s, callRecords); 36 } 37 s = input.nextLine(); 38 } 39 Collections.sort(LandLinePhoneUsers, new Comparator<User>() { 40 // 对座机容器中的对象根据电话号码大小进行升序排序 41 @Override 42 public int compare(User o1, User o2) { 43 double d1 = Double.parseDouble(o1.getNumber()); 44 double d2 = Double.parseDouble(o2.getNumber()); 45 if(d1 > d2) { 46 return 1; 47 } 48 return -1; 49 } 50 }); 51 Collections.sort(MobilePhoneUsers, new Comparator<User>() { 52 // 对手机用户容器里的对象根据电话号码大小进行升序排序 53 @Override 54 public int compare(User o1, User o2) { 55 double d1 = Double.parseDouble(o1.getNumber()); 56 double d2 = Double.parseDouble(o2.getNumber()); 57 if(d1 > d2) { 58 return 1; 59 } 60 return -1; 61 } 62 }); 63 64 InputData.saveLandUserRecords(LandLinePhoneUsers, callRecords); 65 InputData.saveUsePhonerRecords(MobilePhoneUsers, callRecords); 66 67 for(User u : LandLinePhoneUsers) { 68 System.out.println(u.getNumber()+" "+String.format("%.1f", u.calCost())+" "+String.format("%.1f", u.getBalance())); 69 } 70 for(User u : MobilePhoneUsers) { 71 System.out.println(u.getNumber()+" "+String.format("%.1f", u.calCost())+" "+String.format("%.1f", u.getBalance())); 72 } 73 } 74 75 } 76 abstract class CallChargeRule extends ChargeRule { 77 78 public abstract double calCost(ArrayList<CallRecord> callRecords); 79 } 80 class CallRecord extends CommunicationRecord { 81 82 private Date startTime; 83 private Date endTime; 84 private String callingAddressAreaCode; 85 private String answerAddressAreaCode; 86 87 public CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode, String callingNumber, String answerNumber) { 88 super(); 89 this.startTime = startTime; 90 this.endTime = endTime; 91 this.callingAddressAreaCode = callingAddressAreaCode; 92 this.answerAddressAreaCode = answerAddressAreaCode; 93 this.setCallingNumber(callingNumber); 94 this.setAnswerNumber(answerNumber); 95 } 96 public Date getStartTime() { 97 return startTime; 98 } 99 public void setStartTime(Date startTime) { 100 this.startTime = startTime; 101 } 102 public Date getEndTime() { 103 return endTime; 104 } 105 public void setEndTime(Date endTime) { 106 this.endTime = endTime; 107 } 108 public String getCallingAddressAreaCode() { 109 return callingAddressAreaCode; 110 } 111 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 112 this.callingAddressAreaCode = callingAddressAreaCode; 113 } 114 public String getAnswerAddressAreaCode() { 115 return answerAddressAreaCode; 116 } 117 public void setAnswerAddressAreaCode(String answerAddressAreaCode) { 118 this.answerAddressAreaCode = answerAddressAreaCode; 119 } 120 121 122 123 } 124 abstract class ChargeMode { 125 126 private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>(); 127 128 public abstract double calCost(UserRecords userRecords); 129 public abstract double getMonthlyRent(); 130 131 public ArrayList<ChargeRule> getChargeRules() { 132 return chargeRules; 133 } 134 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 135 this.chargeRules = chargeRules; 136 } 137 } 138 abstract class ChargeRule { 139 140 } 141 abstract class CommunicationRecord { 142 143 private String callingNumber; 144 private String answerNumber; 145 146 public String getCallingNumber() { 147 return callingNumber; 148 } 149 public void setCallingNumber(String callingNumber) { 150 this.callingNumber = callingNumber; 151 } 152 public String getAnswerNumber() { 153 return answerNumber; 154 } 155 public void setAnswerNumber(String answerNumber) { 156 this.answerNumber = answerNumber; 157 } 158 159 160 } 161 class InputData { 162 163 /* 座机 */ 164 public static void saveLandUserRecords(ArrayList<User> users, ArrayList<CallRecord> callRecords) { 165 for(int i=0; i<users.size(); i++) { 166 UserRecords userRecords = new UserRecords();//用户记录 167 for(int j=0; j<callRecords.size(); j++) { 168 // 将用户记录添加到对应的用户记录当中 169 if(users.get(i).getNumber().equals(callRecords.get(j).getCallingNumber())) { 170 if(callRecords.get(j).getAnswerAddressAreaCode().matches("0791")) { 171 // 打市内电话 172 userRecords.addCallingInCityRecords(callRecords.get(j)); 173 } 174 else if(callRecords.get(j).getAnswerAddressAreaCode().matches("((079\\d)|0701)")) { 175 // 打省内电话 176 userRecords.addCallingInProvinceRecords(callRecords.get(j)); 177 } 178 else { 179 // 打国内电话 180 userRecords.addCallingInLandRecords(callRecords.get(j)); 181 } 182 } 183 if(users.get(i).getNumber().equals(callRecords.get(j).getAnswerNumber())) { 184 if(callRecords.get(j).getCallingAddressAreaCode().matches("0791")) { 185 // 市内接电话 186 userRecords.addanswerInCityRecords(callRecords.get(j)); 187 } 188 else if(callRecords.get(j).getCallingAddressAreaCode().matches("((079\\d)|0701)")) { 189 // 省内接电话 190 userRecords.addanswerInProvinceRecords(callRecords.get(j)); 191 } 192 else { 193 // 国内接电话漫游 194 userRecords.addanswerInLandMANYOURecords(callRecords.get(j)); 195 } 196 } 197 } 198 // 将用户记录存入对应用户中 199 users.get(i).setUserRecords(userRecords); 200 } 201 } 202 203 /* 手机 */ 204 public static void saveUsePhonerRecords(ArrayList<User> users, ArrayList<CallRecord> callRecords) { 205 for(int i=0; i<users.size(); i++) { 206 UserRecords userRecords = new UserRecords();//用户记录 207 for(int j=0; j<callRecords.size(); j++) { 208 if(users.get(i).getNumber().equals(callRecords.get(j).getCallingNumber())) { 209 if(callRecords.get(j).getCallingAddressAreaCode().equals("0791")) { 210 if(callRecords.get(j).getAnswerAddressAreaCode().matches("0791")) { 211 // 市内打市内电话 212 userRecords.addCallingInCityRecords(callRecords.get(j)); 213 } 214 else if(callRecords.get(j).getAnswerAddressAreaCode().matches("((079\\d)|0701)")) { 215 // 市内打省内电话 216 userRecords.addCallingInProvinceRecords(callRecords.get(j)); 217 } 218 else { 219 // 市内打国内电话 220 userRecords.addCallingInLandRecords(callRecords.get(j)); 221 } 222 } 223 else if(callRecords.get(j).getCallingAddressAreaCode().matches("((079\\d)|0701)")) { 224 userRecords.addcallingInProvinceMANYOURecords(callRecords.get(j));; 225 } 226 else { 227 userRecords.addcallingInLandMANYOURecords(callRecords.get(j)); 228 } 229 } 230 if(users.get(i).getNumber().equals(callRecords.get(j).getAnswerNumber())) { 231 if(callRecords.get(j).getAnswerAddressAreaCode().matches("0791")) { 232 // 市内接电话 233 userRecords.addanswerInCityRecords(callRecords.get(j)); 234 } 235 else if(callRecords.get(j).getAnswerAddressAreaCode().matches("((079\\d)|0701)")) { 236 // 省内接电话 237 userRecords.addanswerInProvinceRecords(callRecords.get(j)); 238 } 239 else { 240 // 国内接电话漫游 241 userRecords.addanswerInLandMANYOURecords(callRecords.get(j));; 242 } 243 } 244 } 245 // 将用户记录存入对应用户中 246 users.get(i).setUserRecords(userRecords); 247 } 248 } 249 250 251 252 } 253 class InPutFormat { 254 255 256 public static void LindLinePhoneUsers(String s,ArrayList<User> users) { 257 LandlinePhoneCharging llPhone = new LandlinePhoneCharging(); 258 String[] ss = s.split(" "); 259 String[] sss = ss[0].split("-"); 260 int flag = 0; 261 for(int i=0;i<users.size();i++) { 262 if(users.get(i).getNumber().equals(sss[1])) { 263 flag = 1; 264 } 265 } 266 if(flag==0) { 267 User u = new User(llPhone, sss[1]); 268 users.add(u); 269 } 270 } 271 272 public static void MobilePhoneUsers(String s,ArrayList<User> users) { 273 MobilePhoneCharging mPhone = new MobilePhoneCharging(); 274 LandlinePhoneCharging llPhone = new LandlinePhoneCharging(); 275 String[] ss = s.split(" "); 276 String[] sss = ss[0].split("-"); 277 int flag = 0; 278 for(int i=0;i<users.size();i++) { 279 if(users.get(i).getNumber().equals(sss[1])) { 280 flag = 1; 281 } 282 } 283 if(flag==0) { 284 User u = new User(mPhone, sss[1]); 285 users.add(u); 286 } 287 } 288 289 290 291 public static void addCallRecord(String s,ArrayList<CallRecord> callrecords) throws ParseException { 292 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 293 CallRecord callRecord = null; 294 Date start; 295 Date end; 296 if(InPutFormat.Recordjudge(s)) { 297 String[] ss = s.split(" "); 298 String[] sss = ss[0].split("-"); 299 if(InPutFormat.LtoMjudge(s)) { 300 start = dateFormat.parse(ss[3]+" "+ss[4]); 301 end = dateFormat.parse(ss[5]+" "+ss[6]); 302 String callAddress = sss[1].substring(0, 4); 303 String answerAddress = ss[2]; 304 String callNumber = sss[1]; 305 String answerNumber = ss[1]; 306 callRecord = new CallRecord(start, end, callAddress, answerAddress, callNumber, answerNumber); 307 } 308 if(InPutFormat.LtoLjudge(s)) { 309 start = dateFormat.parse(ss[2]+" "+ss[3]); 310 end = dateFormat.parse(ss[4]+" "+ss[5]); 311 String callAddress = sss[1].substring(0, 4); 312 String answerAddress = ss[1].substring(0, 4); 313 String callNumber = sss[1]; 314 String answerNumber = ss[1]; 315 callRecord = new CallRecord(start, end, callAddress, answerAddress, callNumber, answerNumber); 316 } 317 if(InPutFormat.MtoLjudge(s)) { 318 start = dateFormat.parse(ss[3]+" "+ss[4]); 319 end = dateFormat.parse(ss[5]+" "+ss[6]); 320 String callAddress = ss[1]; 321 String answerAddress = ss[2].substring(0, 4); 322 String callNumber = sss[1]; 323 String answerNumber = ss[2]; 324 callRecord = new CallRecord(start, end, callAddress, answerAddress, callNumber, answerNumber); 325 } 326 if(InPutFormat.MtoMjudge(s)) { 327 start = dateFormat.parse(ss[4]+" "+ss[5]); 328 end = dateFormat.parse(ss[6]+" "+ss[7]); 329 String callAddress = ss[1]; 330 String answerAddress = ss[3]; 331 String callNumber = sss[1]; 332 String answerNumber = ss[2]; 333 callRecord = new CallRecord(start, end, callAddress, answerAddress, callNumber, answerNumber); 334 335 } 336 } 337 callrecords.add(callRecord); 338 } 339 340 341 342 public static boolean LandLinePhoneUjudge(String s) { 343 // 判断座机开户输入是否符合要求 344 if(s.matches("u-\\d{10,13} 0")) { 345 return true; 346 } 347 else 348 return false; 349 } 350 351 public static boolean LtoLjudge(String s) { 352 // 座机打座机 353 // 判断通话记录输入是否符合要求 354 if(s.matches("t-\\d{10,13} \\d{10,13} \\d{4}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d \\d{4}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d")) { 355 return true; 356 } 357 else 358 return false; 359 } 360 public static boolean MobilePhoneUjudge(String s) { 361 // 电话开户是否符合输入要求 362 if(s.matches("u-1\\d{10} [1-2]")) { 363 return true; 364 } 365 else 366 return false; 367 } 368 369 public static boolean LtoMjudge(String s) { 370 // 座机打手机 371 // 判断通话记录输入是否符合要求 372 if(s.matches("t-\\d{10,13} 1\\d{10} \\d{3,5} \\d{4}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d \\d{4}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d")) { 373 return true; 374 } 375 else 376 return false; 377 } 378 379 public static boolean MtoMjudge(String s) { 380 // 手机打手机 381 // 判断通话记录输入是否符合要求 382 if(s.matches("t-1\\d{10} \\d{3,5} 1\\d{10} \\d{3,5} \\d{4}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d \\d{4}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d")) { 383 return true; 384 } 385 else 386 return false; 387 } 388 public static boolean MtoLjudge(String s) { 389 // 手机打座机 390 // 判断通话记录输入是否符合要求 391 if(s.matches("t-1\\d{10} \\d{3,5} \\d{10,13} \\d{4}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d \\d{4}\\.([1-9]|1[0-2])\\.([1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[0-1]\\d):[0-5]\\d:[0-5]\\d")) { 392 return true; 393 } 394 else 395 return false; 396 } 397 398 public static boolean Recordjudge(String s) { 399 if( LtoLjudge(s) || LtoMjudge(s) || MtoLjudge(s) || MtoMjudge(s)) 400 return true; 401 else 402 return false; 403 } 404 405 } 406 class LandlinePhoneCharging extends ChargeMode { 407 408 private double monthlyRent = 20; 409 410 @Override 411 public double getMonthlyRent() { 412 // TODO 自动生成的方法存根 413 return monthlyRent; 414 } 415 416 @Override 417 public double calCost(UserRecords userRecords) { 418 // TODO 自动生成的方法存根 419 double cityCost,provinceCost,landCost; 420 LandPhoneInCityRule city = new LandPhoneInCityRule(); 421 LandPhoneInProvinceRule province = new LandPhoneInProvinceRule(); 422 LandPhoneInLandRule land = new LandPhoneInLandRule(); 423 424 cityCost = city.calCost(userRecords.getCallingInCityRecords()); 425 provinceCost = province.calCost(userRecords.getCallingInProvinceRecords()); 426 landCost = land.calCost(userRecords.getCallingInLandRecords()); 427 428 return cityCost+provinceCost+landCost; 429 } 430 431 } 432 class LandPhoneInCityRule extends CallChargeRule { 433 434 @Override 435 public double calCost(ArrayList<CallRecord> callRecords) { 436 // TODO 自动生成的方法存根 437 double cost = 0; 438 Date start; 439 Date end; 440 for(int i=0;i<callRecords.size();i++) { 441 start = callRecords.get(i).getStartTime(); 442 end = callRecords.get(i).getEndTime(); 443 long time = end.getTime()-start.getTime(); 444 if(time%60000!=0) 445 cost = cost + time/60000 + 1; 446 else 447 cost = cost + time/60000; 448 } 449 cost = cost*0.1; 450 return cost; 451 } 452 453 } 454 class LandPhoneInLandRule extends CallChargeRule { 455 456 @Override 457 public double calCost(ArrayList<CallRecord> callRecords) { 458 // TODO 自动生成的方法存根 459 double cost = 0; 460 Date start; 461 Date end; 462 for(int i=0;i<callRecords.size();i++) { 463 start = callRecords.get(i).getStartTime(); 464 end = callRecords.get(i).getEndTime(); 465 long time = end.getTime()-start.getTime(); 466 if(time%60000!=0) 467 cost = cost + time/60000 + 1; 468 else 469 cost = cost + time/60000; 470 } 471 cost = cost*0.6; 472 return cost; 473 } 474 475 } 476 class LandPhoneInProvinceRule extends CallChargeRule { 477 478 @Override 479 public double calCost(ArrayList<CallRecord> callRecords) { 480 // TODO 自动生成的方法存根 481 double cost = 0; 482 Date start; 483 Date end; 484 for(int i=0;i<callRecords.size();i++) { 485 start = callRecords.get(i).getStartTime(); 486 end = callRecords.get(i).getEndTime(); 487 long time = end.getTime()-start.getTime(); 488 if(time%60000!=0) 489 cost = cost + time/60000 + 1; 490 else 491 cost = cost + time/60000; 492 } 493 cost = cost*0.3; 494 return cost; 495 } 496 497 } 498 class MessageRecord extends CommunicationRecord { 499 500 private String message; 501 502 public String getMessage() { 503 return message; 504 } 505 506 public void setMessage(String message) { 507 this.message = message; 508 } 509 510 511 512 } 513 class MobilePhoneCharging extends ChargeMode { 514 515 private double monthlyRent = 15; 516 @Override 517 public double calCost(UserRecords userRecords) { 518 // TODO 自动生成的方法存 519 double cost = 0; 520 MobilePhoneInCityToCityRule a = new MobilePhoneInCityToCityRule(); 521 MobilePhoneInCityToProvinceRule b = new MobilePhoneInCityToProvinceRule(); 522 MobilePhoneInCityToLandRule c = new MobilePhoneInCityToLandRule(); 523 MobilePhoneInLandAnswerRule d = new MobilePhoneInLandAnswerRule(); 524 MobilePhoneInProvinceCallRule e = new MobilePhoneInProvinceCallRule(); 525 MobilePhoneInLandCallRule f = new MobilePhoneInLandCallRule(); 526 527 528 cost = a.calCost(userRecords.getCallingInCityRecords()) + b.calCost(userRecords.getCallingInProvinceRecords()) + c.calCost(userRecords.getCallingInLandRecords()) + d.calCost(userRecords.getAnswerInlandRecords()) + e.calCost(userRecords.getCallingInProvinceMANYOURecords()) + f.calCost(userRecords.getCallingInLandMANYOURecords()); 529 return cost; 530 } 531 532 @Override 533 public double getMonthlyRent() { 534 // TODO 自动生成的方法存根 535 return monthlyRent; 536 } 537 538 } 539 class MobilePhoneInCityToCityRule extends CallChargeRule { 540 541 @Override 542 public double calCost(ArrayList<CallRecord> callRecords) { 543 // TODO 自动生成的方法存根 544 double cost = 0; 545 Date start; 546 Date end; 547 for(int i=0;i<callRecords.size();i++) { 548 start = callRecords.get(i).getStartTime(); 549 end = callRecords.get(i).getEndTime(); 550 long time = end.getTime()-start.getTime(); 551 if(time%60000!=0) 552 cost = cost + time/60000 + 1; 553 else 554 cost = cost + time/60000; 555 } 556 cost = cost*0.1; 557 return cost; 558 } 559 560 } 561 class MobilePhoneInCityToLandRule extends CallChargeRule { 562 563 @Override 564 public double calCost(ArrayList<CallRecord> callRecords) { 565 // TODO 自动生成的方法存根 566 double cost = 0; 567 Date start; 568 Date end; 569 for(int i=0;i<callRecords.size();i++) { 570 start = callRecords.get(i).getStartTime(); 571 end = callRecords.get(i).getEndTime(); 572 long time = end.getTime()-start.getTime(); 573 if(time%60000!=0) 574 cost = cost + time/60000 + 1; 575 else 576 cost = cost + time/60000; 577 } 578 cost = cost*0.3; 579 return cost; 580 } 581 582 } 583 class MobilePhoneInCityToProvinceRule extends CallChargeRule { 584 585 @Override 586 public double calCost(ArrayList<CallRecord> callRecords) { 587 // TODO 自动生成的方法存根 588 double cost = 0; 589 Date start; 590 Date end; 591 for(int i=0;i<callRecords.size();i++) { 592 start = callRecords.get(i).getStartTime(); 593 end = callRecords.get(i).getEndTime(); 594 long time = end.getTime()-start.getTime(); 595 if(time%60000!=0) 596 cost = cost + time/60000 + 1; 597 else 598 cost = cost + time/60000; 599 } 600 cost = cost*0.2; 601 return cost; 602 } 603 604 } 605 class MobilePhoneInLandAnswerRule extends CallChargeRule { 606 607 @Override 608 public double calCost(ArrayList<CallRecord> callRecords) { 609 // TODO 自动生成的方法存根 610 double cost = 0; 611 Date start; 612 Date end; 613 for(int i=0;i<callRecords.size();i++) { 614 start = callRecords.get(i).getStartTime(); 615 end = callRecords.get(i).getEndTime(); 616 long time = end.getTime()-start.getTime(); 617 if(time%60000!=0) 618 cost = cost + time/60000 + 1; 619 else 620 cost = cost + time/60000; 621 } 622 cost = cost*0.3; 623 return cost; 624 } 625 626 } 627 class MobilePhoneInLandCallRule extends CallChargeRule { 628 629 @Override 630 public double calCost(ArrayList<CallRecord> callRecords) { 631 // TODO 自动生成的方法存根 632 double cost = 0; 633 Date start; 634 Date end; 635 for(int i=0;i<callRecords.size();i++) { 636 start = callRecords.get(i).getStartTime(); 637 end = callRecords.get(i).getEndTime(); 638 long time = end.getTime()-start.getTime(); 639 if(time%60000!=0) 640 cost = cost + time/60000 + 1; 641 else 642 cost = cost + time/60000; 643 } 644 cost = cost*0.6; 645 return cost; 646 } 647 648 } 649 class MobilePhoneInProvinceCallRule extends CallChargeRule { 650 651 @Override 652 public double calCost(ArrayList<CallRecord> callRecords) { 653 // TODO 自动生成的方法存根 654 double cost = 0; 655 Date start; 656 Date end; 657 for(int i=0;i<callRecords.size();i++) { 658 start = callRecords.get(i).getStartTime(); 659 end = callRecords.get(i).getEndTime(); 660 long time = end.getTime()-start.getTime(); 661 if(time%60000!=0) 662 cost = cost + time/60000 + 1; 663 else 664 cost = cost + time/60000; 665 } 666 cost = cost*0.3; 667 return cost; 668 } 669 670 } 671 class User { 672 673 private UserRecords userRecords;//用户记录 674 private double balance = 100;//用户余额 675 private ChargeMode chargeMode;//计费方式 676 private String number;//号码 677 678 public User(ChargeMode chargeMode, String number) { 679 this.chargeMode = chargeMode; 680 this.number = number; 681 } 682 683 public double calCost() { 684 balance = balance - (chargeMode.calCost(userRecords) + chargeMode.getMonthlyRent()); 685 return chargeMode.calCost(userRecords); 686 } 687 688 public UserRecords getUserRecords() { 689 return userRecords; 690 } 691 public void setUserRecords(UserRecords userRecords) { 692 this.userRecords = userRecords; 693 } 694 public ChargeMode getChargeMode() { 695 return chargeMode; 696 } 697 public void setChargeMode(ChargeMode chargeMode) { 698 this.chargeMode = chargeMode; 699 } 700 public String getNumber() { 701 return number; 702 } 703 public void setNumber(String number) { 704 this.number = number; 705 } 706 public double getBalance() { 707 return balance; 708 } 709 710 public void setBalance(double balance) { 711 this.balance = balance; 712 } 713 714 } 715 class UserRecords { 716 717 // 保存用户记录 718 private ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();//市内打市内 719 private ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<CallRecord>();//市内打省内 720 private ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();//市内打国内 721 private ArrayList<CallRecord> callingInProvinceMANYOURecords = new ArrayList<CallRecord>();//市外但省内漫游打电话 722 private ArrayList<CallRecord> callingInLandMANYOURecords = new ArrayList<CallRecord>();//省外但国内漫游打电话 723 private ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();//人在市内接电话 724 private ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<CallRecord>();//人在省内接电话 725 private ArrayList<CallRecord> answerInlandRecords = new ArrayList<CallRecord>();//人在国内接电话(属于漫游,要收费) 726 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();//发信息 727 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();//收信息 728 729 // 添加人在市内打市内电话记录 730 public void addCallingInCityRecords (CallRecord callRecord) { 731 callingInCityRecords.add(callRecord); 732 } 733 // 添加人在市内打省内打电话记录 734 public void addCallingInProvinceRecords (CallRecord callRecord) { 735 callingInProvinceRecords.add(callRecord); 736 } 737 // 添加人在市内打国内打电话记录 738 public void addCallingInLandRecords (CallRecord callRecord) { 739 callingInLandRecords.add(callRecord); 740 } 741 // 添加人在市内接电话记录 742 public void addanswerInCityRecords (CallRecord answerRecord) { 743 answerInCityRecords.add(answerRecord); 744 } 745 // 添加人在省内接电话记录 746 public void addanswerInProvinceRecords (CallRecord answerRecord) { 747 answerInProvinceRecords.add(answerRecord); 748 } 749 // 添加人在国内接电话记录(属于漫游,要收费) 750 public void addanswerInLandMANYOURecords (CallRecord answerRecord) { 751 callingInProvinceMANYOURecords.add(answerRecord); 752 } 753 // 添加发消息记录 754 public void addSendMessageRecords (MessageRecord sendMessageRecord) { 755 sendMessageRecords.add(sendMessageRecord); 756 } 757 // 添加收消息记录 758 public void addreceiveMessageRecords (MessageRecord receiveMessageRecord) { 759 receiveMessageRecords.add(receiveMessageRecord); 760 } 761 // 添加人在不在市内但在省内漫游打电话记录 762 public void addcallingInProvinceMANYOURecords (CallRecord callRecord) { 763 callingInProvinceMANYOURecords.add(callRecord); 764 } 765 // 添加人不在省内但在国内漫游打电话记录 766 public void addcallingInLandMANYOURecords (CallRecord callRecord) { 767 callingInLandMANYOURecords.add(callRecord); 768 } 769 770 771 772 773 774 public ArrayList<CallRecord> getCallingInCityRecords() { 775 return callingInCityRecords; 776 } 777 public ArrayList<CallRecord> getCallingInProvinceRecords() { 778 return callingInProvinceRecords; 779 } 780 public ArrayList<CallRecord> getCallingInLandRecords() { 781 return callingInLandRecords; 782 } 783 public ArrayList<CallRecord> getAnswerInCityRecords() { 784 return answerInCityRecords; 785 } 786 public ArrayList<CallRecord> getAnswerInProvinceRecords() { 787 return answerInProvinceRecords; 788 } 789 public ArrayList<CallRecord> getAnswerInlandRecords() { 790 return answerInlandRecords; 791 } 792 public ArrayList<MessageRecord> getSendMessageRecords() { 793 return sendMessageRecords; 794 } 795 public ArrayList<MessageRecord> getReceiveMessageRecords() { 796 return receiveMessageRecords; 797 } 798 public ArrayList<CallRecord> getCallingInProvinceMANYOURecords() { 799 return callingInProvinceMANYOURecords; 800 } 801 public ArrayList<CallRecord> getCallingInLandMANYOURecords() { 802 return callingInLandMANYOURecords; 803 } 804 805 806 }
2、没什么难度

1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.Comparator; 4 import java.util.Scanner; 5 6 public class Main { 7 8 public static void main(String[] args) { 9 // TODO 自动生成的方法存根 10 11 ArrayList<Student> stus =new ArrayList<Student>(); 12 Scanner in = new Scanner(System.in); 13 String a = in.nextLine(); 14 int n = Integer.parseInt(a); 15 for(int i=0; i<n; i++) { 16 String s = in.nextLine(); 17 String[] ss = s.split(" "); 18 Student student = new Student(ss[0], ss[1], ss[2], ss[3]); 19 boolean flag = true; 20 for(Student stu : stus) { 21 if(stu.getNum().equals(student.getNum())) 22 flag = false; 23 } 24 if(flag) { 25 stus.add(student); 26 } 27 } 28 29 Collections.sort(stus); 30 System.out.println(stus.size()); 31 for(Student s : stus) { 32 System.out.println(s.getNum()+" " +s.getName()+" "+s.getAge()+" "+s.getSex()); 33 } 34 in.close(); 35 36 } 37 } 38 class Student implements Comparable<Student>{ 39 40 private String num; 41 private String name; 42 private String age; 43 private String sex; 44 public Student(String num, String name, String age, String sex) { 45 super(); 46 this.num = num; 47 this.name = name; 48 this.age = age; 49 this.sex = sex; 50 } 51 public Student() { 52 // TODO 自动生成的构造函数存根 53 } 54 public String getNum() { 55 return num; 56 } 57 public void setNum(String num) { 58 this.num = num; 59 } 60 public String getName() { 61 return name; 62 } 63 public void setName(String name) { 64 this.name = name; 65 } 66 public String getAge() { 67 return age; 68 } 69 public void setAge(String age) { 70 this.age = age; 71 } 72 public String getSex() { 73 return sex; 74 } 75 public void setSex(String sex) { 76 this.sex = sex; 77 } 78 @Override 79 public int compareTo(Student o) { 80 // TODO 自动生成的方法存根 81 return Integer.valueOf(this.getNum())-Integer.valueOf(o.getNum()); 82 } 83 84 85 86 }
3、没什么难度

1 import java.util.ArrayList; 2 import java.util.Collection; 3 import java.util.Iterator; 4 import java.util.Scanner; 5 6 //1、导入相关包 7 8 //定义员工类 9 class Employee { 10 11 private String name; 12 private int age; 13 14 public Employee() { 15 super(); 16 } 17 public Employee(String name, int age) { 18 super(); 19 this.name = name; 20 this.age = age; 21 } 22 23 public String getName() { 24 return name; 25 } 26 27 public void setName(String name) { 28 this.name = name; 29 } 30 31 public int getAge() { 32 return age; 33 } 34 35 public void setAge(int age) { 36 this.age = age; 37 } 38 } 39 40 //主函数 41 public class Main { 42 43 public static void main(String[] args) { 44 // 1、创建有序集合对象 45 Collection<Employee> c = new ArrayList(); 46 47 // 创建3个员工元素对象 48 for (int i = 0; i < 3; i++) { 49 Scanner sc = new Scanner(System.in); 50 String employeeName = sc.nextLine(); 51 int employeeAge = sc.nextInt(); 52 Employee employee = new Employee(employeeName, employeeAge); 53 c.add(employee); 54 } 55 56 // 2、创建迭代器遍历集合 57 Iterator<Employee> it = c.iterator(); 58 59 //3、遍历 60 while (it.hasNext()) { 61 62 //4、集合中对象未知,向下转型 63 Employee e = it.next(); 64 65 System.out.println(e.getName() + "---" + e.getAge()); 66 } 67 } 68 69 }
(3)第七次作业的设计分析总结
1、第一题没什么难度,就是按照之前的思路来做就行,不过要注意用substring截取从第26位开始的东西比较方便,因为第26位之后的就全是短信内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自动生成的方法存根 Scanner input = new Scanner(System. in ); ArrayList<User> MobilePhoneUsers = new ArrayList<User>(); ArrayList<MessageRecord> MessageRecords = new ArrayList<MessageRecord>(); String s = input.nextLine(); while (!s.equals( "end" )) { if (InPutFormat.MobilePhoneUjudge(s)) { InPutFormat.MobilePhoneUsers(s, MobilePhoneUsers); } if (InPutFormat.MessageRecordJudge(s)) { InPutFormat.addMessageRecord(s, MessageRecords); } s = input.nextLine(); } Collections.sort(MobilePhoneUsers, new Comparator<User>() { @Override public int compare(User o1,User o2) { double d1 = Double.parseDouble(o1.getNumber()); double d2 = Double.parseDouble(o2.getNumber()); if (d1 > d2) { return 1; } return -1; } }); InputData.SaveRightMessageRecords(MobilePhoneUsers, MessageRecords); for (User u : MobilePhoneUsers) { System.out.println(u.getNumber()+ " " +String.format( "%.1f" , u.calCost())+ " " +String.format( "%.1f" , u.getBalance())); } } } abstract class ChargeMode { private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>(); 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; } } abstract class ChargeRule { } abstract class CommunicationRecord { private String callingNumber; private String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this .callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this .answerNumber = answerNumber; } } class InputData { public static void SaveRightMessageRecords(ArrayList<User> users, ArrayList<MessageRecord> messageRecords) { for (int i=0; i<users.size(); i++) { UserRecords userRecords = new UserRecords(); //用户记录 for (int j=0; j<messageRecords.size(); j++) { // 将用户记录添加到对应的用户记录当中 if (users.get(i).getNumber().equals(messageRecords.get(j).getCallingNumber())) { userRecords.addSendMessageRecords(messageRecords.get(j)); } } // 将用户记录存入对应用户中 users.get(i).setUserRecords(userRecords); } } } class InPutFormat { public static boolean MobilePhoneUjudge(String s) { // 电话开户是否符合输入要求 if (s.matches( "u-1\\d{10} 3" )) { return true ; } else return false ; } public static boolean MessageRecordJudge(String s) { // 短信记录是否符合输入要求 if (s.matches( "m-1\\d{10} 1\\d{10} (\\w|\\d|\\.| |,)+" )) { return true ; } else return false ; } public static void MobilePhoneUsers(String s,ArrayList<User> users) { PhoneCharging mPhone = new PhoneCharging(); String[] ss = s.split( " " ); String[] sss = ss[0].split( "-" ); int flag = 0; for (int i=0;i<users.size();i++) { if (users.get(i).getNumber().equals(sss[1])) { flag = 1; } } if (flag==0) { User u = new User(mPhone, sss[1]); users.add(u); } } public static void addMessageRecord(String s, ArrayList<MessageRecord> MessageRecords) { String[] ss = s.split( " " ); String[] sss = ss[0].split( "-" ); MessageRecord m = new MessageRecord(s.substring(26), sss[1], ss[0]); MessageRecords.add(m); } } abstract class MessageChargeRule extends ChargeRule { public abstract double CalCost(ArrayList<MessageRecord> messageRecords); } class MessageRecord extends CommunicationRecord { private String message; public MessageRecord(String message, String callingNumber, String answerNumber) { super (); this .message = message; this .setCallingNumber(callingNumber); this .setAnswerNumber(answerNumber); } public String getMessage() { return message; } public void setMessage(String message) { this .message = message; } } class PhoneCharging extends ChargeMode { private double MonthlyRent=0; @Override public double calCost(UserRecords userRecords) { // TODO 自动生成的方法存根 SendMessageRule s = new SendMessageRule(); return s.CalCost(userRecords.getSendMessageRecords())+MonthlyRent; } @Override public double getMonthlyRent() { // TODO 自动生成的方法存根 return MonthlyRent; } } class SendMessageRule extends MessageChargeRule { @Override public double CalCost(ArrayList<MessageRecord> messageRecords) { // TODO 自动生成的方法存根 double cost =0; double flag =0; for (int i=0;i<messageRecords.size();i++) { flag += messageRecords.get(i).getMessage().length()/10; if (messageRecords.get(i).getMessage().length()%10!=0) flag +=1; } if (flag<=3) return 0.1*flag; else if (flag>3&&flag<=5) return 0.3+0.2*(flag-3); else return 0.7+0.3*(flag-5); } } class User { private UserRecords userRecords; //用户记录 private double balance = 100; //用户余额 private ChargeMode chargeMode; //计费方式 private String number; //号码 public User(ChargeMode chargeMode, String number) { this .chargeMode = chargeMode; this .number = number; } public double calCost() { balance = balance - (chargeMode.calCost(userRecords) + chargeMode.getMonthlyRent()); return chargeMode.calCost(userRecords); } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this .userRecords = userRecords; } 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; } public double getBalance() { return balance; } public void setBalance(double balance) { this .balance = balance; } } class UserRecords { private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); //发信息 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); //收信息 public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public void setSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) { this .sendMessageRecords = sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } public void setReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) { this .receiveMessageRecords = receiveMessageRecords; } // 添加发消息记录 public void addSendMessageRecords (MessageRecord sendMessageRecord) { sendMessageRecords.add(sendMessageRecord); } // 添加收消息记录 public void addreceiveMessageRecords (MessageRecord receiveMessageRecord) { receiveMessageRecords.add(receiveMessageRecord); } } |
2、没什么难度

1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 // TODO 自动生成的方法存根 7 8 Scanner input = new Scanner(System.in); 9 int number = input.nextInt(); 10 Shop shop = new Shop(); 11 shop.setMilkCount(number); 12 shop.coupons50.buy(); 13 shop.coupons100.buy(); 14 15 } 16 17 } 18 class Shop { 19 20 private int milkCount; 21 22 InnerCoupons coupons50; 23 InnerCoupons coupons100; 24 25 26 class InnerCoupons 27 { 28 public int value; 29 30 InnerCoupons(int n){ 31 this.value=n; 32 } 33 34 public void buy() { 35 36 System.out.println("使用了面值为"+value+"的购物券进行支付"); 37 milkCount-=value/50; 38 System.out.println("牛奶还剩"+milkCount+"箱"); 39 } 40 41 } 42 43 Shop() 44 { 45 coupons50 = new InnerCoupons(50); 46 coupons100 = new InnerCoupons(100); 47 } 48 49 public int getMilkCount() { 50 return milkCount; 51 } 52 53 public void setMilkCount(int milkCount) { 54 this.milkCount = milkCount; 55 } 56 57 58 59 60 61 62 63 64 }
3、没什么难度

1 public class Main { 2 public static void main(String[] args) { 3 Cat cat = new Cat(); 4 Dog dog = new Dog(); 5 Goat goat = new Goat(); 6 speak(cat); 7 speak(dog); 8 speak(goat); 9 } 10 11 //定义静态方法speak() 12 public static void speak(Animal animal) { 13 System.out.println(animal.getAnimalClass()+animal.shout()); 14 } 15 } 16 17 //定义抽象类Animal 18 abstract class Animal{ 19 public abstract String getAnimalClass(); 20 public abstract String shout(); 21 } 22 //基于Animal类,定义猫类Cat,并重写两个抽象方法 23 class Cat extends Animal{ 24 25 @Override 26 public String getAnimalClass() { 27 String name = "猫的叫声:"; 28 return name; 29 } 30 31 @Override 32 public String shout() { 33 String shout = "喵喵"; 34 return shout; 35 } 36 } 37 //基于Animal类,定义狗类Dog,并重写两个抽象方法 38 class Dog extends Animal{ 39 40 @Override 41 public String getAnimalClass() { 42 String name = "狗的叫声:"; 43 return name; 44 } 45 46 @Override 47 public String shout() { 48 String shout = "汪汪"; 49 return shout; 50 } 51 } 52 //基于Animal类,定义山羊类Goat,并重写两个抽象方法 53 class Goat extends Animal { 54 55 @Override 56 public String getAnimalClass() { 57 String name = "山羊的叫声:"; 58 return name; 59 } 60 61 @Override 62 public String shout() { 63 String shout = "咩咩"; 64 return shout; 65 } 66 }
三、踩坑心得
1、还是没有养成边码代码边写注释的习惯,再加上这次题目十分复杂,代码行数已经达到了2000行以上,方法数十分地多,这就导致我经常忘记哪个方法是干什么的,以后一定养成边码代码边写注释的习惯。
2、没有对重复出现的代码方法话,导致代码复用率特别高,尤其是在穷举时。
3、用了大量的判断语句导致代码的圈复杂度特别高
4、没有找到合适的数学方法,导致在判断某些东西时漏掉情况。
四、改进建议
1. 在定义方法时,选取高效的算法降低代码运行时占用的内存,并降低运行时间,若算法差,则代码冗长,可读性差。
2. 尽可能减少代码复用,提高代码质量。
3. 需要养成及时写注释的习惯,在这次写博客的过程中就深刻体会到了这一点,因为前两次作业都过了有一段时间,这就导致我完全不记得流程,这就浪费了我大量时间来回顾题目复习代码,实在是费时费力。并且希望以后在审完题后花一段时间来构思代码,合理分配职责,让代码的复杂度下降,并提高代码整体的美观性。
4.依据题目要求设计类,设计类的固有属性和方法,分配好各类间的职责,尽量做到职责单一化,并且规划好各类的关系。把需要重复出现的语句设计成一个方法,需要用时只需调用即可,降低代码的耦合度。
五、总结
这三次作业考试最大的收获是深刻地理解了继承和多态的应用,让我深深地体会到了其的便利性,这是面向过程所不能带来的。这次的经历也让我知道了自己在算法方面也存在不足,无法设计出优良的代码结构。最后,在面对程序出现的各种错误时去面对出现的各种错误,遇到问题冷静处理分析,多方面寻找原因去解决,从而慢慢提高自己的代码能力,这也是一个合格的程序员所必须具备的能力。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~