前言
- 在这次pta题目集4~6中,我们有了前三次基础java作业的基础,正式开始对java实验的进阶,其中的菜单计价程序的难度逐渐增大,第五次和第六次pta作业都是在第四次作业菜单计价程序-三上进行添加的,难度有点大。
- 在这三次题目集当中,因为对于java函数的使用不算熟练,有些函数实现的代码还得通过去查询相关的资料,比如时间函数中引入头文件import java.time.LocalDate;import java.time.temporal.ChronoUnit;这两个头文件可以很好的用于解决两个日期间隔多少天,通过long daysBetween = ChronoUnit.DAYS.between(date1, date2)可以计算出给定时间date1和date2之间间隔多少天。还学会了利用哈希表来进行查询,可以缩短用时的时间,提高查询的时间效率。
- 这三次题目集当中,最重要的莫过于是菜单计价程序的设计,从版本二到版本三、四、5,都是层层递进的,最简单的莫过于菜单计价程序二了,只需要完成对菜品类,菜谱类,点菜类,以及订单类的设计,再进入主函数进行相关程序的设计。在程序设计中对类进行一些封装,在点菜类里利用System.arraycopy(records,i+1,newRecords,i,records.length-i-1);此函数对于实现根据序号进行删除一条记录。
- 而菜单四和菜单五在原来的基础上增加了一系列功能的判定,例如增加特色菜以及table类来进行点菜,再加上规定时间范围内的营业,这些都有着相对应的折扣价格,以及对于一些输入错误或者不在营业时间内的一些判定给出的异常输出。例如如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"等等,对于输入格式和输出格式都有着较为严格的要求。
设计与分析
-
7-2 菜单计价程序-2 的相应生成类图报表
相关复杂度的分析
Dish类:表示菜品,包含菜品名称和单价,以及根据份额计算价格的方法。
Record类:表示订单中的一条记录,包含序号、菜品、份额和份数,以及根据菜品信息计算价格的方法。
Menu类:表示菜单,包含所有菜品的信息,可以根据菜名查找菜品,还可以添加新菜品。
Order类:表示订单,包含多条记录,可以计算订单的总价格,可以添加、删除和查找记录。
main类:主程序入口,通过命令行输入来操作菜单和订单,并输出最终的总价格。
该代码的设计比较简单和清晰,使用了面向对象的思想,将不同的功能模块封装成不同的类,便于扩展和维护。同时,使用了数组和集合等数据结构来存储和管理数据。在主程序中,通过循环读取用户输入的命令,根据命令执行相应的操作,最后输出订单的总价格。
第五次作业 菜单计价程序5相应生成类图报表
复杂度分析
类设计:
Dish类:表示菜品,包括菜品名称、单价和计算菜品价格的方法。
Menu类:菜谱类,包含了一个菜品数组,可以根据菜品名称查找菜品,也可以添加新的菜品。
Record类:点菜记录类,保存了订单上的一道菜品记录,包括序号、菜品、份额和份数,可以计算本条记录的价格。
Order类:订单类,保存了用户点的所有菜的信息,包括订单上每一道的记录,可以计算订单的总价,添加、删除和查找一条记录。
Table类:桌子类,表示餐桌信息,包括桌号、订单、日期和折扣。
主程序逻辑:
主程序首先通过控制台输入获取菜品和点菜信息,并进行格式检查和数据处理。
然后根据输入的点菜信息创建菜品和订单记录,并加入到对应的菜谱和订单中。
在处理完所有输入后,根据订单信息计算每个桌子的总价和优惠价,并输出结果。
输入输出处理:
代码通过Scanner类获取控制台输入,通过System.out.println输出结果。
对输入的字符串进行分割和类型转换,进行各种格式和逻辑上的检查,并将错误信息加入到messageList中,最后统一输出。
时间比较方法:
timeCalendar方法接收三个日期参数,判断当前时间是否在开始时间和结束时间之间,用于判断餐桌是否在营业时间内。
综上所述,该程序实现了一个简单的餐厅点菜系统,通过合理的类设计和逻辑处理,完成了菜品管理、订单处理和营业时间判断等功能。
期中考试编程题
一.圆类设计
创建一个圆形类(Circle),私有属性为圆的半径,从控制台输入圆的半径,输出圆的面积
import java.util.*;
class Circle{
private double banjin;
public Circle(double banjin){
this.banjin = banjin;
}
}
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double banjin = scanner.nextDouble();
if(banjin>0){
double area = 0;
area = Math.PI *banjin*banjin;
System.out.printf("%.2f", area);
}
else{
System.out.println("Wrong Format");
}
}
}
二.类结构设计
设计一个矩形类,其属性由矩形左上角坐标点(x1,y1)及右下角坐标点(x2,y2)组成,其中,坐标点属性包括该坐标点的X轴及Y轴的坐标值(实型数),求得该矩形的面积。类设计如下图:
import java.util.*;
class juxing{
private double x1,y1;
private double x2,y2;
public juxing(double x1,double y1,double x2,double y2){
this.x1 = x1;
this.y1 = x2;
this.x2 = y1;
this.y2 = y2;
}
}
public class Main{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
double x1 = scanner.nextDouble();
double y1 = scanner.nextDouble();
double x2 = scanner.nextDouble();
double y2 = scanner.nextDouble();
double getarea = 0.0;
juxing juxing = new juxing(x1,y1,x2,y2);
getarea = Math.abs(x1-x2)*Math.abs(y1-y2);
System.out.printf("%.2f",getarea);
}
}
三.继承与多态
将测验1与测验2的类设计进行合并设计,抽象出Shape父类(抽象类),Circle及Rectangle作为子类,类图如下所示:
import java.util.Scanner;
abstract class Shape {
public abstract double getArea();
}
class Circle extends Shape {
private double banjin;
public Circle(double radius) {
this.banjin = radius;
}
public double getArea() {
if (banjin > 0) {
return Math.PI * banjin * banjin;
} else {
return 0;
}
}
}
class Rectangle extends Shape {
private double x1;
private double y1;
private double x2;
private double y2;
public Rectangle(double x1, double y1, double x2, double y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public double getArea() {
return Math.abs(x2 - x1) * Math.abs(y2 - y1);
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
if (choice == 1) {
double banjin = scanner.nextDouble();
Circle circle = new Circle(banjin);
if(banjin>0) {
System.out.printf("%.2f", circle.getArea());
}else{
System.out.println("Wrong Format");
}
} else if (choice == 2) {
double x1 = scanner.nextDouble();
double y1 = scanner.nextDouble();
double x2 = scanner.nextDouble();
double y2 = scanner.nextDouble();
Rectangle rectangle = new Rectangle(x1, y1, x2, y2);
System.out.printf("%.2f", rectangle.getArea());
}
}
}
第六次pta作业
7-1菜单计价程序5相应生成类图报表
相关复杂度分析
-
Menu类:该类用于管理菜单信息,包括菜品名称、价格和口味等。提供了添加菜品和搜索菜品的方法。
Dish类:表示菜品,包括名称、价格、口味等信息。同时还包含判断是否为特价菜的标志位。
Order类:表示点菜,包括记录点菜的菜品、数量等信息,并提供了添加和删除点菜记录的方法。
Table类:表示餐桌,包括餐桌号、点餐时间、总消费等信息。提供了判断餐桌是否在营业时间内的方法。
Record类:记录点菜的具体信息,包括订单号、菜品、份数等。提供了计算订单金额和折扣的方法。
Main类:包含主程序入口和一些辅助方法,如判断是否为数字、搜索电话号码是否合法等。在主函数中,首先创建了一个菜单实例,然后进入一个循环,提示用户输入桌号并选择操作,根据用户的选择进行相应的操作,直到用户选择退出。
踩坑心得
第四次题目集 菜单计价程序-2
(1)在代码中使用了数组来存储菜品、订单记录等信息,需要注意数组的扩容和复制操作。在添加新菜品或订单记录时,需要考虑扩大数组的容量并复制原数据到新数组中,这一部分已经在你的代码中得到了处理。
(2)在用户输入的处理上,需要考虑到可能的异常情况,比如用户输入错误的菜品名或数量。可以增加一些输入验证的逻辑,确保程序能够处理各种不同的输入情况,避免出现异常。
(3)在代码中明白各个类的调用完成功能的实现,例如在点菜类里使用record记录类里的菜单的序号,根据序号删除记录以及查找订单。
第五次题目集 菜单计价程序-4
(1)利用ArrayList来存取数据而不采用数组来存取,数组在创建时需要指定固定的大小,而ArrayList可以根据需要动态地增长或缩小。这意味着你不需要提前知道存储的元素数量,可以根据实际需求自由地添加或删除元素。ArrayList类提供了一系列方便的方法来操作数据,例如添加、删除、查找、替换等。这些方法可以大大简化代码的编写,并且已经经过了测试和调试,可以提供可靠的功能。
(2)增加错误处理和异常处理编写代码时,需要考虑可能发生的错误和异常情况,并编写相应的错误处理和异常处理逻辑,以保证程序的稳定性和健壮性。
第六次题目集 菜单计价程序-5
(1)相比于菜单计价程序4来说难度还降低了一些,但是增加了一些口味度,如辣,微辣等,还分为了浙菜、川菜、晋菜等,需要在菜单计价程序3上进行一定程度上的修改,修改判断条件即可。
(2)合理使用循环和条件语句。用户可以连续点餐或者多次修改订单,因此需要使用循环来处理多次输入。同时,需要根据用户的选择执行不同的操作,因此需要使用条件语句来实现分支逻辑。
踩坑心得
-
1,pta部分题目运行时间超时,要优化代码的算法,很多时候不是你的方法不行,而是有优化的地方没有优化,导致程序运行的时间加长导致超时,现在争取把每个小步骤都优化,以后的大作业程序才能不断的节省时间。
2,pta部分题目非零返回,自己的代码有问题才会导致的,要检查自己的程序逻辑。
3,对继承的方法使用不熟练,对传参的方法也不太熟练,会用但是容易出错,要多使用,防止以后出错。
4,对类的设计要更细节和具体,每个类包含的属性和方法,以及不同类之间的关系。
5.、在PTA训练集05中的7-1 菜单计价程序-4题目中,所使用的if...else...语句过多,或许可以换个思路来减少一些if...else...语句,增强代码可读性和可修改性;
总结
1.类和对象的设计:类是面向对象设计的基本单位,它具有属性(数据)和方法(行为)。在设计类时,需要关注类的职责和功能,确保类具有高内聚和低耦合的特性。合理选择和设计类的属性和方法,使其能够描述对象的状态和行为。同时,要注意类之间的关系,如继承、接口实现、组合等。通过合理的类和对象设计,能够更好地组织和管理代码,提高代码的可读性和可维护性。
2.封装和信息隐藏:封装是面向对象设计的核心原则之一,通过封装可以将数据和方法组合在一起,形成类的内部实现细节。封装可以隐藏内部细节,只暴露必要的接口给外部使用。在设计类时,要考虑属性的访问权限和方法的正确使用方式,以保证数据安全性和代码的可靠性。
3.继承和多态:继承是面向对象设计的另一个重要概念,它能够通过子类继承父类的属性和方法,并可以添加或修改自己的特性。通过合理使用继承,可以实现代码的复用,并能够体现出对象之间的关系("is-a"关系)。多态是继承的一种扩展,通过多态可以在程序运行时,根据实际对象的类型,选择正确的方法调用。对于继承和多态的使用,要考虑类之间的关系、方法的覆盖和重载,以及灵活使用接口和抽象类。
4.设计模式和代码重构:设计模式是一些解决特定问题的经验和经典方案的总结,能够提供可重用的解决方案。在面向对象设计中,学习和应用设计模式能够提高代码的质量和可维护性。同时,代码重构是改善现有代码的一种方式,它能够通过优化代码结构、提高代码的可读性和可维护性。学习并熟练使用设计模式和代码重构的技巧,有助于提高代码设计和编写的效率。
5.异常处理和错误处理:在面向对象设计中,异常处理是一种常见的行为,能够提高代码的容错性和健壮性。合理捕获和处理异常,能够避免程序的崩溃,并提供友好的错误提示信息。同时,可以针对不同的异常类型,进行适当的处理和恢复。在设计类和方法时,要考虑可能出现的异常情况,并提供相应的处理方式。