一、前言:
几次的大作业还是比较简单的,只需要按照题目给出的类图,对应的写出相应的类,框架已经给出,你只需要填充就行了,多看几遍题目的类图,理清类之间的关联差不多就能写出了。
题量也不是太多,快的话就一天的事(指的是写一天的代码)。
知识点涉及到继承,多态,SimpleDateFormat类。
二、设计与分析:
1.电信计费系列1-座机计费
实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
输入格式:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码除区号外由是7-8位数字组成。
本题只考虑计费类型0-座机计费,电信系列2、3题会逐步增加计费类型。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
注意:
本题非法输入只做格式非法的判断,不做内容是否合理的判断(时间除外,否则无法计算),比如:
1、输入的所有通讯信息均认为是同一个月的通讯信息,不做日期是否在同一个月还是多个月的判定,直接将通讯费用累加,因此月租只计算一次。
2、记录中如果同一电话号码的多条通话记录时间出现重合,这种情况也不做判断,直接 计算每条记录的费用并累加。
3、用户区号不为南昌市的区号也作为正常用户处理。
输出格式:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,
单位元)。假设每个用户初始余额是100元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
建议类图:
参见图1、2、3,可根据理解自行调整:
图1 图1中User是用户类,包括属性: userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。 ChargeMode是计费方式的抽象类: chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。 getMonthlyRent()方法用于返回月租(monthlyRent)。 UserRecords是用户记录类,保存用户各种通话、短信的记录, 各种计费规则将使用其中的部分或者全部记录。 其属性从上到下依次是: 市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、 市内接听电话、省内(不含市内)接听电话、省外接听电话的记录 以及发送短信、接收短信的记录。
图2 图2中CommunicationRecord是抽象的通讯记录类: 包含callingNumber拨打号码、answerNumber接听号码两个属性。 CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。 CallRecord(通话记录类)包含属性: 通话的起始、结束时间以及 拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。 区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。
图3 图3是计费规则的相关类,这些类的核心方法是: calCost(ArrayList<CallRecord> callRecords)。 该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。 输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。 LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是 座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。 (提示:可以从UserRecords类中获取各种类型的callRecords)。
输入样例1:
u-079186300001 0 t-079186300001 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:25 end
输出样例1:
079186300001 3.0 77.0
代码:
1 import java.util.*; 2 import java.text.DecimalFormat; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 Scanner scanner = new Scanner(System.in); 8 String user = scanner.nextLine(); 9 String[] num = user.split(" "); 10 String[] num1 = num[0].split("-"); 11 System.out.print(num1[1]+' '); 12 String s="end"; 13 String s1="t"; 14 double balance = 100; 15 double all=0; 16 String pattern1 = "[t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s" + 17 "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?" + 18 "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + 19 "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + 20 "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s" + 21 "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.(" + 22 "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + 23 "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + 24 "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-^9]):([0-5][0-9])"; 25 while(true) 26 { 27 double cost = 0,kk; 28 double h=0,f=0,m=0,d=0; 29 double totol=0; 30 double h1=0,h2=0,f1=0,f2=0,m1=0,m2=0,d1=0,d2=0; 31 String information = scanner.next(); 32 if(information.equals(s)) 33 { 34 break; 35 } 36 String receiveNumber = scanner.next(); 37 String startDay = scanner.next(); 38 String startTime = scanner.next(); 39 String endDay = scanner.next(); 40 String endTime = scanner.next(); 41 42 String start =information + " " +receiveNumber+ " " +startDay + " " + startTime + " " +endDay + " " + endTime; 43 44 if(start.matches(pattern1)) 45 { 46 String[] num2 = information.split("-"); 47 String[] number = information.split("-"); 48 String[] time1 = startTime.split(":"); 49 String[] time2 = endTime.split(":"); 50 h1=Double.parseDouble(time1[0]); 51 h2=Double.parseDouble(time2[0]); 52 f1=Double.parseDouble(time1[1]); 53 f2=Double.parseDouble(time2[1]); 54 m1=Double.parseDouble(time1[2]); 55 m2=Double.parseDouble(time2[2]); 56 h=(h2-h1)*60; 57 f=f2-f1; 58 m=m2-m1; 59 if(m>0) 60 { 61 f++; 62 } 63 totol=h+f+d; 64 if(startDay.equals(endDay)) 65 totol=totol; 66 else 67 totol=totol+1440; 68 69 char str[] = receiveNumber.toCharArray(); 70 if(str[0]=='0' && str[1]=='7' && str[2]=='9' && str[3]=='1') 71 { 72 cost=totol*0.1; 73 } 74 else if(str[0]=='0' && str[1]=='7' && str[2]=='9' && str[3]!='1') 75 { 76 cost=totol*0.3; 77 } 78 else if(str[0]=='0' && str[1]=='7' && str[2]=='0' && str[3]=='1') 79 { 80 cost=totol*0.3; 81 } 82 else 83 cost=totol*0.6; 84 if(receiveNumber.equals(num1[1])) 85 cost=0; 86 balance=balance-cost; 87 all=all+cost; 88 } 89 else 90 cost=0; 91 } 92 balance=balance-20; 93 System.out.print(new DecimalFormat("0.0#").format(all)+" "); 94 System.out.print(new DecimalFormat("0.0#").format(balance)); 95 } 96 }View Code
2. 多态测试
定义容器Container接口。模拟实现一个容器类层次结构,并进行接口的实现、抽象方法重写和多态机制测试。各容器类实现求表面积、体积的方法。
- 定义接口Container:
属性:
public static final double pi=3.1415926;
抽象方法:
public abstract double area();
public abstract double volume();
static double sumofArea(Container c[]);
static double sumofVolume(Container c[]);
其中两个静态方法分别计算返回容器数组中所有对象的面积之和、周长之和; - 定义Cube类、Cylinder类均实现自Container接口。
Cube类(属性:边长double类型)、Cylinder类(属性:底圆半径、高,double类型)。
输入格式:
第一行n表示对象个数,对象类型用cube、cylinder区分,cube表示立方体对象,后面输入边长,输入cylinder表示圆柱体对象,后面是底圆半径、高。
输出格式:
分别输出所有容器对象的表面积之和、体积之和,结果保留小数点后2位。
输入样例1:
4 cube 15.7 cylinder 23.5 100 cube 46.8 cylinder 17.5 200
输出样例1:
56771.13 472290.12
代码:
1 import java.text.DecimalFormat; 2 import java.util.Scanner; 3 public class Main { 4 public static void main(String[] args) { 5 String ch; 6 Scanner s=new Scanner(System.in); 7 int n=s.nextInt(); 8 Container c[] = new Container[n]; 9 for(int i=0;i<n;i++) { 10 ch=s.next(); 11 if(ch.equals("cube")){ 12 c[i]=new Cube(s.nextDouble()); 13 } 14 else if(ch.equals("cylinder")) { 15 double q=s.nextDouble(); 16 double p=s.nextDouble(); 17 c[i]=new Cylinder(q,p); 18 } 19 } 20 System.out.println(Container.sumofArea(c)); 21 System.out.println(Container.sumofVolume(c)); 22 } 23 } 24 interface Container{ 25 public static final double P =3.1415926; 26 public abstract double area(); 27 public abstract double volume(); 28 static double sumofArea(Container c[]) { 29 double s=0; 30 for(Container j:c) { 31 s+=j.area(); 32 } 33 DecimalFormat d = new DecimalFormat("#.00"); 34 Double output = Double.valueOf(d.format(s)); 35 return output; 36 } 37 static double sumofVolume(Container c[]) { 38 double f=0; 39 for(Container d:c) { 40 f+=d.volume(); 41 } 42 DecimalFormat d = new DecimalFormat("#.00"); 43 Double output = Double.valueOf(d.format(f)); 44 return output; 45 } 46 } 47 class Cube implements Container{ 48 private double q; 49 Cube(double q) { 50 this.q=q; 51 } 52 public double area() { 53 double A=q*q*6; 54 return A; 55 } 56 public double volume() { 57 double V=q*q*q; 58 return V; 59 } 60 } 61 class Cylinder implements Container{ 62 private double q; 63 private double p; 64 Cylinder(double q, double p) { 65 this.q=q; 66 this.p=p; 67 } 68 public double area() { 69 double A= P *q*q*2+2* P *q*p; 70 return A; 71 } 72 public double volume() { 73 double V= P *q*q*p; 74 return V; 75 } 76 }View Code
3.电信计费系列2-手机+座机计费
实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
1、针对市内座机用户采用的计费方式(与电信计费系列1内容相同):
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
假设本市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
2、针对手机用户采用实时计费方式:
月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟;
注:被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
输入:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,含手机和座机用户
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题在电信计费系列1基础上增加类型1-手机实时计费。
手机设置0或者座机设置成1,此种错误可不做判断。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
输入格式增加手机接打电话以及收发短信的格式,手机接打电话的信息除了号码之外需要额外记录拨打/接听的地点的区号,比如:
座机打手机:
t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:
t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
输入样例:
u-13811111111 1 t-13811111111 0791 13811111110 020 2022.1.3 08:00:00 2022.1.3 08:09:20 end
输出样例:
13811111111 3.0 82.0
代码:
1 import java.util.ArrayList; 2 import java.util.Date; 3 import java.util.Iterator; 4 import java.util.Map; 5 import java.util.Scanner; 6 import java.util.TreeMap; 7 import java.text.ParseException; 8 import java.text.SimpleDateFormat; 9 public class Main { 10 11 public static void main(String[] args) { 12 // TODO 自动生成的方法存根 13 Processdata p = new Processdata(); 14 p.work(); 15 } 16 17 } 18 abstract class AnswerChargeRule extends ChargeRule { 19 20 public abstract double calCost(ArrayList<CallRecord> callrecords); 21 } 22 class AnswerRoamMobilePhoneInCityRule extends AnswerChargeRule { 23 24 @Override 25 public double calCost(ArrayList<CallRecord> callrecords) { 26 // TODO 自动生成的方法存根 27 double cost = 0; 28 for(CallRecord c : callrecords) { 29 cost+=Math.ceil((c.getEndTime().getTime()-c.getStateTime().getTime())/1000.0/60.0)*0.3; 30 } 31 return cost; 32 } 33 34 } 35 abstract class CallChargeRule extends ChargeRule { 36 public abstract double calCost(ArrayList<CallRecord> callrecords); 37 38 39 } 40 class CallRecord extends CommunicationRecord { 41 private Date stateTime; 42 private Date endTime; 43 private String callingAddressAreaCode; 44 private String answerAddressAreaCode; 45 46 public CallRecord( String callingNumber,String answerNumber,Date stateTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) { 47 48 super(); 49 setCallingNumber(callingNumber); 50 setAnswerNumber(answerNumber); 51 this.stateTime = stateTime; 52 this.endTime = endTime; 53 this.callingAddressAreaCode = callingAddressAreaCode; 54 this.answerAddressAreaCode = answerAddressAreaCode; 55 } 56 public Date getStateTime() { 57 return stateTime; 58 } 59 public void setStateTime(Date stateTime) { 60 this.stateTime = stateTime; 61 } 62 public Date getEndTime() { 63 return endTime; 64 } 65 public void setEndTime(Date endTime) { 66 this.endTime = endTime; 67 } 68 public String getCallingAddressAreaCode() { 69 return callingAddressAreaCode; 70 } 71 public void setCallingAddressAreaCode(String callingAddressAreaCode) { 72 this.callingAddressAreaCode = callingAddressAreaCode; 73 } 74 public String getAnswerAddressAreaCode() { 75 return answerAddressAreaCode; 76 } 77 public void setAnswerAddressAreaCode(String answerAddressAreaCode) { 78 this.answerAddressAreaCode = answerAddressAreaCode; 79 } 80 81 } 82 abstract class ChargeMode { 83 private ArrayList<ChargeRule> chargeRules = new ArrayList<ChargeRule>(); 84 85 86 87 88 89 public ArrayList<ChargeRule> getChargeRules() { 90 return chargeRules; 91 } 92 93 public void setChargeRules(ArrayList<ChargeRule> chargeRules) { 94 this.chargeRules = chargeRules; 95 } 96 97 public abstract double calCost(UserRecords useRecords); 98 99 public abstract double getMonthlyRent(); 100 101 } 102 abstract class ChargeRule { 103 public abstract double calCost(ArrayList<CallRecord> callrecords); 104 } 105 abstract class CommunicationRecord { 106 protected String callingNumber; 107 protected String answerNumber; 108 109 public String getCallingNumber() { 110 return callingNumber; 111 } 112 113 public void setCallingNumber(String callingNumber) { 114 this.callingNumber = callingNumber; 115 } 116 117 public String getAnswerNumber() { 118 return answerNumber; 119 } 120 121 public void setAnswerNumber(String answerNumber) { 122 this.answerNumber = answerNumber; 123 } 124 125 } 126 class LandlinePhoneCharging extends ChargeMode { 127 private double monthlyRent = 20; 128 129 public LandlinePhoneCharging() { 130 super(); 131 132 getChargeRules().add(new LandPhoneInCityRule()); 133 getChargeRules().add(new LandPhoneInProvinceRule()); 134 getChargeRules().add(new LandPhoneInLandRule()); 135 } 136 137 @Override 138 public double calCost(UserRecords useRecords) { 139 // TODO 自动生成的方法存根 140 double cost= 0; 141 cost+= getChargeRules().get(0).calCost(useRecords.getCallinginCityRecords()); 142 cost+= getChargeRules().get(1).calCost(useRecords.getCallinginProvinceRecords()); 143 cost+= getChargeRules().get(2).calCost(useRecords.getCallinginLandRecords()); 144 return cost; 145 146 } 147 148 @Override 149 public double getMonthlyRent() { 150 // TODO 自动生成的方法存根 151 return this.monthlyRent; 152 } 153 154 } 155 class LandPhoneInCityRule extends CallChargeRule { 156 157 @Override 158 public double calCost(ArrayList<CallRecord> callrecords) { 159 // TODO 自动生成的方法存根 160 double cost = 0; 161 for(CallRecord c : callrecords) { 162 cost+=Math.ceil((c.getEndTime().getTime()-c.getStateTime().getTime())/1000.0/60.0)*0.1; 163 } 164 return cost; 165 166 } 167 168 169 } 170 class LandPhoneInLandRule extends CallChargeRule { 171 172 @Override 173 public double calCost(ArrayList<CallRecord> callrecords) { 174 // TODO 自动生成的方法存根 175 double cost = 0; 176 for(CallRecord c : callrecords) { 177 cost+=Math.ceil((c.getEndTime().getTime()-c.getStateTime().getTime())/1000.0/60.0)*0.6; 178 } 179 return cost; 180 } 181 182 183 184 } 185 class LandPhoneInProvinceRule extends CallChargeRule { 186 187 @Override 188 public double calCost(ArrayList<CallRecord> callrecords) { 189 // TODO 自动生成的方法存根 190 double cost = 0; 191 for(CallRecord c : callrecords) { 192 cost+=Math.ceil((c.getEndTime().getTime()-c.getStateTime().getTime())/1000.0/60.0)*0.3; 193 } 194 return cost; 195 } 196 197 198 199 } 200 class MessageRecord extends CommunicationRecord { 201 private String message; 202 203 public MessageRecord(String callingNumber, String answerNumber, String message) { 204 super(); 205 setCallingNumber(callingNumber); 206 setAnswerNumber(answerNumber); 207 this.message = message; 208 } 209 210 public String getMessage() { 211 return message; 212 } 213 214 public void setMessage(String message) { 215 this.message = message; 216 } 217 218 } 219 class MobilePhoneCharging extends ChargeMode { 220 private double monthlyRent = 15; 221 222 223 public MobilePhoneCharging() { 224 super(); 225 getChargeRules().add(new MobilePhoneInCityRule()); 226 getChargeRules().add(new MobilePhoneInProvinceRule()); 227 getChargeRules().add(new MobilePhoneInLandRule()); 228 getChargeRules().add(new RoamMobilePhoneInLandRule()); 229 getChargeRules().add(new RoamMobilePhoneInProvinceRule()); 230 getChargeRules().add(new AnswerRoamMobilePhoneInCityRule()); 231 } 232 233 @Override 234 public double calCost(UserRecords useRecords) { 235 // TODO 自动生成的方法存根 236 double cost= 0; 237 cost+= getChargeRules().get(0).calCost(useRecords.getCallinginCityRecords()); 238 cost+= getChargeRules().get(1).calCost(useRecords.getCallinginProvinceRecords()); 239 cost+= getChargeRules().get(2).calCost(useRecords.getCallinginLandRecords()); 240 cost+= getChargeRules().get(3).calCost(useRecords.getRoamCallingInLandRecords()); 241 cost+= getChargeRules().get(4).calCost(useRecords.getRoamCallingInProvinceRecords()); 242 cost+= getChargeRules().get(5).calCost(useRecords.getRoamAnswernLandRecords()); 243 return cost; 244 } 245 246 @Override 247 public double getMonthlyRent() { 248 // TODO 自动生成的方法存根 249 return this.monthlyRent; 250 } 251 252 } 253 254 class MobilePhoneInCityRule extends CallChargeRule { 255 256 @Override 257 public double calCost(ArrayList<CallRecord> callrecords) { 258 // TODO 自动生成的方法存根 259 double cost = 0; 260 for(CallRecord c : callrecords) { 261 cost+=Math.ceil((c.getEndTime().getTime()-c.getStateTime().getTime())/1000.0/60.0)*0.1; 262 } 263 return cost; 264 } 265 266 } 267 268 class MobilePhoneInLandRule extends CallChargeRule { 269 270 @Override 271 public double calCost(ArrayList<CallRecord> callrecords) { 272 // TODO 自动生成的方法存根 273 double cost = 0; 274 for(CallRecord c : callrecords) { 275 cost+=Math.ceil((c.getEndTime().getTime()-c.getStateTime().getTime())/1000.0/60.0)*0.3; 276 } 277 return cost; 278 } 279 280 } 281 class MobilePhoneInProvinceRule extends CallChargeRule { 282 283 @Override 284 public double calCost(ArrayList<CallRecord> callrecords) { 285 // TODO 自动生成的方法存根 286 // TODO 自动生成的方法存根 287 double cost = 0; 288 for(CallRecord c : callrecords) { 289 cost+=Math.ceil((c.getEndTime().getTime()-c.getStateTime().getTime())/1000.0/60.0)*0.2; 290 } 291 return cost; 292 } 293 294 } 295 296 class Processdata { 297 298 public Processdata() { 299 super(); 300 // TODO 自动生成的构造函数存根 301 } 302 303 public void work() { 304 TreeMap<String, User> users = new TreeMap<>(); 305 Scanner input = new Scanner(System.in); 306 String regex1 = "[u]-0[0-9]{10,11}\\s[0]"; 307 String regex5 = "[u]-1(\\d){10}\\s[1]"; 308 String regex2 = "t-0[0-9]{9,11}\\s0[0-9]{9,11}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}"; 309 String regex3 = "t-0[0-9]{9,11}\\s1(\\d){10}\\s(\\d){3,4}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}"; 310 String regex6 = "t-1(\\d){10}\\s(\\d){3,4}\\s0[0-9]{9,11}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}"; 311 String regex4 = "t-1(\\d){10}\\s(\\d){3,4}\\s1(\\d){10}\\s(\\d){3,4}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\d{4}.\\d{1,2}.\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}"; 312 String s = input.nextLine(); 313 while (!s.equals("end")) { 314 if (s.matches(regex1)) {//座机用户 315 String data[] = s.substring(2).split(" "); 316 String number = data[0]; 317 ChargeMode changeMode = new LandlinePhoneCharging(); 318 User user = new User(changeMode, number); 319 users.put(number, user); 320 // t-13986300001 0799 079186300001 2022.12.31 23:50:25 2023.1.1 00:05:11 321 322 } 323 else if (s.matches(regex5)) {//手机用户 324 String data[] = s.substring(2).split(" "); 325 String number = data[0]; 326 ChargeMode changeMode = new MobilePhoneCharging(); 327 User user = new User(changeMode, number); 328 users.put(number, user); 329 } 330 else if(s.matches(regex6)) {//手机打座机 331 String data[] = s.substring(2).split(" "); 332 String callingNumber = data[0]; 333 String callingAddressAreaCode = data[1]; 334 String answerAddressAreaCode = data[2].substring(0, 4); 335 String answerNumber = data[2]; 336 String stateDate = data[3]; 337 String stateTime = data[4]; 338 String endDate = data[5]; 339 String endTime = data[6]; 340 String state = stateDate + " " + stateTime; 341 String end = endDate + " " + endTime; 342 Date statedate = new Date(); 343 Date enddate = new Date(); 344 String strDateFormat = "yyyy.MM.dd HH:mm:ss"; 345 346 SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat); 347 try { 348 statedate = sdf.parse(state); 349 } catch (ParseException e) { 350 // TODO 自动生成的 catch 块 351 e.printStackTrace(); 352 } 353 354 try { 355 enddate = sdf.parse(end); 356 } catch (ParseException e) { 357 // TODO 自动生成的 catch 块 358 e.printStackTrace(); 359 } 360 if(statedate.before(enddate)) { 361 362 363 CallRecord callRecord = new CallRecord(callingNumber, answerNumber, statedate, enddate, 364 callingAddressAreaCode, answerAddressAreaCode); 365 Long address1 = Long.parseLong(callRecord.getCallingAddressAreaCode()); 366 Long address2 = Long.parseLong(callRecord.getAnswerAddressAreaCode()); 367 368 if (address1 == 791) { 369 if(address2==791) { 370 users.get(callingNumber).getUserRecords().addCallinginCityRecords(callRecord); 371 } 372 else if( (address2 == 701 ||address2 >= 790 && address2 <= 799 )) { 373 users.get(callingNumber).getUserRecords().addCallinginProvinceRecords(callRecord); 374 } 375 else { 376 users.get(callingNumber).getUserRecords().addCallinginLandRecords(callRecord); 377 } 378 } 379 380 else if (address1 == 701 || (address1 >= 790 && address1 <= 799 )) { 381 users.get(callingNumber).getUserRecords().addRoamCallingInProvinceRecords(callRecord); 382 383 } else { 384 users.get(callingNumber).getUserRecords().addRoamCallingInLandRecords(callRecord); 385 } 386 387 } 388 389 } 390 else if (s.matches(regex2)) {//座机打座机 391 String data[] = s.substring(2).split(" "); 392 String callingAddressAreaCode = data[0].substring(0, 4); 393 String answerAddressAreaCode = data[1].substring(0, 4); 394 String callingNumber = data[0]; 395 String answerNumber = data[1].substring(4); 396 String stateDate = data[2]; 397 String stateTime = data[3]; 398 String endDate = data[4]; 399 String endTime = data[5]; 400 String state = stateDate + " " + stateTime; 401 String end = endDate + " " + endTime; 402 Date statedate = new Date(); 403 Date enddate = new Date(); 404 String strDateFormat = "yyyy.MM.dd HH:mm:ss"; 405 406 SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat); 407 try { 408 statedate = sdf.parse(state); 409 } catch (ParseException e) { 410 // TODO 自动生成的 catch 块 411 e.printStackTrace(); 412 } 413 414 try { 415 enddate = sdf.parse(end); 416 } catch (ParseException e) { 417 // TODO 自动生成的 catch 块 418 e.printStackTrace(); 419 } 420 421 CallRecord callRecord = new CallRecord(callingNumber, answerNumber, statedate, enddate, 422 callingAddressAreaCode, answerAddressAreaCode); 423 Long address = Long.parseLong(callRecord.getAnswerAddressAreaCode()); 424 // if(callRecord.getCallingNumber().equals(callRecord.getAnswerNumber())) { 425 // break; 426 // } 427 428 if (address == 791) { 429 users.get(callingNumber).getUserRecords().addCallinginCityRecords(callRecord); 430 } 431 432 else if (address == 701 || (address >= 790 && address <= 799 )) { 433 users.get(callingNumber).getUserRecords().addCallinginProvinceRecords(callRecord); 434 435 } else { 436 users.get(callingNumber).getUserRecords().addCallinginLandRecords(callRecord); 437 } 438 439 440 } else if (s.matches(regex3)) {//座机打手机 441 String data[] = s.substring(2).split(" "); 442 String callingNumber = data[0]; 443 String answerNumber = data[1]; 444 String callingAddressAreaCode = data[0].substring(0, 4); 445 String answerAddressAreaCode = data[2]; 446 String stateDate = data[3]; 447 String stateTime = data[4]; 448 String endDate = data[5]; 449 String endTime = data[6]; 450 String state = stateDate + " " + stateTime; 451 String end = endDate + " " + endTime; 452 Date statedate = new Date(); 453 Date enddate = new Date(); 454 String strDateFormat = "yyyy.MM.dd HH:mm:ss"; 455 456 SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat); 457 try { 458 statedate = sdf.parse(state); 459 } catch (ParseException e) { 460 // TODO 自动生成的 catch 块 461 e.printStackTrace(); 462 } 463 464 try { 465 enddate = sdf.parse(end); 466 } catch (ParseException e) { 467 // TODO 自动生成的 catch 块 468 e.printStackTrace(); 469 } 470 CallRecord callRecord = new CallRecord(callingNumber, answerNumber, statedate, enddate, 471 callingAddressAreaCode, answerAddressAreaCode); 472 Long address = Long.parseLong(callRecord.getAnswerAddressAreaCode()); 473 if(users.get(answerNumber)!=null) { 474 if (!(address == 701 || (address >= 790 && address <= 799 ))) { 475 users.get(answerNumber).getUserRecords().addRoamAnswernLandRecords(callRecord); 476 } 477 } 478 if (users.get(callingNumber) != null) { 479 if (address == 791) { 480 users.get(callingNumber).getUserRecords().addCallinginCityRecords(callRecord); 481 } 482 483 else if (address == 701 || (address >= 790 && address <= 799)) { 484 users.get(callingNumber).getUserRecords().addCallinginProvinceRecords(callRecord); 485 486 } else { 487 users.get(callingNumber).getUserRecords().addCallinginLandRecords(callRecord); 488 489 } 490 } 491 } else if (s.matches(regex4)) {//手机打手机 492 String data[] = s.substring(2).split(" "); 493 String callingNumber = data[0]; 494 String callingAddressAreaCode = data[1]; 495 String answerNumber = data[2]; 496 String answerAddressAreaCode = data[3]; 497 String stateDate = data[4]; 498 String stateTime = data[5]; 499 String endDate = data[6]; 500 String endTime = data[7]; 501 String state = stateDate + " " + stateTime; 502 String end = endDate + " " + endTime; 503 Date statedate = new Date(); 504 Date enddate = new Date(); 505 String strDateFormat = "yyyy.MM.dd HH:mm:ss"; 506 507 SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat); 508 try { 509 statedate = sdf.parse(state); 510 } catch (ParseException e) { 511 // TODO 自动生成的 catch 块 512 e.printStackTrace(); 513 } 514 515 try { 516 enddate = sdf.parse(end); 517 } catch (ParseException e) { 518 // TODO 自动生成的 catch 块 519 e.printStackTrace(); 520 } 521 if(statedate.before(enddate)) { 522 523 524 CallRecord callRecord = new CallRecord(callingNumber, answerNumber, statedate, enddate, 525 callingAddressAreaCode, answerAddressAreaCode); 526 Long address1 = Long.parseLong(callRecord.getCallingAddressAreaCode()); 527 Long address2 = Long.parseLong(callRecord.getAnswerAddressAreaCode()); 528 if(!callingNumber.equals(answerNumber)) { 529 if(users.get(answerNumber)!=null) { 530 if (!(address2 == 701 || (address2 >= 790 && address2 <= 799 ))) { 531 users.get(answerNumber).getUserRecords().addRoamAnswernLandRecords(callRecord); 532 } 533 } 534 if(users.get(callingNumber)!=null) { 535 536 537 if (address1 == 791 && address2 == 791) { 538 users.get(callingNumber).getUserRecords().addCallinginCityRecords(callRecord); 539 540 } else if (address1 == 791 541 && (address2 == 701 || (address2 >= 790 && address2 <= 799 && address2 != 791))) { 542 users.get(callingNumber).getUserRecords().addCallinginProvinceRecords(callRecord); 543 } else if (address1 == 791 544 && !(address2 == 701 || (address2 >= 790 && address2 <= 799 && address2 != 791))) { 545 users.get(callingNumber).getUserRecords().addCallinginLandRecords(callRecord); 546 547 }else if ((address1==701||(address1>= 790 &&address1<=799))) { 548 users.get(callingNumber).getUserRecords().addRoamCallingInProvinceRecords(callRecord); 549 } 550 else if (!(address1==701||(address1>= 790 &&address1<=799))) { 551 users.get(callingNumber).getUserRecords().addRoamCallingInLandRecords(callRecord); 552 } 553 } 554 } 555 556 557 } 558 } 559 560 561 s = input.nextLine(); 562 } 563 564 for (User user : users.values()) { 565 System.out.printf("%s %.1f %.1f\n",user.getNumber(),user.calCost(),user.calBanlance()); 566 } 567 } 568 } 569 class RoamMobilePhoneInLandRule extends CallChargeRule { 570 571 @Override 572 public double calCost(ArrayList<CallRecord> callrecords) { 573 // TODO 自动生成的方法存根 574 double cost = 0; 575 for(CallRecord c : callrecords) { 576 cost+=Math.ceil((c.getEndTime().getTime()-c.getStateTime().getTime())/1000.0/60.0)*0.6; 577 } 578 return cost; 579 } 580 581 } 582 583 class RoamMobilePhoneInProvinceRule extends CallChargeRule { 584 585 @Override 586 public double calCost(ArrayList<CallRecord> callrecords) { 587 // TODO 自动生成的方法存根 588 double cost = 0; 589 for(CallRecord c : callrecords) { 590 cost+=Math.ceil((c.getEndTime().getTime()-c.getStateTime().getTime())/1000.0/60.0)*0.3; 591 } 592 return cost; 593 } 594 595 } 596 class User { 597 private UserRecords userRecords = new UserRecords();// 用户记录 598 private double banlance = 100; // 余额 599 private ChargeMode changeMode; // 计费方式 600 private String number; // 电话号码 601 602 603 604 605 606 public User(ChargeMode changeMode, String number) { 607 super(); 608 this.changeMode = changeMode; 609 this.number = number; 610 } 611 612 public UserRecords getUserRecords() { 613 return userRecords; 614 } 615 616 public void setUserRecords(UserRecords userRecords) { 617 this.userRecords = userRecords; 618 } 619 620 public double getBanlance() { 621 return banlance; 622 } 623 624 public void setBanlance(double banlance) { 625 this.banlance = banlance; 626 } 627 628 public ChargeMode getChangeMode() { 629 return changeMode; 630 } 631 632 public void setChangeMode(ChargeMode changeMode) { 633 this.changeMode = changeMode; 634 } 635 636 public String getNumber() { 637 return number; 638 } 639 640 public void setNumber(String number) { 641 this.number = number; 642 } 643 644 public double calBanlance() { 645 return this.banlance-changeMode.calCost(userRecords)-changeMode.getMonthlyRent(); 646 647 } 648 649 public double calCost() { 650 return changeMode.calCost(userRecords); 651 652 } 653 } 654 655 class UserRecords { 656 657 public UserRecords() { 658 super(); 659 // TODO 自动生成的构造函数存根 660 } 661 662 private ArrayList<CallRecord> callinginCityRecords = new ArrayList<CallRecord>(); 663 private ArrayList<CallRecord> callinginProvinceRecords = new ArrayList<CallRecord>(); 664 private ArrayList<CallRecord> callinginLandRecords = new ArrayList<CallRecord>(); 665 private ArrayList<CallRecord> answerinCityRecords = new ArrayList<CallRecord>(); 666 private ArrayList<CallRecord> answerinProvinceRecords = new ArrayList<CallRecord>(); 667 private ArrayList<CallRecord> answerinLandRecords = new ArrayList<CallRecord>(); 668 private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); 669 private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); 670 private ArrayList<CallRecord> roamcallinginProvinceRecords = new ArrayList<CallRecord>(); 671 private ArrayList<CallRecord> roamcallinginLandRecords = new ArrayList<CallRecord>(); 672 private ArrayList<CallRecord> roamanswernLandRecords = new ArrayList<CallRecord>(); 673 public ArrayList<CallRecord> getCallinginCityRecords() { 674 return callinginCityRecords; 675 } 676 677 public ArrayList<CallRecord> getCallinginProvinceRecords() { 678 return callinginProvinceRecords; 679 } 680 681 public ArrayList<CallRecord> getCallinginLandRecords() { 682 return callinginLandRecords; 683 } 684 685 public ArrayList<CallRecord> getAnswerinCityRecords() { 686 return answerinCityRecords; 687 } 688 689 public ArrayList<CallRecord> getAnswerinProvinceRecords() { 690 return answerinProvinceRecords; 691 } 692 693 public ArrayList<CallRecord> getAnswerinLandRecords() { 694 return answerinLandRecords; 695 } 696 697 public ArrayList<MessageRecord> getSendMessageRecords() { 698 return sendMessageRecords; 699 } 700 701 public ArrayList<MessageRecord> getReceiveMessageRecords() { 702 return receiveMessageRecords; 703 } 704 705 public ArrayList<CallRecord> getRoamCallingInProvinceRecords() { 706 return roamcallinginProvinceRecords; 707 } 708 709 public ArrayList<CallRecord> getRoamCallingInLandRecords() { 710 return roamcallinginLandRecords; 711 } 712 713 public ArrayList<CallRecord> getRoamAnswernLandRecords(){ 714 return roamanswernLandRecords; 715 } 716 717 718 public void addCallinginCityRecords(CallRecord callRecord) { 719 callinginCityRecords.add(callRecord); 720 } 721 722 public void addCallinginLandRecords(CallRecord callRecord) { 723 callinginLandRecords.add(callRecord); 724 } 725 726 public void addCallinginProvinceRecords(CallRecord callRecord) { 727 callinginProvinceRecords.add(callRecord); 728 } 729 730 public void addAnswennCityRecords(CallRecord callRecord) { 731 answerinCityRecords.add(callRecord); 732 } 733 734 public void addAnswerinProvinceRecords(CallRecord callRecord) { 735 answerinProvinceRecords.add(callRecord); 736 } 737 738 public void addAnswernLandRecords(CallRecord callRecord) { 739 answerinLandRecords.add(callRecord); 740 } 741 742 public void addSendMessageRecords(MessageRecord messageRecord) { 743 sendMessageRecords.add(messageRecord); 744 } 745 746 public void addReceiveMessageRecords(MessageRecord messageRecord) { 747 receiveMessageRecords.add(messageRecord); 748 } 749 public void addRoamCallingInProvinceRecords(CallRecord callRecord) { 750 roamcallinginProvinceRecords.add(callRecord); 751 } 752 public void addRoamCallingInLandRecords(CallRecord callRecord) { 753 roamcallinginLandRecords.add(callRecord); 754 } 755 public void addRoamAnswernLandRecords(CallRecord callRecord) { 756 roamanswernLandRecords.add(callRecord); 757 } 758 759 }View Code
4. sdut-Collection-sort--C~K的班级(II)
经过不懈的努力,C~K终于当上了班主任。
现在他要统计班里学生的名单,但是C~K在教务系统中导出班级名单时出了问题,发现会有同学的信息重复,现在他想把重复的同学信息删掉,只保留一个,
但是工作量太大了,所以找到了会编程的你,你能帮他解决这个问题吗?
输入格式:
第一行输入一个N,代表C~K导出的名单共有N行(N<100000).
接下来的N行,每一行包括一个同学的信息,学号 姓名 年龄 性别。
输出格式:
第一行输出一个n,代表删除重复名字后C~K的班级共有几人。
接下来的n行,输出每一个同学的信息,输出按照学号从小到大的顺序。
输入样例:
6 0001 MeiK 20 M 0001 MeiK 20 M 0002 sdk2 21 M 0002 sdk2 21 M 0002 sdk2 21 M 0000 blf2 22 F
输出样例:
3 0000 blf2 22 F 0001 MeiK 20 M 0002 sdk2 21 M
代码:
1 import java.util.Scanner; 2 public class Main { 3 public static void main(String[] args) { 4 String ch; 5 Scanner in = new Scanner(System.in); 6 int c = in.nextInt(); 7 in.nextLine(); 8 String[] n = new String[c]; 9 for(int i=0;i<c;i++) { 10 ch=in.nextLine(); 11 n[i]=ch; 12 } 13 for(int i=0;i<c-1;i++) { 14 for(int k=i+1;k<c;k++) 15 { 16 if(n[i].equals(n[k])) 17 { 18 for(int j=k;j<c-1;j++) 19 n[j]=n[j+1]; 20 c--; 21 k--; 22 23 } 24 25 } 26 } 27 System.out.println(c); 28 String m = null; 29 for(int i=0;i<c;i++) { 30 for(int k=i+1;k<c;k++) { 31 if(n[i].compareTo(n[k])>0){ 32 m=n[i]; 33 n[i]=n[k]; 34 n[k]=m; 35 } 36 } 37 } 38 for(int i=0;i<c;i++) { 39 System.out.println(n[i]); 40 } 41 } 42 }View Code
5.阅读程序,按照题目需求修改程序
功能需求: 使用集合存储3个员工的信息(有序); 通过迭代器依次找出所有的员工。
提示:学生复制以下代码到编程区,并按需求进行调试修改。
// 1、导入相关包 //定义员工类 class Employee { private String name; private int age; public Employee() { super(); } public Employee(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } //主函数 public class Main { public static void main(String[] args) { // 1、创建有序集合对象 Collection c ; // 创建3个员工元素对象 for (int i = 0; i < 3; i++) { Scanner sc = new Scanner(System.in); String employeeName = sc.nextLine(); int employeeAge = sc.nextInt(); Employee employee = new Employee(employeeName, employeeAge); c.add(employee); } // 2、创建迭代器遍历集合 Iterator it; //3、遍历 while (it.hasnext) { //4、集合中对象未知,向下转型 Employee e = it.next(); System.out.println(e.getName() + "---" + e.getAge()); } } }
输入样例:
zs 10 ls 20 ww 30
输出样例:
zs---10 ls---20 ww---30
代码:
1 import java.util.ArrayList; 2 import java.util.Scanner; 3 import java.util.Collection; 4 import java.util.Iterator; 5 class Employee { 6 private String name; 7 private int age; 8 public Employee() { 9 super(); 10 } 11 public Employee(String name, int age) { 12 super(); 13 this.name = name; 14 this.age = age; 15 } 16 public String getName() { 17 return name; 18 } 19 public void setName(String name) { 20 this.name = name; 21 } 22 public int getAge() { 23 return age; 24 } 25 public void setAge(int age) { 26 this.age = age; 27 } 28 } 29 public class Main { 30 public static void main(String[] args) { 31 Collection c = new ArrayList(); 32 Scanner sc = new Scanner(System.in); 33 String employeeName = sc.nextLine(); 34 int employeeAge = sc.nextInt(); 35 for (int i = 0; i < 3; i++) { 36 Employee employee = new Employee(employeeName, employeeAge); 37 c.add(employee); 38 } 39 Iterator it=c.iterator(); 40 while (it.hasNext()) { 41 Employee e = (Employee)it.next(); 42 43 System.out.println(e.getName() + "---" + e.getAge()); 44 } 45 } 46 }View Code
6.电信计费系列3-短信计费
实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
1、接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。
2、如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。
输入格式:
输入信息包括两种类型
1、逐行输入南昌市手机用户开户的信息,每行一个用户。
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐 3-手机短信计费)
例如:u-13305862264 3
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题只针对类型3-手机短信计费。
2、逐行输入本月某些用户的短信信息,短信的格式:
m-主叫号码,接收号码,短信内容 (短信内容只能由数字、字母、空格、英文逗号、英文句号组成)
m-18907910010 13305862264 welcome to jiangxi.
m-13305862264 18907910010 thank you.
注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出格式:
根据输入的详细短信信息,计算所有已开户的用户的当月短信费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码、自己给自己打电话等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。
输入样例1:
u-18907910010 3 m-18907910010 13305862264 aaaaaaaaaaaaaaaaaaaaaaa end
输出样例1:
18907910010 0.3 99.7
输入样例2:
u-18907910010 3 m-18907910010 13305862264 aaaaaaaaaaaa m-18907910010 13305862264 aaaaaaa. m-18907910010 13305862264 bb,bbbb end
输出样例2:
18907910010 0.5 99.5
代码:
1 import java.util.ArrayList; 2 import java.util.Scanner; 3 import java.text.DecimalFormat; 4 import java.util.Comparator; 5 6 public class Main { 7 public static void main(String[] args) { 8 Scanner sc=new Scanner(System.in); 9 String mq=sc.nextLine(); 10 ArrayList<User> Users=new ArrayList<User>(); 11 DecimalFormat df = new DecimalFormat("0.00"); 12 User user; 13 Xiaoxi xiaoxi; 14 String nr; 15 String hm2; 16 while(!mq.equals("end")) { 17 18 if(mq.matches("u-1[0-9]{10} 3")) { 19 user=new User(); 20 user.number=mq.substring(2,13); 21 Users.add(user); 22 } 23 else if(mq.matches("m-1[0-9]{10} 1[0-9]{10} [a-z A-Z 0-9,.]+")) { 24 hm2=mq.substring(2,13); 25 for(User xd: Users) { 26 if(hm2.equals(xd.number)) { 27 xiaoxi=new Xiaoxi(); 28 xiaoxi.number1=mq.substring(2,13); 29 xiaoxi.number2=mq.substring(14,25); 30 nr=mq.substring(26); 31 xiaoxi.isneirong=nr; 32 if(Xiaoxi.isduanxin(nr)) { 33 for(User a:Users) { 34 if(a.number.equals(xiaoxi.number1)) 35 a.All.add(xiaoxi); 36 } 37 } 38 } 39 } 40 41 42 } 43 else 44 {} 45 mq=sc.nextLine(); 46 } 47 int sum=0; 48 for(User a:Users) { 49 for(Xiaoxi b:a.All) { 50 double n1=b.isneirong.length()/10.0; 51 int n2=(int) n1; 52 if(n1-n2>0) n2++; 53 sum+=n2; 54 } 55 if(sum>5) 56 a.buy+=0.7+(sum-5)*0.3; 57 else if(sum>3) 58 a.buy+=0.3+(sum-3)*0.2; 59 else 60 a.buy+=sum*0.1; 61 a.balance-=a.buy; 62 63 sum=0; 64 } 65 Users.sort(new Sort_length()); 66 for(User a:Users) { 67 System.out.println(a.number+" "+Double.valueOf(df.format(a.buy))+" "+Double.valueOf(df.format(a.balance))); 68 } 69 } 70 } 71 72 class Sort_length implements Comparator<User>{ 73 public int compare(User a,User b) { 74 return a.number.compareTo(b.number); 75 } 76 } 77 78 class Number{ 79 public static boolean isdianhua(String haoma) { 80 if(haoma.matches("u-1[0-9]{10} 3")) { 81 return true; 82 } 83 return false; 84 } 85 86 } 87 class Xiaoxi{ 88 public String isneirong; 89 String number1; 90 String number2; 91 92 public static boolean isduanxin(String xinxi) { 93 if(xinxi.matches("[0-9 a-z A-Z,.]+")) { 94 return true; 95 } 96 return false; 97 } 98 } 99 class User{ 100 String number; 101 double balance=100; 102 double buy=0; 103 ArrayList<Xiaoxi> All = new ArrayList<Xiaoxi>(); 104 105 }View Code
7.编写一个类Shop(商店)、内部类InnerCoupons(内部购物券)
编写一个类Shop
(商店),该类中有一个成员内部类InnerCoupons
(内部购物券),可以用于购买该商店的牛奶(假设每箱牛奶售价为50元)。要求如下:
(1)Shop类中有私有属性milkCount
(牛奶的箱数,int类型)、公有的成员方法setMilkCount( )
和getMilkCount( )
分别用于设置和获取牛奶的箱数。
(2)成员内部类InnerCoupons,有公有属性value
(面值,int类型),一个带参数的构造方法可以设定购物券的面值value,一个公有的成员方法buy( )
要求输出使用了面值为多少的购物券进行支付,同时使商店牛奶的箱数减少value/50。
(3)Shop类中还有成员变量coupons50
(面值为50元的内部购物券,类型为InnerCoupons)、coupons100
(面值为100元的内部购物券,类型为InnerCoupons)。
(4)在Shop类的构造方法中,调用内部类InnerCoupons的带参数的构造方法分别创建上面的购物券coupons50、coupons100。
在测试类Main
中,创建一个Shop类的对象myshop,从键盘输入一个整数(大于或等于3),将其设置为牛奶的箱数。假定有顾客分别使用了该商店面值为50的购物券、面值为100的购物券各消费一次,分别输出消费后商店剩下的牛奶箱数。
输入格式:
输入一个大于或等于3的整数。
输出格式:
使用了面值为50的购物券进行支付
牛奶还剩XX箱
使用了面值为100的购物券进行支付
牛奶还剩XX箱
输入样例:
5
输出样例:
使用了面值为50的购物券进行支付 牛奶还剩4箱 使用了面值为100的购物券进行支付 牛奶还剩2箱
代码:
1 import java.util.*; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner sc=new Scanner(System.in); 6 Shop myshop=new Shop(sc.nextInt()); 7 Shop.InnerCoupons coupons50=myshop.new InnerCoupons(50); 8 Shop.InnerCoupons coupons100=myshop.new InnerCoupons(100); 9 coupons50.buy(); 10 coupons100.buy(); 11 } 12 } 13 class Shop{ 14 static int milkCount; 15 InnerCoupons coupons50; 16 InnerCoupons coupons100; 17 public Shop(int milkCount) { 18 this.milkCount=milkCount; 19 } 20 21 public void setMilkCount(int milkCount) { 22 this.milkCount=milkCount; 23 } 24 public int getMilkCount() { 25 return milkCount; 26 } 27 public class InnerCoupons{ 28 public int value; 29 public InnerCoupons(int value){ 30 this.value=value; 31 } 32 33 public void buy(){ 34 Shop.this.milkCount=Shop.this.milkCount-value/50; 35 System.out.println("使用了面值为"+value+"的购物券进行支付"); 36 System.out.println("牛奶还剩"+Shop.this.milkCount+"箱"); 37 } 38 } 39 }View Code
8.动物发声模拟器(多态)
设计一个动物发生模拟器,用于模拟不同动物的叫声。比如狮吼、虎啸、狗旺旺、猫喵喵……。
定义抽象类Animal,包含两个抽象方法:获取动物类别getAnimalClass()、动物叫shout();
然后基于抽象类Animal定义狗类Dog、猫类Cat和山羊Goat,用getAnimalClass()方法返回不同的动物类别(比如猫,狗,山羊),用shout()方法分别输出不同的叫声(比如喵喵、汪汪、咩咩)。
最后编写AnimalShoutTest类测试,输出:
猫的叫声:喵喵
狗的叫声:汪汪
山羊的叫声:咩咩
其中,在AnimalShoutTestMain类中,用speak(Animal animal){}方法输出动物animal的叫声,在main()方法中调用speak()方法,分别输出猫、狗和山羊对象的叫声。
请在下面的【】处添加代码。
//动物发生模拟器. 请在下面的【】处添加代码。 public class AnimalShoutTest2 { public static void main(String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); Goat goat = new Goat(); speak(cat); speak(dog); speak(goat); } //定义静态方法speak() 【】 } //定义抽象类Animal 【】class Animal{ 【】 } //基于Animal类,定义猫类Cat,并重写两个抽象方法 class Cat 【】{ 【】 【】 } //基于Animal类,定义狗类Dog,并重写两个抽象方法 class Dog 【】{ 【】 【】 } //基于Animal类,定义山羊类Goat,并重写两个抽象方法 class Goat 【】{ 【】 【】 }
输入样例1:
输出样例1:
猫的叫声:喵喵 狗的叫声:汪汪 山羊的叫声:咩咩
代码:
1 //动物发生模拟器. 请在下面的【】处添加代码。 2 public class Main{ 3 public static void main(String[] args) { 4 Cat cat = new Cat(); 5 Dog dog = new Dog(); 6 Goat goat = new Goat(); 7 speak(cat); 8 speak(dog); 9 speak(goat); 10 } 11 //定义静态方法speak() 12 static void speak(Animal animal) { 13 animal.shout(); 14 } 15 } 16 17 //定义抽象类Animal 18 abstract class Animal{ 19 20 abstract String getAnimalClass(Animal animal); 21 22 abstract void shout(); 23 } 24 //基于Animal类,定义猫类Cat,并重写两个抽象方法 25 class Cat extends Animal{ 26 27 @Override 28 String getAnimalClass(Animal animal) { 29 30 return animal.getClass().getName(); 31 } 32 33 @Override 34 void shout() { 35 System.out.println("猫的叫声:喵喵"); 36 } 37 38 39 } 40 //基于Animal类,定义狗类Dog,并重写两个抽象方法 41 class Dog extends Animal{ 42 43 @Override 44 String getAnimalClass(Animal animal) { 45 46 return animal.getClass().getName(); 47 } 48 49 @Override 50 void shout() { 51 System.out.println("狗的叫声:汪汪"); 52 } 53 54 55 56 } 57 //基于Animal类,定义山羊类Goat,并重写两个抽象方法 58 class Goat extends Animal{ 59 60 @Override 61 String getAnimalClass(Animal animal) { 62 63 return animal.getClass().getName(); 64 } 65 66 @Override 67 void shout() { 68 System.out.println("山羊的叫声:咩咩"); 69 } 70 71 }View Code
三、采坑心得:
(1)第七次题目集中第二题,由于没有注意题中的要求,没有读懂题中可以相同图形可以有着多个,而且需要计算每个图形的面积,导致在调试代码的时候,测试点一直不通过,而且测试点的输出对应不上,浪费了很多时间,后来还是多次通过阅读题目来发现了问题。但输入多个图形其面积的储存又是一个问题,尝试了很多种方法都觉得不可行,最后想到去年C语言中动态数组的方法,虽然没有成功,但是自己联想到了一种其他的方法,通过使用数组然后用打标签的方法来实现了多个相同图形面积的储存。
(2)第八次题目集和第九次题目集中最难的点便是它的设计思路,需要巧妙,我自己设计的时候用了许多种方法,最后采用了类的数组来储存,将每个用户做为一个最大的单位,然后卡号、银行卡、密码、余额、存钱和取钱等等,思路的设计是最难的部分,而且各个类的接口需要设计的巧妙既不能相互干涉,又要达到预期的目的,对人的逻辑思维能力的要求比较高,一定要细心看完类图,然后用心的去设计相关的类的接口等等。
四、改进建议:
对相应题目的编码改进给出自己的见解,做到可持续改进
这几次的大作业相较之前的大作业来说整体难度有所下降,类的设计也基本都是按着题目给的类图来设计,大家的代码都大同小异。
感觉可以写一个工厂类,在里面进行判断,返回相应的类。
五、总结:
本次作业是学习java的最后一次大作业,主要巩固了类之间关系的知识,类之间的关系更加明确,也学会了如何根据功能设计类;还学会了一些接口和方法的使用,equals方法和comparable、comparator接口等,贴近实际的设计习题是一个很好的结尾,面向对象编程的基本知识也就此告一段落,不过编程之路还有很长的路要走,之后的还需要学习关于设计模式等知识来进一步改进自己的对象编程;总之,通过这三次习题,我巩固了类的基本使用知识,也知道了更多类设计的知识,让我能够更好的对实际中的开发有一定了解;之后的学习还道路遥远,学到这里java也仅仅才是入门,还需更加努力
标签:return,String,double,ArrayList,博客,EDUL,new,public,第三次 From: https://www.cnblogs.com/edul3/p/16953281.html