第二次博客作业:作业和期中考试总结
(1)前言:
菜单作业知识点:
1. Java基础语法:例如变量定义、常量定义、数据类型、循环、条件语句等。
2. 面向对象编程:例如类和对象的定义,封装、继承和多态的概念,方法的重载和重写等。
3. 数组:因为菜单上可能有多个选项,需要使用数组进行管理和操作。
4. 输入和输出:程序需要从控制台或文件中读取菜单内容,并将计算结果输出到控制台或者保存到文件中。
5. 异常处理:在程序运行过程中,可能会出现一些错误或者异常情况,需要进行捕获和处理,以保证程序正常运行且不影响用户体验。
7. 设计模式:例如观察者模式、工厂模式等设计模式可以提高代码的灵活性和可扩展性,使得程序更易于维护和修改。
难度:较困难,需要实现简单的菜单选项,实现不算复杂,只需一些基础的Java语法知识。但需要考虑到多种菜品、状态切换、价格计算等场景,就需要更深入地掌握Java面向对象编程、数组、输入输出操作等相关知识。
期中考试知识点:
7-1 测验1-圆类设计:这题没有什么特殊的知识点,知道Java如何使用圆周率——Math.PI即可!
7-2 测验2-类结构设计:本题类图已给出,主要考察根据已知类完成代码的能力,只需要按照类图书写即可。同时略微涉及到构造函数的知识! 设计一个矩形类,以及点类,矩形由两个点组成(左上,右下),只需要输出面积,唯一麻烦的是所有的属性都 是prevate类型的都要所有对应的set和get方法进行操作,以及要写新的构造方法(在构造时将属性全部设置好)。
7-3 测验3-继承与多态:将测验1与测验2的类设计进行合并设计,抽象出Shape父类(抽象类),Circle及Rectangle作为子类
7-4 测验4-抽象类与接口:在测验3的题目基础上,重构类设计,实现列表内图形的排序功能(按照图形的面积进行排序)。
难度:较简单。
(2)设计与分析:
第五次大作业
类图:


