blog3
1)前言:这一次博客是针对该学期第六次到第七八次作业以及期中考试所做的总结。
随着课堂的不断深入,我们所学的知识呈现出了复杂化、多元化等一系列特点,这一方面最直观的感受便来自于定期的PTA题集训练.此三次的PTA题集的题量较上周期相比更少,但是难度却大幅度地增加了,知识考察的广度以及深度逐渐提高.经过此次题集的训练后,不难发现先前的题目考察面仅仅停留在JAVA语言编程的表面即简单的结构建立以及正确的语法使用,自此次题集开始则开始接触到了JAVA语言逐渐核心的部分即其编程思想以及恰当的逻辑结构.题目集4-6首先考察了根据所给类图正确的构建出相关的类以及函数,继而是提出了不同聚合设计方案对日期类进行代码的构建,接着一些正则表达式的基本语法以及使用问题,最后也是最核心的部分,为三种渐进式图形继承设计的思路与技术运用,即考察封装,继承,多态以及接口等.一系列的考察面对编程者的知识点理解以及运用,同时兼包括自学能力提出了更高的要求.
通过这次作业,我对Java的一些基本语法有了一些了解,对于面向对象的过程的思想有了一些掌握,但是还有美中不足的地方,以下是我的反思以及对这三次作业以及期中考试的理解。
(2)设计与分析
第六次作业
第一题
菜单计价5
本题在菜单计价程序-3的基础上增加了部分内容,增加的内容用加粗字体标识。
注意不是菜单计价程序-4,本题和菜单计价程序-4同属菜单计价程序-3的两个不同迭代分支。
设计点菜计价程序,根据输入的信息,计算并输出总价格。
输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。
菜单由一条或多条菜品记录组成,每条记录一行
每条菜品记录包含:菜名、基础价格 三个信息。
订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。
桌号标识独占一行,包含两个信息:桌号、时间。
桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。
点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。
不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。
删除记录格式:序号 delete
标识删除对应序号的那条点菜记录。
如果序号不对,输出"delete error"
代点菜信息包含:桌号 序号 菜品名称 口味度 份额 份数
代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。
程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。
每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。
折扣的计算方法(注:以下时间段均按闭区间计算):
周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。
周末全价,营业时间:9:30-21:30
如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"
参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。
Dish {
String name;//菜品名称
int unit_price; //单价
int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }
菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
Menu {
Dish[] dishs ;//菜品数组,保存所有菜品信息
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
Dish addDish(String dishName,int unit_price)//添加一道菜品信息
}
点菜记录类:保存订单上的一道菜品记录
Record {
int orderNum;//序号\\
Dish d;//菜品\\
int portion;//份额(1/2/3代表小/中/大份)\\
int getPrice()//计价,计算本条记录的价格\\
}
订单类:保存用户点的所有菜的信息。
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice()//计算订单的总价
Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。
delARecordByOrderNum(int orderNum)//根据序号删除一条记录
findRecordByNum(int orderNum)//根据序号查找一条记录
}
### 输入格式:
桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)
菜品记录格式:
菜名+英文空格+基础价格
如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。
点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
删除记录格式:序号 +英文空格+delete
代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数
最后一条记录以“end”结束。
### 输出格式:
按输入顺序输出每一桌的订单记录处理信息,包括:
1、桌号,格式:table+英文空格+桌号+”:”
2、按顺序输出当前这一桌每条订单记录的处理信息,
每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名
如果删除记录的序号不存在,则输出“delete error”
最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价
以上为菜单计价系列-3的题目要求,加粗的部分是有调整的内容。本次课题相比菜单计价系列-3新增要求如下:
1、菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+口味类型+英文空格+基础价格+"T"
例如:麻婆豆腐 川菜 9 T
菜价的计算方法:
周一至周五 7折, 周末全价。
特色菜的口味类型:川菜、晋菜、浙菜
川菜增加辣度值:辣度0-5级;对应辣度水平为:不辣、微辣、稍辣、辣、很辣、爆辣;
晋菜增加酸度值,酸度0-4级;对应酸度水平为:不酸、微酸、稍酸、酸、很酸;
浙菜增加甜度值,甜度0-3级;对应酸度水平为:不甜、微甜、稍甜、甜;
例如:麻婆豆腐 川菜 9 T
输入订单记录时如果是特色菜,添加口味度(辣/酸/甜度)值,格式为:序号+英文空格+菜名+英文空格+口味度值+英文空格+份额+英文空格+份数
例如:1 麻婆豆腐 4 1 9
单条信息在处理时,如果口味度超过正常范围,输出"spicy/acidity/sweetness num out of range : "+口味度值,spicy/acidity/sweetness(辣度/酸度/甜度)根据菜品类型择一输出,例如:
acidity num out of range : 5
输出一桌的信息时,按辣、酸、甜度的顺序依次输出本桌菜各种口味的口味度水平,如果没有某个类型的菜,对应的口味(辣/酸/甜)度不输出,只输出已点的菜的口味度。口味度水平由口味度平均值确定,口味度平均值只综合对应口味菜系的菜计算,不做所有菜的平均。比如,某桌菜点了3份川菜,辣度分别是1、3、5;还有4份晋菜,酸度分别是,1、1、2、2,辣度平均值为3、酸度平均值四舍五入为2,甜度没有,不输出。
一桌信息的输出格式:table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格+"川菜"+数量+辣度+英文空格+"晋菜"+数量+酸度+英文空格+"浙菜"+数量+甜度。
如果整桌菜没有特色菜,则只输出table的基本信息,格式如下,注意最后加一个英文空格:
table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格
例如:table 1: 60 36 川菜 2 爆辣 浙菜 1 微甜
计算口味度时要累计本桌各类菜系所有记录的口味度总和(每条记录的口味度乘以菜的份数),再除以对应菜系菜的总份数,最后四舍五入。
注:本题要考虑代点菜的情况,当前桌点的菜要加上被其他桌代点的菜综合计算口味度平均值。
2、考虑客户订多桌菜的情况,输入时桌号时,增加用户的信息:
格式:table+英文空格+桌号+英文空格+":"+英文空格+客户姓名+英文空格+手机号+日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)
例如:table 1 : tom 13670008181 2023/5/1 21/30/00
约束条件:客户姓名不超过10个字符,手机号11位,前三位必须是180、181、189、133、135、136其中之一。
输出结果时,先按要求输出每一桌的信息,最后按字母顺序依次输出每位客户需要支付的金额。不考虑各桌时间段的问题,同一个客户的所有table金额都要累加。
输出用户支付金额格式:
用户姓名+英文空格+手机号+英文空格+支付金额
注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价:
计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。
将所有记录的菜价累加得到整桌菜的价格。
输入格式:
桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)
菜品记录格式:
菜名+口味类型+英文空格+基础价格
如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。
点菜记录格式:序号+英文空格+菜名+英文空格+辣/酸/甜度值+英文空格+份额+英文空格+份数 注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。辣/酸/甜度取值范围见题目中说明。
删除记录格式:序号 +英文空格+delete
代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称**+英文空格+辣/酸/甜度值+**英文空格+份额+英文空格+分数
最后一条记录以“end”结束。
输出格式:
按输入顺序输出每一桌的订单记录处理信息,包括:
1、桌号,格式:table+英文空格+桌号+“:”+英文空格
2、按顺序输出当前这一桌每条订单记录的处理信息,
每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名
如果删除记录的序号不存在,则输出“delete error”
之后按输入顺序一次输出每一桌所有菜品的价格(整数数值),
格式:table+英文空格+桌号+“:”+英文空格+当前桌的计算折扣后总价+英文空格+辣度平均值+英文空格+酸度平均值+英文空格+甜度平均值+英文空格
最后按拼音顺序输出每位客户(不考虑客户同名或拼音相同的情况)的支付金额,格式: 用户姓名+英文空格+手机号+英文空格+支付总金额,按输入顺序排列。
输入样例1:
桌号时间超出营业范围。例如:
麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 21/30/00
1 麻婆豆腐 3 1 2
2 油淋生菜 2 1
3 麻婆豆腐 2 3 2
end
输出样例1:
在这里给出相应的输出。例如:
table 1 out of opening hours
输入样例2:
一种口味的菜品。例如:
麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 20/30/00
1 麻婆豆腐 2 1 2
2 油淋生菜 2 1
3 麻婆豆腐 2 3 2
end
输出样例2:
在这里给出相应的输出。例如:
table 1:
1 麻婆豆腐 24
2 油淋生菜 14
3 麻婆豆腐 48
table 1: 86 62 川菜 4 稍辣
tom 13605054400 62
输入样例3:
辣度值超出范围。例如:
麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 18/30/00
1 麻婆豆腐 6 1 2
2 油淋生菜 1 1
3 麻婆豆腐 5 3 2
end
输出样例3:
在这里给出相应的输出。例如:
table 1:
spicy num out of range :6
2 油淋生菜 9
3 麻婆豆腐 48
table 1: 57 41 川菜 2 爆辣
tom 13605054400 41
输入样例4:
同一用户对应多桌菜。例如:
麻婆豆腐 川菜 12 T
油淋生菜 9
麻辣鸡丝 10
table 1 : tom 13605054400 2023/5/1 18/30/00
1 麻婆豆腐 1 1 2
2 油淋生菜 1 1
3 麻婆豆腐 2 2 2
table 2 : tom 13605054400 2023/5/6 18/30/00
1 麻婆豆腐 2 1 2
2 麻辣鸡丝 2 2
3 麻婆豆腐 2 1 1
end
输出样例4:
在这里给出相应的输出。例如:
table 1:
1 麻婆豆腐 24
2 油淋生菜 9
3 麻婆豆腐 36
table 2:
1 麻婆豆腐 24
2 麻辣鸡丝 30
3 麻婆豆腐 12
table 1: 69 49 川菜 4 稍辣
table 2: 66 66 川菜 3 稍辣
tom 13605054400 115
输入样例5:
多用户多桌菜。例如:
东坡肉 浙菜 25 T
油淋生菜 9
蜜汁灌藕 浙菜 10 T
刀削面 晋菜 10 T
醋浇羊肉 晋菜 30 T
麻婆豆腐 川菜 12 T
麻辣鸡丝 川菜 15 T
table 1 : tom 13605054400 2023/5/6 12/30/00
1 醋浇羊肉 4 1 1
3 刀削面 1 1 3
2 东坡肉 3 2 1
4 麻辣鸡丝 2 1 1
table 2 : jerry 18100334566 2023/5/1 12/30/00
1 醋浇羊肉 1 1 2
3 麻婆豆腐 2 2 1
4 麻辣鸡丝 2 3 3
table 3 : jerry 18100334566 2023/5/1 12/30/00
1 醋浇羊肉 2 1 1
3 蜜汁灌藕 1 1 2
2 东坡肉 2 2 1
4 麻辣鸡丝 5 1 1
end
输出样例5:
在这里给出相应的输出。例如:
table 1:
1 醋浇羊肉 30
3 刀削面 30
2 东坡肉 38
4 麻辣鸡丝 15
table 2:
1 醋浇羊肉 60
3 麻婆豆腐 18
4 麻辣鸡丝 90
table 3:
1 醋浇羊肉 30
3 蜜汁灌藕 20
2 东坡肉 38
4 麻辣鸡丝 15
table 1: 113 113 川菜 1 稍辣 晋菜 4 稍酸 浙菜 1 甜
table 2: 168 118 川菜 4 稍辣 晋菜 2 微酸
table 3: 103 73 川菜 1 爆辣 晋菜 1 稍酸 浙菜 3 微甜
jerry 18100334566 191
tom 13605054400 113
输入样例6:
多用户多桌菜含代点菜。例如:
东坡肉 浙菜 25 T
油淋生菜 9
蜜汁灌藕 浙菜 10 T
刀削面 晋菜 10 T
醋浇羊肉 晋菜 30 T
麻婆豆腐 川菜 12 T
麻辣鸡丝 川菜 15 T
table 1 : tom 13605054400 2023/5/6 12/30/00
1 醋浇羊肉 4 1 1
3 刀削面 1 1 3
2 东坡肉 3 2 1
4 麻辣鸡丝 2 1 1
table 2 : jerry 18100334566 2023/5/1 12/30/00
1 1 醋浇羊肉 0 1 2
3 麻婆豆腐 2 2 1
4 麻辣鸡丝 2 3 3
table 3 : lucy 18957348763 2023/5/1 12/30/00
1 醋浇羊肉 2 1 1
3 蜜汁灌藕 1 1 2
2 东坡肉 2 2 1
4 麻辣鸡丝 5 1 1
end
输出样例6:
在这里给出相应的输出。例如:
table 1:
1 醋浇羊肉 30
3 刀削面 30
2 东坡肉 38
4 麻辣鸡丝 15
table 2:
1 table 2 pay for table 1 60
3 麻婆豆腐 18
4 麻辣鸡丝 90
table 3:
1 醋浇羊肉 30
3 蜜汁灌藕 20
2 东坡肉 38
4 麻辣鸡丝 15
table 1: 113 113 川菜 1 稍辣 晋菜 6 微酸 浙菜 1 甜
table 2: 168 118 川菜 4 稍辣
table 3: 103 73 川菜 1 爆辣 晋菜 1 稍酸 浙菜 3 微甜
jerry 18100334566 118
lucy 18957348763 73
tom 13605054400 113
输入样例7:
错误的菜品记录和桌号记录,用户丢弃。例如:
东坡肉 25 T
油淋生菜 9
table 1 : tom 136050540 2023/5/1 12/30/00
2 东坡肉 3 2 1
end
输出样例7:
在这里给出相应的输出。例如:
wrong format wrong format
代码如下
import java.text.ParseException; import java.time.LocalDate; import java.util.Calendar; import java.util.Scanner; //import java.util.Date; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); Menu menu = new Menu(); Dish dish; Table CURRENTTABLE; Table[] table = new Table[100]; User[] users = new User[100]; int TABLECOUNT = 0; int USERCOUNT = 0; String line = in.nextLine(); while (!line.equals("end")) { String[] s = line.split(" "); int l = s.length; if (line.matches("[\\S]* [1-9][\\d]*")){//非特色菜 dish = new Dish(); dish.name = s[0]; dish.PRICE = Integer.parseInt(s[1]); menu.add(dish); } else if(line.matches("[\\S]* [\\S]* [1-9][\\d]* T"))//特色菜 { dish=new Dish(); dish.name = s[0]; dish.typeName=s[1]; dish.PRICE = Integer.parseInt(s[2]); dish.isT=true; if(dish.typeName.equals("川菜")) dish.MAXDEGREE=5; else if(dish.typeName.equals("晋菜")) dish.MAXDEGREE=4; else if(dish.typeName.equals("浙菜")) dish.MAXDEGREE=3; menu.add(dish); } else if(s[0].charAt(0)=='t') { break; } else { System.out.println("wrong format"); } line = in.nextLine(); } while (!line.equals("end")) { boolean f1=false; String[] s = line.split(" "); if(line.matches("table.*")) { String name=s[3]; String number=s[4]; if(name.length()>10) { // System.out.println("wrong format"); CURRENTTABLE = new Table(); CURRENTTABLE.count=false; table[++TABLECOUNT] = CURRENTTABLE; } else if(number.length()!=11) { // System.out.println("wrong format"); CURRENTTABLE = new Table(); CURRENTTABLE.count=false; table[++TABLECOUNT] = CURRENTTABLE; } else if(number.indexOf("180")!=0&&number.indexOf("181")!=0&&number.indexOf("189")!=0&&number.indexOf("133")!=0&&number.indexOf("135")!=0&&number.indexOf("136")!=0) { // System.out.println("wrong format"); CURRENTTABLE = new Table(); CURRENTTABLE.count=false; table[++TABLECOUNT] = CURRENTTABLE; } else { int i; boolean FINDUSER=false; for(i=1;i<=USERCOUNT;i++) if(users[i].number.equals(number)) { CURRENTTABLE = new Table(Integer.parseInt(s[1]), s[5], s[6], menu); table[++TABLECOUNT] = CURRENTTABLE; users[i].addTable(CURRENTTABLE); FINDUSER=true; break; } if(!FINDUSER) { CURRENTTABLE = new Table(Integer.parseInt(s[1]), s[5], s[6], menu); table[++TABLECOUNT] = CURRENTTABLE; User currentUser=new User(name,number); users[++USERCOUNT]=currentUser; users[USERCOUNT].addTable(CURRENTTABLE); } f1=true; } line = in.nextLine(); String[] s2 = line.split(" "); if (s2[0].charAt(0) != 't' && !s2[0].equals("end"))//输入该桌子的菜 { while (true) { String[] s3 = line.split(" "); if (s3[0].equals("end")||s3[0].charAt(0)=='t') { break; } if (s3.length == 2 && s3[1].equals("delete")&&s3[0].charAt(0)>='1'&&s3[0].charAt(0)<='9'&&f1) { //删除点菜记录 boolean SUCCESS=table[TABLECOUNT].TABLEORDER.delARecordByOrderNum(Integer.parseInt(s3[0])); table[TABLECOUNT].TABLEORDER.addARecord(Integer.parseInt(s3[0]),SUCCESS); } else if(s3.length==5&&line.matches("[1-9][\\d]* [\\S]* [\\d] [1-9]\\d* [\\d]")&&f1)//本桌点特色菜 { //System.out.println("特色"); //改一下记录里面对特色菜的存储 if (s3[0].charAt(0) <= '9' && s3[0].charAt(0) >= '1' &&f1) { int SNO = Integer.parseInt(s3[0]); String dishName = s3[1]; int degree = Integer.parseInt(s3[2]); int PORTION = Integer.parseInt(s3[3]); int orderNum = Integer.parseInt(s3[4]); /* if (s3[2].length()!= 1 || s3[3].charAt(0) <= '0' || s3[3].charAt(0) > '9') { table[TABLECOUNT].ORDERWRONG = true; }*/ table[TABLECOUNT].TABLEORDER.addARecord(SNO, dishName,degree,PORTION, orderNum); } } else if (line.matches("[1-9][\\d]* [\\S]* [\\d] [1-9][\\d]*")&&f1) //本桌点普通菜 { //System.out.println("非特色"); if (s3[0].charAt(0) <= '9' && s3[0].charAt(0) >= '1' && f1) { //向该桌的order对象存菜 int SNO = Integer.parseInt(s3[0]); String dishName = s3[1]; int PORTION = Integer.parseInt(s3[2]); int orderNum = Integer.parseInt(s3[3]); if (s3[2].length() != 1 || s3[3].charAt(0) <= '0' || s3[3].charAt(0) > '9') { table[TABLECOUNT].ORDERWRONG = true; } table[TABLECOUNT].TABLEORDER.addARecord(SNO, dishName, PORTION, orderNum); }/* else if (s3[0].charAt(0) < '0' || s3[0].charAt(0) > '9' && !f1) { boolean mixDish = true; table[TABLECOUNT].TABLEORDER.addARecord(mixDish); } else if (s3[0].charAt(0) == '0' || s3[0].charAt(0) > '9' && !f1) table[TABLECOUNT].TABLEORDER.addWrongFormatRecord(true);*/ } else if(line.matches("[1-9][\\d]* [1-9][\\d]* [\\S]* [\\d] [1-9][\\d]* [\\d]")&&f1)//代点菜 { if(s3.length==5) { // System.out.println("代点普通菜"); int toTable = Integer.parseInt(s3[0]); int SNO = Integer.parseInt(s3[1]); String dishName = s3[2]; int PORTION = Integer.parseInt(s3[3]); int orderNum = Integer.parseInt(s3[4]); boolean toSUCCESS=false ; for (int i = 1; i <= TABLECOUNT; i++) { if (table[i].TABLESNO == toTable) { toSUCCESS = true; break; } } table[TABLECOUNT].TABLEORDER.addARecord(toSUCCESS, toTable, SNO, dishName, PORTION, orderNum); } else if(s3.length==6) { // System.out.println("代点特色菜"); int toTable = Integer.parseInt(s3[0]); int SNO = Integer.parseInt(s3[1]); String dishName = s3[2]; int degree = Integer.parseInt(s3[3]); int PORTION = Integer.parseInt(s3[4]); int orderNum = Integer.parseInt(s3[5]); boolean toSUCCESS; toSUCCESS = false; for (int i = 1; i <= TABLECOUNT; i++) { if (table[i].TABLESNO == toTable) { toSUCCESS = true; table[i].beSent(menu.searthDish(dishName).typeName,degree, orderNum); break; } } table[TABLECOUNT].TABLEORDER.addARecord(toSUCCESS, toTable, SNO, dishName, PORTION, orderNum); } } line=in.nextLine(); } } } } // System.out.println(TABLECOUNT); int i,j; for( i = 1; i <=TABLECOUNT; i++) { table[i].show(); } for( i = 1; i <=TABLECOUNT; i++) { table[i].showSum(); } // jerry 18100334566 118 for(i=1; i <= USERCOUNT; i++) { User min ; for(j=i+1;j<=USERCOUNT;j++) { if(users[i].name.compareToIgnoreCase(users[j].name)>0) { min=users[j]; users[j]=users[i]; users[i]=min; } } } //\*\* does not exist for( i = 1; i <=USERCOUNT; i++){ if(users[i].checkTable()) System.out.println(users[i].name+" "+users[i].number+" "+users[i].getCost()); } } } class checkTime { static int[] ms1={0,31,28,31,30,31,30,31,31,30,31,30,31}; static int[] ms2={0,31,29,31,30,31,30,31,31,30,31,30,31}; static boolean checkDateformat1(String y) { String[] s=y.split("/"); return s.length == 3 && s[0].length() == 4 && s[1].length() <= 2 && s[2].length() <= 2; } static boolean checkDateformat2(String y) { String[] s=y.split("/"); return s.length == 3 && s[0].length() <= 2 && s[1].length() <= 2 && s[2].length() <= 2; } private static final String dateFormatter = "yyyy/MM/dd"; static boolean checkDateError(String dateStr) { String[] dayArray = dateStr.split("/"); int y=Integer.parseInt(dayArray[0]); int m=Integer.parseInt(dayArray[1]); int d=Integer.parseInt(dayArray[2]); if(y%400==0||(y%4==0&&y%100!=0)) { if (d > ms2[m]) return false; } else if(d>ms1[m]) return false; return true; } private static final String dateFormatter2 = "hh/mm/ss"; /*static boolean checkDateError2(String dateStr) { final DateFormat sdf = new SimpleDateFormat(dateFormatter2); //这种情况下java不会把你输入的日期进行计算,比如54个月那么就是不合法的日期了,直接异常 sdf.setLenient(false); try { sdf.parse(dateStr); } catch (ParseException e) { e.printStackTrace(); return false; } return true; }*/ static LocalDate date1 = LocalDate.of(2022,1,1),date2=LocalDate.of(2023,12,31); static boolean checkTimeValid(String time) { String[] dayArray = time.split("/"); LocalDate date3 = LocalDate.of(Integer.parseInt(dayArray[0]),Integer.parseInt(dayArray[1]),Integer.parseInt(dayArray[2])); if(date3.isBefore(date1)||date3.isAfter(date2)) return false; else return true; } } //菜品类:对应菜谱上一道菜的信息。 class User { String name; String number; Table[] table = new Table[100]; int tableCnt=0; User(String name, String number) { this.name=name; this.number=number; } void addTable(Table table) { this.table[++tableCnt] = table; } int getCost() { int cost=0; int i; for(i=1;i<=tableCnt;i++) cost+=this.table[i].sumF; return cost; } boolean checkTable() { int i; for(i=1;i<=tableCnt;i++) if(this.table[i].f!=0&&this.table[i].count) return true; return false; } } class Table { int TABLESNO; int maxOrderSNO=0;//遍历时使用 String useDay,useTimeOfDay; Order TABLEORDER; Calendar weekendBegin,weekendEnd; Calendar normalDayBegin,normalDayEnd,normalNightBegin,normalNightEnd; int weekDay; Calendar now; void beSent(String typeName,int degree,int orderNum) { if(typeName.equals("川菜")) { degreeOfC+=degree*orderNum; cntOfC+=orderNum; } else if(typeName.equals("晋菜")) { degreeOfJ+=degree*orderNum; cntOfJ+=orderNum; } else if(typeName.equals("浙菜")) { degreeOfZ+=degree*orderNum; cntOfZ+=orderNum; } } Table(int tableNum,String useDay,String useTimeOfDay,Menu menu) { this.TABLESNO =tableNum; this.useDay=useDay; this.useTimeOfDay=useTimeOfDay; this.TABLEORDER=new Order(menu); this.weekDay=setWeek( useDay); // System.out.println(weekDay); this.now=setTimeCalendar(useTimeOfDay); this.weekendBegin=setTimeCalendar("9/30/0"); this.weekendEnd=setTimeCalendar("21/00/00"); this.normalDayBegin=setTimeCalendar("10/30/00"); this.normalDayEnd=setTimeCalendar("14/30/00"); this.normalNightBegin=setTimeCalendar("17/00/00"); this.normalNightEnd=setTimeCalendar("20/30/00"); } Table() { this.FF=false; } private Calendar setTimeCalendar(String useTimeOfDay) { String[] arr = useTimeOfDay.split("/"); Calendar cal = Calendar.getInstance(); cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(arr[0])); cal.set(Calendar.MINUTE, Integer.parseInt(arr[1])); cal.set(Calendar.SECOND, Integer.parseInt(arr[2])); return cal; } private int setWeek(String useDay) { String[] dayArray = useDay.split("/"); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.DAY_OF_MONTH, 32); calendar.set(Integer.parseInt(dayArray[0]), Integer.parseInt(dayArray[1])-1, Integer.parseInt(dayArray[2])); int weekDay = calendar.get(Calendar.DAY_OF_WEEK) - 1; return weekDay; } private int checkTime(boolean T) { //System.out.println("+"+weekDay); if (weekDay == 6 || weekDay == 0) { if (!now.before(this.weekendBegin) && !now.after(this.weekendEnd)) { return 10; } } else { if (!now.before(this.normalNightBegin) && !now.after(this.normalNightEnd)) { if(!T) return 8; return 7; } else if (!now.before(this.normalDayBegin) && !now.after(this.normalDayEnd)) { if(!T) return 6; return 7; } } // 表示不营业 FF=false; return 0; } boolean ORDERWRONG=false;//如果该卓存在点菜是输入格式错误,则直接输入 w r,不遍历其记录 int maxRecordSNO=0; int sumO=0,sumF=0; void GETEVERYRECORDPRICE()// 计算订单的总价 { int i; for(i=0;i<TABLEORDER.cnt2;i++) { if(TABLEORDER.records[i].mixDish==false&&TABLEORDER.records[i].wf==false) { if (TABLEORDER.records[i].d != null) { if ( TABLEORDER.records[i].deleted == false) { if (TABLEORDER.records[i].checkRecord()) { if (!TABLEORDER.records[i].toSUCCESS) { maxRecordSNO = TABLEORDER.records[i].SNO; float f = checkTime(TABLEORDER.records[i].tOfDish); if (f == 0) { return; } else { if (TABLEORDER.records[i].checkRecord()) { System.out.println(TABLEORDER.records[i].SNO + " " + TABLEORDER.records[i].dishName + " " + (int) (1.0 * TABLEORDER.records[i].getPRICE())); this.sumO += TABLEORDER.records[i].getPRICE(); this.sumF += (int) (1.0 * TABLEORDER.records[i].getPRICE() * f / 10 + 0.5); if (TABLEORDER.records[i].d.isT) { if (TABLEORDER.records[i].d.typeName.equals("川菜")) { degreeOfC += TABLEORDER.records[i].degreeOfDish * TABLEORDER.records[i].orderNum; cntOfC += TABLEORDER.records[i].orderNum; timeOfC++; } else if (TABLEORDER.records[i].d.typeName.equals("晋菜")) { degreeOfJ += TABLEORDER.records[i].degreeOfDish * TABLEORDER.records[i].orderNum; cntOfJ += TABLEORDER.records[i].orderNum; timeOfJ++; } else if (TABLEORDER.records[i].d.typeName.equals("浙菜")) { degreeOfZ += TABLEORDER.records[i].degreeOfDish * TABLEORDER.records[i].orderNum; cntOfZ += TABLEORDER.records[i].orderNum; timeOfZ++; } } } } } else { //1 table 2 pay for table 1 60 System.out.println(TABLEORDER.records[i].SNO + " table "+TABLESNO+" pay for table "+TABLEORDER.records[i].toTable+" "+ (int) (1.0 * TABLEORDER.records[i].getPRICE())); this.sumO += TABLEORDER.records[i].getPRICE(); this.sumF += (int) (1.0 * TABLEORDER.records[i].getPRICE() * checkTime(TABLEORDER.records[i].tOfDish) / 10 + 0.5); } } } else { float f = checkTime(TABLEORDER.records[i].tOfDish); // System.out.println(TABLEORDER.records[i].tOfDish); if (f == 0) { System.out.println("table " + TABLESNO + " out of opening hours"); return; } //System.out.println("f2"+f); TABLEORDER.deleteRecord[TABLEORDER.records[i].DELETESNO] = true; System.out.println(TABLEORDER.records[i].SNO + " " + TABLEORDER.records[i].dishName + " " + (int) (1.0 * TABLEORDER.records[i].getPRICE())); } } else { if(TABLEORDER.records[i].DELETESNO!=0) { if (TABLEORDER.records[i].SUCCESS) { if (TABLEORDER.deleteRecord[TABLEORDER.records[i].DELETESNO] == false) { TABLEORDER.deleteRecord[TABLEORDER.records[i].DELETESNO] = true; } /*else { System.out.println("deduplication " + TABLEORDER.records[i].DELETESNO); }*/ } else System.out.println("delete error"); } else { System.out.println(TABLEORDER.records[i].dishName+" does not exist");//case 30+ } } } else { /* if(TABLEORDER.records[i].mixDish==true) System.out.println("invalid dish"); else*/ System.out.println("wrong format"); } } } boolean count=true; int which=0; Table(boolean count,int which) { this.count=false; this.which=which; } float f=0; void show() { if(!ORDERWRONG&&count) { f = checkTime(TABLEORDER.records[0].tOfDish); if(f!=0) System.out.println("table " + TABLESNO + ": "); else System.out.println("table " + TABLESNO + " out of opening hours"); GETEVERYRECORDPRICE(); } else { System.out.println("wrong format"); } } boolean FF=true; int cntOfC=0,cntOfJ=0,cntOfZ=0; int timeOfC=0,timeOfJ=0,timeOfZ=0; int degreeOfC=0,degreeOfJ=0,degreeOfZ=0;//计算在GETEVERYRECORDPRICE()里计算。 String getChuanValue(int degreeOfC) { if(cntOfC==0) return ""; else { //不辣、微辣、稍辣、辣、很辣、爆辣 degreeOfC=(int)(1.0*degreeOfC/cntOfC+0.5); String answer=" 川菜 "+cntOfC; switch (degreeOfC) { case 0: answer+=" 不辣";break; case 1: answer+=" 微辣";break; case 2: answer+=" 稍辣";break; case 3: answer+=" 辣";break; case 4: answer+=" 很辣";break; case 5: answer+=" 爆辣";break; } return answer; } } String getJinValue(int degreeOfJ) { if(cntOfJ==0) return ""; else { //不酸、微酸、稍酸、酸、很酸 // System.out.println(degreeOfJ+" "+timeOfJ); degreeOfJ=(int)(1.0*degreeOfJ/cntOfJ+0.5); // System.out.println(degreeOfJ+""); String answer=" 晋菜 "+cntOfJ; switch (degreeOfJ) { case 0: answer+=" 不酸";break; case 1: answer+=" 微酸";break; case 2: answer+=" 稍酸";break; case 3: answer+=" 酸";break; case 4: answer+=" 很酸";break; } return answer; } } String getZheValue(int degreeOfZ) { if(cntOfZ==0) return ""; else { //不甜、微甜、稍甜、甜 // System.out.println("tian: " +degreeOfZ+" "+timeOfZ ); degreeOfZ=(int)(1.0*degreeOfZ/cntOfZ+0.5); // System.out.println("tian: " + degreeOfZ); String answer=" 浙菜 "+cntOfZ; switch (degreeOfZ) { case 0: answer+=" 不甜";break; case 1: answer+=" 微甜";break; case 2: answer+=" 稍甜";break; case 3: answer+=" 甜";break; } return answer; } } void showSum() { if(FF) System.out.println("table " + TABLESNO + ": "+this.sumO+" "+this.sumF+getChuanValue(degreeOfC)+getJinValue(degreeOfJ)+getZheValue(degreeOfZ));//case 9 } } class Dish { String name;// 菜品名称 int PRICE; // 单价 boolean isT=false; String typeName; Dish(String name,int PRICE) { this.name=name; this.PRICE=PRICE; } int MAXDEGREE=0; Dish(String name,int PRICE,boolean T) { this.name=name; this.PRICE=PRICE; this.isT=T; } public Dish() { } boolean checkPORTION(int PORTION) { if(PORTION==1||PORTION==2||PORTION==3) { return true; } else return false; } float getPRICE(int PORTION)// 计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) { float[] bl = {1,1.5f,2}; return PRICE*bl[PORTION-1]; } } //菜谱类:对应菜谱,包含饭店提供的所有菜的信息。 class Menu { public Dish[] dish=new Dish[1000];// 菜品数组,保存所有菜品信息 static int cnt=0; public void add(Dish dish)//菜单加一道菜 { this.dish[cnt]=dish; cnt++; } Dish searthDish(String dishName)// 根据菜名在菜谱中查找菜品信息,返回Dish对象。 { Dish find=null; for(int i=cnt-1;i>=0;i--) { if(dishName.equals(dish[i].name)) { find=dish[i];//返回最新的 break; } } return find; } } //点菜记录类:保存订单上的一道菜品记录 class Record {//实际上应该设计一个父类为操作类,然后点菜和删除,为其子类。 int SNO; boolean daiDian=false; Dish d;// 菜品 int degreeOfDish=0; public Record(int SNO,Dish d,int degree,int PORTION,int orderNum,String dishName)throws ParseException { this.SNO=SNO; this.d=d;//如果d记录为null则说明菜不存在 this.degreeOfDish=degree; if(d!=null) this.tOfDish=d.isT; this.PORTION=PORTION;// this.orderNum=orderNum;// this.dishName=dishName; } int PORTION;// 份额(1/2/3代表小/中/大份) int orderNum; boolean deleted=false; String dishName; boolean tOfDish=false; public Record(int SNO,Dish d,int PORTION,int orderNum,String dishName) throws ParseException { this.SNO=SNO; this.d=d;//如果d记录为null则说明菜不存在 if(d!=null) this.tOfDish=d.isT; this.PORTION=PORTION;// this.orderNum=orderNum;// this.dishName=dishName; } boolean toSUCCESS=false; int toTable=0; public Record(boolean toSUCCESS,int toTable,int SNO,Dish d,int PORTION,int orderNum,String dishName)throws ParseException { if (toSUCCESS) this.toSUCCESS = true; else this.toSUCCESS = false; this.toTable=toTable; this.SNO=SNO; this.d=d;//如果d记录为null则说明菜不存在 if(d!=null) this.tOfDish=d.isT; this.PORTION=PORTION;// this.orderNum=orderNum;// this.dishName= dishName; } // boolean mixDish=false; boolean wf=false; public Record(boolean mixDish,boolean wf) { this.mixDish=mixDish; this.wf=wf; } // int DELETESNO=0; boolean SUCCESS=false; public Record(int DELETESNO,boolean SUCCESS) { this.DELETESNO=DELETESNO; this.SUCCESS=SUCCESS; } boolean checkRecord() { // if(this.d==null) { // System.out.println(dishName+" does not exist"); // return false; // } // if(!this.d.checkPORTION(PORTION)) // { // System.out.println(SNO+" PORTION out of range "+PORTION); // return false; // } // if (orderNum<0||orderNum>15) // { // System.out.println(SNO+" num out of range "+orderNum); // return false; // } // if(toSUCCESS==false&&toTable!=0) // { // System.out.println("Table number :"+toTable+" does not exist"); // return false; // } if(d.isT) { if (d.typeName.equals("川菜")) { if (degreeOfDish < 0 || degreeOfDish > 5) { System.out.println("spicy num out of range :" + degreeOfDish); return false; } } if (d.typeName.equals("晋菜")) { if (degreeOfDish < 0 || degreeOfDish > 4) { System.out.println("acidity num out of range :" + degreeOfDish); return false; } } if (d.typeName.equals("浙菜")) { if (degreeOfDish < 0 || degreeOfDish > 3) { System.out.println("sweetness num out of range :" + degreeOfDish); return false; } } } return true; } int PRICE=0; float getPRICE()// 计价,计算本条记录的价格 { this.PRICE= ((int)(d.getPRICE(PORTION)+0.5))*orderNum; //System.out.println("+"+PRICE); return PRICE; } } //订单类:保存用户点的所有菜的信息。 class Order { Record[] records=new Record[1000000];// 保存订单上每一道的记录 boolean [] deleteRecord=new boolean[10000]; Menu menu; int cnt2=0; public Order(Menu menu) { this.menu=menu; } //根据菜名点菜 void addARecord( int SNO, String dishName, int PORTION, int orderNum)//点菜记录 { Record r; try { r = new Record(SNO,menu.searthDish(dishName),PORTION,orderNum,dishName); } catch (ParseException e) { throw new RuntimeException(e); } records[cnt2++]=r; } void addARecord( int SNO, String dishName,int degree, int PORTION, int orderNum) { Record r; try { r = new Record(SNO,menu.searthDish(dishName),degree,PORTION,orderNum,dishName); } catch (ParseException e) { throw new RuntimeException(e); } records[cnt2++]=r; } void addARecord(boolean toSUCCESS,int toTable,int SNO,String dishName,int PORTION,int orderNum) { Record r; try { r = new Record(toSUCCESS,toTable,SNO,menu.searthDish(dishName),PORTION,orderNum,dishName); } catch (ParseException e) { throw new RuntimeException(e); } records[cnt2++]=r; } void addARecord( int DELETESNO,boolean SUCCESS)//删除记录 { records[cnt2++]=new Record(DELETESNO,SUCCESS);; } void addARecord(boolean mixDish)//添加菜谱混乱记录 { records[cnt2++]=new Record(mixDish,false); } void addWrongFormatRecord(boolean wF) { records[cnt2++]=new Record(false,true); } boolean delARecordByOrderNum(int SNO)//根据序号删除一条记录 { int i; for(i=0;i<cnt2;i++) { if(records[i].SNO==SNO) { records[i].deleted = true; return true; } } return false; } }
(1)相比于菜单计价程序4来说难度还降低了一些,但是增加了一些口味度,如辣,微辣等,还分为了浙菜、川菜、晋菜等,需要在菜单计价程序3上进行一定程度上的修改,修改判断条件即可。
(2)合理使用循环和条件语句。用户可以连续点餐或者多次修改订单,因此需要使用循环来处理多次输入。同时,需要根据用户的选择执行不同的操作,因此需要使用条件语句来实现分支逻辑。
第八次作业
7-1 容器-ArrayList-排序
题目描述
编辑
输入多个学生的成绩信息,包括:学号、姓名、数学成绩、物理成绩。
学号是每个学生的唯一识别号,互不相同。
姓名可能会存在重复。
要求:使用ArrayList存储学生信息。
输入格式:
输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+数学成绩+英文空格+物理成绩
以“end”为输入结束标志
输出格式:
按数学/物理成绩之和从高到低的顺序输出所有学生信息,每个学生信息的输出格式:学号+英文空格+姓名+英文空格+数学/物理成绩之和
成绩相同的情况,按输入的先后顺序输出。
输入样例:
在这里给出一组输入。例如:
20201124 张少军 83 75
20201136 李四 78 86
20201118 郑觉先 80 62
end
输出样例:
在这里给出相应的输出。例如:
20201136 李四 164
20201124 张少军 158
20201118 郑觉先 142
以下为源代码
import java.util.*; public class Main { public static void main(String[] args) { Scanner READERA = new Scanner(System.in); List<Student> students = new ArrayList<>(); while (READERA.hasNextLine()) { String SHILINEA = READERA.nextLine().trim(); if ("end".equals(SHILINEA)) { break; } else { String[] INFOES = SHILINEA.split("\\s+"); Student student = new Student(INFOES[0], INFOES[1], Integer.parseInt(INFOES[2]), Integer.parseInt(INFOES[3])); students.add(student); } } Collections.sort(students, (a, b) -> { int ABSUM = a.MATHEMATICS + a.PHYSICS; int BBSUM = b.MATHEMATICS + b.PHYSICS; if (ABSUM != BBSUM) { return BBSUM - ABSUM; } else { return students.indexOf(a) - students.indexOf(b); } }); for (Student student : students) { System.out.println(String.format("%s %s %d", student.NUMBER, student.NAME, student.MATHEMATICS + student.PHYSICS)); } } static class Student { String NUMBER; String NAME; int MATHEMATICS; int PHYSICS; public Student(String NUMBER, String NAME, int MATHEMATICS, int PHYSICS) { this.NUMBER = NUMBER; this.NAME = NAME; this.MATHEMATICS = MATHEMATICS; this.PHYSICS = PHYSICS; } } }
课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,
要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。
完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。
题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。
某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
实验的总成绩等于课程每次实验成绩乘以权重后累加而得。
课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。
1、输入:
包括课程、课程成绩两类信息。
课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。
考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重
考察课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重
实验次数至少4次,不超过9次
课程性质输入项:必修、选修、实验
考核方式输入选项:考试、考察、实验
考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩
考试/考查课程成绩信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩
实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致}
实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩
以上信息的相关约束:
1)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】
2)学号由8位数字组成
3)姓名不超过10个字符
4)课程名称不超过10个字符
5)不特别输入班级信息,班级号是学号的前6位。
2、输出:
输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。
为避免四舍五入误差,
计算单个成绩时,分项成绩乘以权重后要保留小数位,计算总成绩时,累加所有分项成绩的权重分以后,再去掉小数位。
学生总成绩/整个班/课程平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。
1)学生课程总成绩平均分按学号由低到高排序输出
格式:学号+英文空格+姓名+英文空格+总成绩平均分
如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams"
2)单门课程成绩按课程名称的字符顺序输出
课程成绩输出格式:课程名称+英文空格+总成绩平均分
如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet"
3)班级所有课程总成绩平均分按班级由低到高排序输出
格式:班级号+英文空格+总成绩平均分
如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet"
异常情况:
1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"
2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch"
以上两种情况如果同时出现,按第一种情况输出结果。
3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch"
4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format"
5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。
6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match"
7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error"
信息约束:
1)成绩平均分只取整数部分,小数部分丢弃
参考类图(与第一次相同,其余内容自行补充):
输入样例1:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
end
输出样例1:
在这里给出相应的输出。例如:
java has no grades yet
输入样例2:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2
end
输出样例2:
在这里给出相应的输出。例如:
java : number of scores does not match
输入样例3:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.1
end
输出样例3:
在这里给出相应的输出。例如:
java : weight value error
输入样例4:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100
end
输出样例4:
在这里给出相应的输出。例如:
20201116 张三 86
java 86
202011 86
输入样例5:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100 80
end
输出样例5:
在这里给出相应的输出。例如:
20201116 张三 : access mode mismatch
20201116 张三 did not take any exams
java has no grades yet
202011 has no grades yet、
这道题也是最难的最后的重点,,以下是我的错误代码
import java.text.Collator; import java.util.*; public class Main { public static void main(String[] args) { ParseInput handle=new ParseInput(); Scanner input = new Scanner(System.in); String nextLine = input.nextLine(); while (!nextLine.equals("end")){ handle.parseInput(nextLine);//解析用户输入的每一行数据 nextLine = input.nextLine(); } handle.showStudents(); handle.showCourses(); handle.showClasses(); } } class Course implements Comparable<Course>{ private String name; private String Type; private String method; private int n; private float [] value; public Course() {} public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return Type; } public void setType(String type) { Type = type; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public int getN() { return n; } public void setN(int n) { this.n = n; } public float[] getValue() { return value; } public void setValue(float[] value) { this.value = value; } public Course(String name, String type, String method, int n, float[] value) { this.name = name; Type = type; this.method = method; this.n = n; this.value = value; } @Override public int compareTo(Course o) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); return compare.compare(name,o.getName()); } } class Select{ private Student student = new Student(); private Course course = new Course(); private Score score; public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public Course getCourse() { return course; } public void setCourse(Course course) { this.course = course; } public Score getScore() { return score; } public void setScore(Score score) { this.score = score; } public Select(Student student, Course course, Score score) { this.student = student; this.course = course; this.score = score; } } class ParseInput{ private List<Student> students = new ArrayList<>(); private List<Course> courses = new ArrayList<>(); private List<Select> selects = new ArrayList<>(); private List<Class> classes = new ArrayList<>(); void addStudent(String id,String name){ Student student = new Student(id,name); if(selects.size()==0){ students.add(student); } else { int flag=0; for(Student student1:students){ if ( student1.getId().equals(id)) { flag = 1; break; } } if(flag==0) students.add(student); } } void addCourse(String name,String Type,String method,int n,float [] value){ if(courses.size()==0){ Course course1 = new Course(name,Type,method,n,value); courses.add(course1); } else { int flag=0; for(Course course:courses){ if (course.getName().equals(name)) { flag = 1; break; } } if(flag==0) { Course course1 = new Course(name,Type,method,n,value); courses.add(course1); } } } void addSelect(Student student, Course course, Score score){ // Select select = new Select(student,course,score); // selects.add(select); if(selects.size()==0){ Select select = new Select(student,course,score); selects.add(select); } else { int flag=0; for(Select select:selects){ if (select.getStudent().getId().equals(student.getId())&&select.getCourse().getName().equals(course.getName())) { flag = 1; break; } } if(flag==0) { Select select = new Select(student,course,score); selects.add(select); } } } void addClass(String id){ if(classes.size()==0){ Class aclass = new Class(id); classes.add(aclass); } else { int flag=0; for (Class aclass:classes){ if (aclass.getId().equals(id)) { flag = 1; break; } } if(flag==0){ Class Aclass = new Class(id); classes.add(Aclass); } } } public void parseInput(String input) { String[] sr = input.split(" "); switch (InputMatching.matchingInput(input)){ case 0: System.out.println("wrong format"); break; case 1:{ if(sr[1].equals("必修")&&sr[2].equals("考察")||(sr[1].equals("实验")&& !sr[1].equals(sr[2])) ||(sr[2].equals("实验")&&!sr[1].equals("实验"))) System.out.println(sr[0]+" : course type & access mode mismatch"); else{ if(sr[2].equals("考试")){ if(sr.length==5){ float [] value = new float[2]; value[0] = Float.parseFloat(sr[3]); value[1] = Float.parseFloat(sr[4]); float sumValue = value[0]+value[1]; if((sumValue<0.99||sumValue>1.01)&&isCourseExist(sr[0])==null) System.out.println(sr[0]+" : weight value error"); else addCourse(sr[0],sr[1],sr[2],2,value); } else System.out.println("wrong format"); } if(sr[2].equals("考察")){ if(sr.length==3) addCourse(sr[0],sr[1],sr[2],1,null); else System.out.println("wrong format"); } if(sr[2].equals("实验")){ float sumValue = 0; int n = Integer.parseInt(sr[3]); if(sr.length!=n+4) System.out.println(sr[0]+" : number of scores does not match"); else{ float [] value = new float[n]; for(int i= 0;i<n;i++){ value[i] = Float.parseFloat(sr[i+4]); sumValue+=value[i]; } if((sumValue<0.99||sumValue>1.01)&&isCourseExist(sr[0])==null) System.out.println(sr[0]+" : weight value error"); else addCourse(sr[0],sr[1],sr[2],n,value);} } } break; } case 2:{ addClass(sr[0].substring(0,6)); Student student = new Student(sr[0],sr[1]); addStudent(sr[0],sr[1]); if(isCourseExist(sr[2])==null){ System.out.println(sr[2]+" does not exist"); } else { if(isCourseExist(sr[2]).getMethod().equals("考试")&&sr.length!=5 ||isCourseExist(sr[2]).getMethod().equals("考察")&&sr.length!=4 ||isCourseExist(sr[2]).getMethod().equals("实验")&&sr.length!=3+isCourseExist(sr[2]).getN()) System.out.println(sr[0]+" "+sr[1]+" : access mode mismatch"); else if(sr.length==4){ SubScore subScore = new SubScore(1.0F,Integer.parseInt(sr[3])); Score score = new Score(sr[0]); score.addSubScore(subScore); addSelect(student,isCourseExist(sr[2]),score); } else if(sr.length==5){ float [] value = isCourseExist(sr[2]).getValue(); SubScore subScore1 = new SubScore(value[0], Integer.parseInt(sr[3])); SubScore subScore2 = new SubScore(value[1], Integer.parseInt(sr[4])); Score score = new Score(sr[2]); score.addSubScore(subScore1); score.addSubScore(subScore2); addSelect(student,isCourseExist(sr[2]),score); } else{ Score score = new Score(sr[2]); int n = isCourseExist(sr[2]).getN(); float [] value = isCourseExist(sr[2]).getValue(); for(int i= 0;i<n;i++){ SubScore subScore = new SubScore(value[i],Integer.parseInt(sr[i+3])); score.addSubScore(subScore); } addSelect(student,isCourseExist(sr[2]),score); } } } } } public Course isCourseExist(String name) { for (Course course : courses) { if (course.getName().equals(name)) return course; } return null; } public void showStudents() { Collections.sort(students); for (Student stu : students) { //从总选课表listChooseCourse中获取该生的选课记录集合 ArrayList<Select> stuCourseSelects = getStudentselects(stu.getId()); if (stuCourseSelects == null) { System.out.println(stu.getId() + " " + stu.getName() + " " + "did not take any exams"); } else { System.out.println(stu.getId() + " " + stu.getName() + " " + getAvgTotalScore(stuCourseSelects)); } } } public void showCourses() { Collections.sort(courses); for(Course cou:courses){ //从总选课表listChooseCourse中获取该course的选课记录集合 ArrayList<Select> couCourseSelection = getCourseselect(cou.getName()); if(couCourseSelection==null){ System.out.println(cou.getName()+" has no grades yet"); } else { System.out.println(cou.getName()+" "+getAvgTotalScore(couCourseSelection)); } } } public void showClasses() { Collections.sort(classes); for(Class cla:classes){ //从总选课表listChooseCourse中获取该class的选课记录集合 ArrayList<Select> claCourseSelection = getClassselect(cla.getId()); if(claCourseSelection==null){ System.out.println(cla.getId()+" has no grades yet"); } else{ System.out.println(cla.getId()+" "+getAvgTotalScore(claCourseSelection)); } } } private String getAvgTotalScore(ArrayList<Select> stuCourseSelects) { int sum = 0; for(Select select:stuCourseSelects){ sum+=select.getScore().getTotalScore(); } return sum/stuCourseSelects.size()+""; } private ArrayList<Select> getClassselect(String id) { ArrayList<Select> selects1 = new ArrayList<>(); for(Select select:selects){ if(select.getStudent().getId().substring(0,6).equals(id)) selects1.add(select); } if(selects1.size()!=0) return selects1; else return null; } private ArrayList<Select> getCourseselect(String name) { ArrayList<Select> selects1 = new ArrayList<>(); for(Select select:selects){ if(select.getCourse().getName().equals(name)) selects1.add(select); } if(selects1.size()!=0) return selects1; else return null; } private ArrayList<Select> getStudentselects(String id) { ArrayList<Select> selects1 = new ArrayList<>(); for(Select select:selects){ if(select.getStudent().getId().equals(id)) selects1.add(select); } if(selects1.size()!=0) return selects1; else return null; } } class Score{ private String courseName; private List<SubScore> subScoreList; public Score(String courseName) { this.courseName = courseName; subScoreList = new ArrayList<>(); } public void addSubScore(SubScore subScore) { subScoreList.add(subScore); } public int getTotalScore() { float totalScore = 0; for (SubScore subScore : subScoreList) { totalScore += subScore.getScore(); } return (int)totalScore; } public String getCourseName() { return courseName; } } class SubScore { private float scoreValue; private int weight; public SubScore(float scoreValue, int weight) { this.scoreValue = scoreValue; this.weight = weight; } public float getScore() { return scoreValue * weight; } public float getScoreValue() { return scoreValue; } public int getWeight() { return weight; } } class Class implements Comparable<Class>{ private String id; private List<Student> students = new ArrayList<>(); void addStudent(){ Student student = new Student(); students.add(student); } public Class(String id){ this.id = id; } public String getId() { return id; } public void setId(String id) { this.id = id; } @Override public int compareTo(Class o) { return id.compareTo(o.id); } } class Student implements Comparable<Student>{ private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student() {} public Student(String id, String name) { this.id = id; this.name = name; } @Override public int compareTo(Student o) { return id.compareTo(o.id); } } class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String scoreMatching1 = "([1-9]\\d{0,1}|0|100)( ([1-9]\\d{0,1}|0|100)){1,9}"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String decimalsRegex = "(\\d+\\.\\d+)( (\\d+\\.\\d+)){2,9}"; static String experimentNumber = "[4-9]";//实验次数 static String decimals = "\\d+\\.\\d+";//小数 //cousrInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + "选修" + " " + "考察"; static String courseInput0 = courseNameMatching + " " + "必修" + " " + "考试"+ " " + decimals + " " + decimals; static String courseInput2 = courseNameMatching + " " + "选修" + " " + "考试"+ " " + decimals + " " + decimals; static String courseInput1 = courseNameMatching + " " + "实验" + " " + "实验" + " " + experimentNumber + " " + decimalsRegex; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching; static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching +" "+scoreMatching1; public static int matchingInput(String s) { if (matchingCourse(s)) { return 1; } if (matchingScore(s)) { return 2; } return 0; } private static boolean matchingCourse(String s) { return (s.matches(courseInput)||s.matches(courseInput1)||s.matches(courseInput0)||s.matches(courseInput2)); } private static boolean matchingScore(String s) { return (s.matches(scoreInput)||s.matches(scoreInput1)); } }
这道题出现很多错误,包括非零返回和答案错误,也是许多我仍需要学习的地方,
虽然最后一次的pta作业结束了,但我深知学习是没有尽头的,希望我能在接下来的学习中取得进步。
7-4 jmu-Java-04面向对象进阶-03-接口-自定义接口ArrayIntegerStack
定义IntegerStack
接口,用于声明一个存放Integer元素的栈的常见方法:
public Integer push(Integer item);
//如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item。
public Integer pop(); //出栈,如果为空,则返回null。出栈时只移动栈顶指针,相应位置不置为null
public Integer peek(); //获得栈顶元素,如果为空,则返回null.
public boolean empty(); //如果为空返回true
public int size(); //返回栈中元素个数
定义IntegerStack的实现类ArrayIntegerStack
,内部使用数组实现。创建时,可指定内部数组大小。
main方法说明
- 输入n,建立可包含n个元素的ArrayIntegerStack对象
- 输入m个值,均入栈。每次入栈均打印入栈返回结果。
- 输出栈顶元素,输出是否为空,输出size
- 使用Arrays.toString()输出内部数组中的值。
- 输入x,然后出栈x次,每次出栈均打印。
- 输出栈顶元素,输出是否为空,输出size
- 使用Arrays.toString()输出内部数组中的值。
思考
如果IntegerStack接口的实现类内部使用ArrayList来存储元素,怎么实现?测试代码需要进行什么修改?
输入样例
5
3
1 2 3
2
输出样例
1
2
3
3,false,3
[1, 2, 3, null, null]
3
2
1,false,1
[1, 2, 3, null, null]
import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int n = input.nextInt(); ArrayIntegerStack a = new ArrayIntegerStack(n); int m = input.nextInt(); while(m > 0){ int item = input.nextInt(); System.out.println(a.push(item)); m--; } System.out.println(a.peek() + "," + a.empty() + "," + a.size()); System.out.println(a); int x = input.nextInt(); while(x > 0){ System.out.println(a.pop()); x--; } System.out.println(a.peek() + "," + a.empty() + "," + a.size()); System.out.println(a); } } interface IntegerStack{ public Integer push(Integer item);//如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item。 public Integer pop(); //出栈,如果为空,则返回null。出栈时只移动栈顶指针,相应位置不置为null public Integer peek(); //获得栈顶元素,如果为空,则返回null. public boolean empty(); //如果为空返回true public int size(); //返回栈中元素个数 } class ArrayIntegerStack implements IntegerStack{ Integer[] array; int top = 0; public ArrayIntegerStack(int n){ array = new Integer[n]; Arrays.fill(array, null); } public ArrayIntegerStack(){} @Override public String toString() { return Arrays.toString(array); } @Override public Integer push(Integer item) { if (item == null || array.length == top){ return null; } array[top++] = item; return item; } @Override public Integer pop() { if (top == 0){ return null; } return array[--top]; } @Override public Integer peek() { if (top == 0){ return null; } return array[top - 1]; } @Override public boolean empty() { return top == 0; } @Override public int size() { return top; } }
我们成功实现了自定义接口ArrayIntegerStack。首先,我们定义了一个名为ArrayIntegerStack的接口,其中包含了push、pop、size和isEmpty方法。接着,我们实现了ArrayIntegerStack接口,
并创建了ArrayIntegerStackImpl类,实现了接口中的所有方法。最后,我们编写了测试代码,验证了ArrayIntegerStack接口的功能。
三踩坑心得
-
1,pta部分题目运行时间超时,要优化代码的算法,很多时候不是你的方法不行,而是有优化的地方没有优化,导致程序运行的时间加长导致超时,现在争取把每个小步骤都优化,以后的大作业程序才能不断的节省时间。
2,pta部分题目非零返回,自己的代码有问题才会导致的,要检查自己的程序逻辑。
3,对继承的方法使用不熟练,对传参的方法也不太熟练,会用但是容易出错,要多使用,防止以后出错。
4,对类的设计要更细节和具体,每个类包含的属性和方法,以及不同类之间的关系。
5.、在PTA训练集05中的7-1 菜单计价程序-4题目中,所使用的if...else...语句过多,或许可以换个思路来减少一些if...else...语句,增强代码可读性和可修改性;
-
1.对于全局变量和局部变量需要格外注意,不然容易导致结果出错。全局变量就是从定义的位置起,作用域覆盖整个程序范围的变量。而只在特定的过程或函数中可以访问的变量,被称为局部变量。
-
2.处理父类和子类关系时,要了解继承的关系和逻辑,不然得出的答案可能会出错。
3.处理类里的变量时,因为属性是私有的,所以调用时只能用get()方法处理。
4.处理问题中的计算问题不能想当然,像这次期末考试的Π不能直接用3.14代。
-
四、改进建议
1.在代码中多标明注释,以便理解和下次修改。
2.有些代码中有一部分功能相同,可以改成方法,使代码更加简洁,也便于下次对代码进行修改。
3.有一些类也可以和其他类一样变成父类的子类,应该尽量减少代码的重复率,提高代码的利用率和可读性。
4.可以尝试使用不同的方法解决同一道题。
五、总结
经过一个学期的JAVA课程学习,现在虽说算不上什么专业的JAVA程序员,但我还是很有收获。了解了这门语言,探索了这门语言,认知了这门语言。我从一个什么都不懂的菜鸟,到现在能够自己编一个简单的程序并使其跑起来,学习JAVA应该是循环渐进,按部就班,脚踏实地的。学JAVA,一定要做到课前预习与课后复习,书上的概念要理解透彻,代码一定要过手;多和同学沟通,互相学习,取长补短。我觉得应该多看别人的总结,多与别人进行交流,但是本学期学习压力较大,可能自己也不是学的很好,我对课程提出的建议就是我认为pta上的题目可以中档难度的题目多一些,而不是太难的题目,这不仅会使我们学习的自信下降,等下一次pta发布又是这道难题的升级版,无从下手,最终陷入恶性循环。其次,我觉得提交的时间应该更加人性化一点,多给些时间也能让学生们的学习压力减轻一些,不会感觉那么压迫,丧失对java学习的兴趣。Java基础课程已经结束,但对于Java知识的学习与提升才刚刚开始。更熟练的使用Java,更好的类关系设计将作为之后学习的目标与方向。相较于Java宏大的知识体系,所学的知识不过风毛菱角,更加丰富的知识还尚未来到。要不断学习,不断探索,虚心学习,勤于练习。