源码:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
class Dish {
String name; //菜品名称
int unit_price; //单价
String type = null;
//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
int getPrice(int portion) {
if (portion == 1) {
return unit_price;
}
else if (portion == 2) {
return (int) Math.round(1.5 * unit_price);
}
else if (portion == 3) {
return 2 * unit_price;
}
return 0;
}
public Dish(String name, int unit_price) {
this.name = name;
this.unit_price = unit_price;
}
public Dish(String name, String type, int unit_price) {
this.name = name;
this.unit_price = unit_price;
this.type = type;
}
}
class Menu {
List<Dish> dishs = new ArrayList<>();//菜品数组,保存所有菜品信息
//根据菜名在菜谱中查找菜品信息,返回Dish对象。
Dish searchDish(String dishName) {
for (Dish dish : dishs) {
if (Objects.equals(dish.name, dishName)) {
return dish;
}
}
return null;
}
//添加一道菜品信息
void addDish(Dish dish) {
dishs.add(dish);
}
}
class Record {
int delete;
int orderNum; //序号
Dish d; //菜品
int portion; //份额(1/2/3代表小/中/大份)
int count; //数量
String dishName; //菜名
int degree;
int forTable;
//计价,计算本条记录的价格
int getPrice() {
return d.getPrice(portion) * count;
}
}
class Table {
List<Record> records = new ArrayList<>(); //保存订单上每一道的记录
int id;
String name;
String phone;
Time time;
public Table(int id, String name, String phone, Time time) {
this.id = id;
this.name = name;
this.phone = phone;
this.time = time;
}
public Table() {
this.id = -1;
this.name = "";
this.phone = "";
this.time = new Time("0/1/1","00/00/00");
}
boolean valid() {
if (name.length() > 10) {
return false;
}
if (phone.length() != 11) {
return false;
}
if (Objects.equals(phone.substring(0, 3), "180")) {
return true;
}
if (Objects.equals(phone.substring(0, 3), "181")) {
return true;
}
if (Objects.equals(phone.substring(0, 3), "189")) {
return true;
}
if (Objects.equals(phone.substring(0, 3), "133")) {
return true;
}
if (Objects.equals(phone.substring(0, 3), "135")) {
return true;
}
if (Objects.equals(phone.substring(0, 3), "136")) {
return true;
}
return false;
}
// 是否营业
boolean isOpening() {
int now = time.hour * 10000 + time.minute * 100 + time.second;
int time1 = 170000;// 17:00
int time2 = 203000;// 20:30
int time3 = 103000;// 10:30
int time4 = 143000;// 14:30
int time5 = 93000;// 9:30
int time6 = 213000;// 21:30
int week = time.getWeek();
if (week >= 1 && week <= 5) {// 周一到周五
if (now >= time1 && now <= time2) {
return true;
}
return now >= time3 && now <= time4;
}
return now >= time5 && now <= time6;
}
}
class Time {
int year;
int month;
int day;
int hour;
int minute;
int second;
//求周几
int getWeek() {
LocalDate date = LocalDate.of(year, month, day);
DayOfWeek weekday = date.getDayOfWeek();
return weekday.getValue();
}
public Time(String str1, String str2) {
String[] split1 = str1.split("/");
year = Integer.parseInt(split1[0]);
month = Integer.parseInt(split1[1]);
day = Integer.parseInt(split1[2]);
String[] split2 = str2.split("/");
hour = Integer.parseInt(split2[0]);
minute = Integer.parseInt(split2[1]);
second = Integer.parseInt(split2[2]);
}
}
class Detail {
int tableId;
int sumPrice;
int salePrice;
String own;
String phone;
public Detail(int tableId, int sumPrice, int salePrice, String own, String phone) {
this.tableId = tableId;
this.sumPrice = sumPrice;
this.salePrice = salePrice;
this.own = own;
this.phone = phone;
}
}
class Account {
String name;
String phone;
int sum;
public Account(String name, String phone, int sum) {
this.name = name;
this.phone = phone;
this.sum = sum;
}
}
public class Main {
public static void main(String[] args) {
Menu menu = new Menu();
boolean isMenu = true;
List<Table> tables = new ArrayList<>();
Table curTable = new Table();
Set<Integer> del = new HashSet<>();
Set<Integer> hasNotDish = new HashSet<>();
Scanner cin = new Scanner(System.in);
while (true) {
String str = cin.nextLine();
if (Objects.equals(str, "end")) {
break;
}
// System.out.println(str);
String[] split = str.split(" ");
if (Objects.equals(split[0], "table")) {
if(split.length == 7){
int tableId = Integer.parseInt(split[1]);
String name = split[3];
String phone = split[4];
Time time = new Time(split[5], split[6]);
isMenu = false;
curTable = new Table(tableId, name, phone, time);
del = new HashSet<>();
hasNotDish = new HashSet<>();
tables.add(curTable);
} else {
del = new HashSet<>();
hasNotDish = new HashSet<>();
curTable = new Table();
isMenu = false;
tables.add(curTable);
}
}
else if (isMenu) {
if (split.length == 4 && Objects.equals(split[3], "T")) { //特色菜
int price = Integer.parseInt(split[2]);
boolean isFind = false;
for (Dish dish : menu.dishs) {
if (Objects.equals(dish.name, split[0])) {
dish.unit_price = price;
isFind = true;
break;
}
}
if (!isFind) {
Dish dish = new Dish(split[0], split[1], price);
menu.addDish(dish);
}
}
else if (split.length == 2) { //非特色菜
int price = Integer.parseInt(split[1]);
boolean isFind = false;
for (Dish dish : menu.dishs) {
if (Objects.equals(dish.name, split[0])) {
dish.unit_price = price;
isFind = true;
break;
}
}
if (!isFind) {
Dish dish = new Dish(split[0], price);
menu.addDish(dish);
}
}
else {
System.out.println("wrong format");
}
}
else {
// 订单
if (split.length == 2 && Objects.equals(split[1], "delete")) { //delete
boolean isDelete = false;
for (Record record : curTable.records) {
if (record.orderNum == Integer.parseInt(split[0])) {
isDelete = true;
del.add(record.orderNum);
break;
}
}
Record record = new Record();
if (!isDelete) {
record.delete = 1;
record.orderNum = Integer.parseInt(split[0]);
curTable.records.add(record);
} else {
record.delete = 2;
record.orderNum = Integer.parseInt(split[0]);
curTable.records.add(record);
}
}
else if (split.length == 4) {
Record record = new Record();
record.orderNum = Integer.parseInt(split[0]);
record.dishName = split[1];
record.portion = Integer.parseInt(split[2]);
record.count = Integer.parseInt(split[3]);
record.forTable = curTable.id;
curTable.records.add(record);
}
else if (split.length == 5) {
if (Character.isDigit(split[1].charAt(0))) {
//代点
Record record = new Record();
record.orderNum = Integer.parseInt(split[1]);
record.forTable = Integer.parseInt(split[0]);
record.dishName = split[2];
record.portion = Integer.parseInt(split[3]);
record.count = Integer.parseInt(split[4]);
curTable.records.add(record);
}
else {
Record record = new Record();
record.orderNum = Integer.parseInt(split[0]);
record.dishName = split[1];
record.degree = Integer.parseInt(split[2]);
record.portion = Integer.parseInt(split[3]);
record.count = Integer.parseInt(split[4]);
record.forTable = curTable.id;
curTable.records.add(record);
}
}
else if (split.length == 6) {
//代点
Record record = new Record();
record.orderNum = Integer.parseInt(split[1]);
record.forTable = Integer.parseInt(split[0]);
record.dishName = split[2];
record.degree = Integer.parseInt(split[3]);
record.portion = Integer.parseInt(split[4]);
record.count = Integer.parseInt(split[5]);
curTable.records.add(record);
}
else {
System.out.println("wrong format");
}
}
}
int[] la = new int[50];
int[] chuan = new int[50];
int[] suan = new int[50];
int[] jin = new int[50];
int[] tian = new int[50];
int[] zhe = new int[50];
List<Detail> tableDetails = new ArrayList<>();
for (Table table : tables) {
if (!table.valid()) {
System.out.println("wrong format");
}
else if (!table.isOpening()) {
System.out.println("table " + table.id + " out of opening hours");
}
else {
System.out.println("table " + table.id + ": ");
int sumPrice = 0, salePrice = 0;
for (Record record : table.records) {
if(record.delete==1 || hasNotDish.contains(record.orderNum)){
System.out.println("delete error;");
continue;
}
if(record.delete!=0){
continue;
}
Dish dish = menu.searchDish(record.dishName);
if (dish == null) {
System.out.println(record.dishName + " does not exist");
hasNotDish.add(record.orderNum);
continue;
}
record.d = dish;
if (dish.type != null) {
switch (dish.type) {
case "川菜":
if (record.degree >= 0 && record.degree <= 5) {
if(!del.contains(record.orderNum)) {
chuan[record.forTable] += record.count;
la[record.forTable] += record.degree * record.count;
}
}
else {
System.out.println("spicy num out of range :"+record.degree);
continue;
}
break;
case "晋菜":
if (record.degree >= 0 && record.degree <= 4) {
if(!del.contains(record.orderNum)){
jin[record.forTable] += record.count;
suan[record.forTable] += record.degree * record.count;
}
}
else {
System.out.println("acidity num out of range :"+record.degree);
continue;
}
break;
case "浙菜":
if (record.degree >= 0 && record.degree <= 3) {
if(!del.contains(record.orderNum)) {
zhe[record.forTable] += record.count;
tian[record.forTable] += record.degree * record.count;
}
}
else {
System.out.println("sweetness num out of range :"+record.degree);
continue;
}
break;
}
}
if (record.forTable == table.id) {
System.out.println(record.orderNum + " " + record.d.name + " " + record.getPrice());
}
else {
System.out.println(record.orderNum + " table " + table.id + " pay for table " + record.forTable + " " + record.getPrice());
}
if(!del.contains(record.orderNum)){
sumPrice += record.getPrice();
salePrice += sale(dish.type != null, record.getPrice(), table.time);
}
}
tableDetails.add(new Detail(table.id, sumPrice, salePrice, table.name, table.phone));
}
}
TreeMap<String, Account> mp = new TreeMap<>();
for (Detail detail : tableDetails) {
String note = "table " + detail.tableId + ": " + detail.sumPrice + " " + detail.salePrice;
boolean st=false;
if (chuan[detail.tableId] > 0) {
note += " 川菜 " + chuan[detail.tableId] + " " + toStringDegree(Math.round((float) la[detail.tableId] / chuan[detail.tableId])) + "辣";
st=true;
}
if (jin[detail.tableId] > 0) {
note += " 晋菜 " + jin[detail.tableId] + " " + toStringDegree(Math.round((float) suan[detail.tableId] / jin[detail.tableId])) + "酸";
st=true;
}
if (zhe[detail.tableId] > 0) {
note += " 浙菜 " + zhe[detail.tableId] + " " + toStringDegree(Math.round((float) tian[detail.tableId] / zhe[detail.tableId])) + "甜";
st=true;
}
if(!st) note+=" ";
System.out.println(note);
if (mp.containsKey(detail.own)) {
Account account = mp.get(detail.own);
account.sum += detail.salePrice;
}
else {
mp.put(detail.own, new Account(detail.own, detail.phone, detail.salePrice));
}
}
for (Account account : mp.values()) {
System.out.println(account.name + " " + account.phone + " " + account.sum);
}
}
private static String toStringDegree(int degree) {
switch (degree) {
case 0:
return "不";
case 1:
return "微";
case 2:
return "稍";
case 3:
return "";
case 4:
return "很";
case 5:
return "爆";
}
return "";
}
private static int sale(boolean type, int price, Time time) {
int week = time.getWeek();
if (type) {
if (week >= 1 && week <= 5) {// 周一到周五
return (int) Math.round(price * 0.7);
}
return price;
}
int now = time.hour * 10000 + time.minute * 100 + time.second;
int time1 = 170000;// 17:00
int time2 = 203000;// 20:30
if (week >= 1 && week <= 5) {// 周一到周五
if (now >= time1 && now <= time2) {
return (int) Math.round(price * 0.8);
}
return (int) Math.round(price * 0.6);
}
return price;
}
}
圈复杂度:

知识点讲解:
- 在实现长度质量计量单位换算程序时,需要使用到Java中的基本数据类型、运算符和控制语句等知识。我们需要定义一些变量来保存输入数据,并使用条件语句处理异常情况,例如用户输入非法字符等。
2. 面向对象编程思想
为了实现程序的可重用性和扩展性,可以采用面向对象编程思想。可以将程序拆分为多个类,每个类负责不同的功能模块。例如,在程序中可以定义一个名为Converte r的类来进行单位转换操作。
Menu类表示一个菜单项,在这里定义了菜名、价格等属性,并提供相关get/set方法。
Order类表示一个订单项,在这里定义了所点菜名及份数等属性,并提供相关get/set方法以及计算总金额的方法。
Main类为主函数入口,负责控制整个逻辑流程,并与用户进行交互
代码实现分析:
在代码实现方面,该程序结构清晰,注释详细,优化良好。在Menu和Order两个类中使用了封装性原则,并且应用了面向对象编程中的继承和重载等特性。同时,在Main函数中也用到了异常处理机制,增强了程序的健壮性。
(3):踩坑心得
1. 编译错误:PTA上的题目往往需要使用Java的类库,如果没有正确导入这些类库,就会出现编译错误。在做题之前,要先阅读题目中所提到的类库,并将其导入到代码中。
2. 输入输出问题:PTA平台会提供多组测试数据,所以要注意输入输出格式。在处理输入时,应该使用Scanner或BufferedReader等工具类;在输出时,应该注意格式控制。
3. 数组越界错误:数组越界错误是一个常见的运行时错误。要避免这个错误,可以使用for-each循环或者List等Java集合代替原生数组。
4. 逻辑错误:有些PTA题目需要考虑边界和特殊情况。在编写代码之前,要认真阅读题目并理解需求,在代码实现过程中考虑各种可能性,并对每个分支进行测试。
5. 在使用Scanner类获取用户输入时,要注意避免空格、回车等非数字字符的干扰。可以在获取完数字后使用nextLine()方法将其余字符清空。
6. 在使用switch语句实现菜单功能时,要注意case语句中的break语句的位置。如果break放在末尾,则会出现意外的bug。建议将break放在case逻辑块的最后一行。
7. 菜单价格计算可能会产生小数,需要考虑数据类型和精度问题。可以使用BigDecimal类进行高精度运算。
8. 如果菜单计价程序中菜单很长,代码可读性和维护性都会降低。可以将菜单选项封装成一个独立类或枚举类型,并提供相应的方法。
(4):主要困难及改进意见
- 困难:理解题目要求和建立问题模型是解题的关键。对于一些复杂的问题,在理解要求和建立模型过程中可能会出现困难。
改进建议:在遇到难题时,不要放弃,应该经常深入思考和讨论,并尝试寻找更多的资料和范例来帮助理解。多看老师课上讲授的相关知识点,加强对基本操作的掌握,逐步积累编程思维能力。
2. 困难:编码中出现了语法错误或逻辑错误,导致程序无法正常运行或得到正确结果。
改进建议:细心地阅读代码、Debug技巧、注释技巧都非常重要。需要用心去分析每一个代码片段,并且有时需要进行代码重构或抽象化以优化代码。在遇到问题时,可以通过查看错误信息、调试语句等方式找到错误并修正它们。
3. 困难:时间限制过短或作业质量过高,导致完成作业较为困难。
改进建议:将时间合理分配并进行有效使用,放弃一开始就想从头到尾完成作业的想法。在时间不够的情况下,优先解决高分值的问题。同时,要阅读题目和代码,在理解后再进行编码。可以把一道大题拆成若干小题进行处理,逐渐深入理解问题。
(5):总结
1.
通过本阶段三次题目集,我学到了Java基础知识的运用,如循环结构、条件语句、数组、方法等。同时也学习到了面向对象编程的概念和实现,如封装、继承和多态等。
在完成菜单计价程序时,我深入了解了Java中Scanner类和DecimalFormat类的使用。使用Scanner获取用户输入,并通过DecimalFormat类对输出结果进行格式化,达到更好的视觉效果。
在实践过程中,我也发现了自己的不足之处。比如对Java集合类的掌握还不够熟练,在程序设计中往往使用基础数据类型进行处理,而没有充分利用Java提供的集合类及其相关方法。因此,在日后需要进一步学习并熟悉Java集合类的应用。
此外,在代码设计过程中还需要注意模块化思想,即将大问题拆分为小问题进行解决,并考虑代码重复利用率和可维护性等因素。
总之,通过这三次题目集的实践,我深入理解了Java编程语言,并掌握了一些基础开发技能。在未来的学习与实践中,我将进一步加强自身技能储备,并努力优化代码设计与开发效率。
2.
下面是我对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见。
1. 教师方面:建议教师讲解时能够结合实际应用场景进行讲解,提高学生的兴趣。同时,在授课内容方面,建议加强对一些实践性较强的内容进行解释和演示。
2. 课程方面:建议在Java语言相关知识点学习之外,可以增加一些实际项目案例进行讲解,并介绍相关行业知识,有助于学生更好地了解该领域的发展趋势和应用场景。
3. 作业方面:建议定期布置合理难度的编程作业,并严格按时同步批阅,及时反馈学生问题并提供优质批改意见。
4. 实验方面:建议设计具有一定难度和挑战性的实验题目,并在实验过程中能够引导学生思考问题并正确使用Java语言进行解决。
5. 课上及课下组织方式方面:针对Java课程特点,可以增加小组讨论、团队作业等课下学习方式,以及线上分享、线下实践等更多的课上教学方式,并鼓励学生积极参与,促进互动交流。同时,建议有关部门加强Java课程授课质量监管和教师培训,确保Java课程能够得到有效推广和应用。
希望以上意见可以对Java课程的改进建设有所启发。

浙公网安备 33010602011771号