BLOG-2
(1)前言
本次BLOG将对题目集4,5及期中考试相关题目进行分析与总结,以下是相关的前言部分。
题目集4,5各自只有一个题目,分别是菜单计价程序-4和菜单计价程序-5,这也是菜单计价程序的最后两个相关题目,难度嘛,可以说很难了。
而期中考试的题目有四个,分别是测验1-圆类设计,测验2-类结构设计,测验3-继承与多态,测验4-抽象类与接口。
测试1的难度属于简单的,不过有点问题我之后在“踩坑心得”会说,特别的知识点没有,都是基础。
测试2的难度也很简单,实际上测试3的难度也不大,主要考察的还是类的创建,继承关系和多态的应用。
测试4的难度就属于中等偏上了,主要因为我不熟悉接口的应用。
(2)设计与分析
以下我先给出菜单计价程序4的源码。
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.Calendar;
import java.util.Date;
public class Main {
public static void main(String[] args) {
Work work = new Work();
work.play();
}
}
class Work {
boolean Stop = false; //用来确定订单和菜单混杂在一起的情况
Menu menu; //单位菜单
Record record; //单位记录
Table table; //单位座位
ArrayList<Table> tables = new ArrayList<>(); //座位数组
Work() { //初始化,用来创建基本的类数组
//只能用一个菜单,别单位化
//对所有的table都开放
menu = new Menu();
//单位化,订单? Record应该是必须得单位化
record = new Record();
//定义一个存储Table的一个ArrayList —— tables的动态数组
tables = new ArrayList<>();
}
public void play() { //play 菜单程序主要运行的程序
Scanner in = new Scanner(System.in);
while (true) {
String Line = in.nextLine();
if (Line.equals("end")) {
break;
}
String[] LineArray = Line.split(" ");
if (LineArray.length == 2) { //一个空格
if (LineArray[1].equals("delete")) { //删除订单
int num = Integer.parseInt(LineArray[0]);
if (table.deletes.contains(num)) {
System.out.println("deduplication " + num);
continue;
}
else {
Record pp =table.order.find(num);
table.order.delARecordByOrderNum(num);
table.deletes.add(num);
}
} else { //菜单添加
if (!Stop) { //菜单还没有输出完
try {
int x = Integer.parseInt(LineArray[1]);
}
catch (Exception e1) {
System.out.println("wrong format");
continue;
}
Dish dish = new Dish(LineArray[0],Integer.parseInt(LineArray[1]));
menu.addDish(dish);
}
else {
System.out.println("invalid dish");
}
}
//continue;
}
else if (LineArray.length == 3) {
if (LineArray[2].equals("T")) { //特色菜
Dish dish = new Dish(LineArray[0],Integer.parseInt(LineArray[1]),LineArray[2]);
menu.addDish(dish);
}
}
else if (LineArray.length == 4) { //三个空格,四个数据
if (LineArray[0].equals("table")) { //座号
try {
table = new Table(LineArray[1], LineArray[2], LineArray[3],menu);
if (table.time_error) {
int yy = Integer.parseInt(LineArray[2]); //用来故意报错
}
table.Discount(); //设定该table的折扣
System.out.println("table " + table.num + ": ");
tables.add(table);
Stop = true;
}
catch (Exception e2) {
System.out.println("wrong format");
break;
}
} else { //添加订单
int number = Integer.parseInt(LineArray[0]);
int portion = Integer.parseInt(LineArray[2]);
int num = Integer.parseInt(LineArray[3]);
if ((3<portion && portion<10)|| portion<1) {
System.out.println(number + " portion out of range " + portion);
if (num>15) {
System.out.println(number + " num out of range " + num);
}
continue;
}
if (portion>=10) {
System.out.println("not a valid time period");
if (num>15) {
System.out.println(number + " num out of range " + num);
}
continue;
}
if (num>15) {
System.out.println(number + " num out of range " + num);
continue;
}
record = new Record(number, LineArray[1], portion, num); //初始化单位record的序号,菜名,份额,数量
if (menu.searchDish(LineArray[1]) != null) { //有该菜
Record oop = table.order.find_ByName(LineArray[1]); //查看Order中是否有该菜名的Record
if (oop!=null && oop.portion == portion) { //如果有该菜名的Record并且portion相等
oop.num += num;
continue;
}
record.d = menu.searchDish(LineArray[1]); //获得该菜名的Dish类
table.order.addARecord(record); //答案在if的前面???
int under_number = table.order.records.size()-1; //存储最后一个的table的下标
//往record中添加菜品,提供单价
//在record里面添加菜品的单价和名字
table.order.records.get(under_number).d = menu.searchDish(LineArray[1]);
//获取record的单个总价
int price = table.order.records.get(under_number).getPrice();
//输出单个record的表出
System.out.println(table.order.records.get(under_number).orderNum + " " +
LineArray[1] + " " +price);
}
}
//continue;
}
else if (LineArray.length == 5) { //代点菜
try {
int number = Integer.parseInt(LineArray[1]);
int portion = Integer.parseInt(LineArray[3]);
int num = Integer.parseInt(LineArray[4]);
record = new Record(number, LineArray[2], portion, num);
if (menu.searchDish(LineArray[2])!=null) { //菜单内有该菜品
//添加record
table.order.addARecord(record);
int under_number = table.order.records.size()-1;
//设定record的菜品单价
table.order.records.get(under_number).d = menu.searchDish(LineArray[2]);
int price = table.order.records.get(under_number).getPrice();
System.out.println(number + " table " + table.num + " pay for table " + LineArray[0] + price);
}
}
catch (Exception e2){
System.out.println("wrong format");
break;
}
}
}
for (int i = 0 ; i < tables.size() ; i++) {
tables.get(i).GetToTalPrice();
}
}
}
// 菜品类:对应菜谱上一道菜的信息。
class Dish { //封装
Dish() { } //空构造器
Dish(String dishName) {
this.name = dishName;
}
Dish(String dishName , int unit_price) {
this.name = dishName;
this.unit_price = unit_price;
} //普通菜的构造器
Dish(String dishName , int unit_price , String pp) {
this.name = dishName;
this.unit_price = unit_price;
if (pp.equals("T")) {
TT = true;
}
} //特色菜的构造器
private String name;//菜品名称
private int unit_price; //单价
private boolean TT = false; //特色菜标志
public int getPrice(int portion) {
double[] size = {1,1.5,2};
double Price = 0;
switch (portion) {
case 1:
Price = this.unit_price * size[0];
break;
case 2:
Price = this.unit_price * size[1];
break;
case 3:
Price = this.unit_price * size[2];
break;
default:;
}
return ((int)Math.round(Price));
}//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }
//封装的读取器
public String getName() {
return name;
}//读取Name
public int getUnit_price() {
return unit_price;
}//读取单价
public boolean getTT() {
return TT;
}// 读取特色菜的标志
public void setUnit_price(int unit_price) {
this.unit_price = unit_price;
} //重新定义单价
}
//菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
class Menu {
Menu() {
}
ArrayList<Dish> dishes = new ArrayList<>(); //菜品数组,保存所有菜品信息
public Dish searchDish(String dishName) {
boolean find = false;
for (Dish dish : dishes){
if (dish.getName().equals(dishName)) {
find = true;
return dish;
} //如果找到就返回dish的类信息
}
System.out.println(dishName + " does not exist");
return null; //没有就返回null,用于判断是否找到
}//根据菜名在菜谱中查找菜品信息,返回Dish对象。
public void addDish(Dish dish) { //开始为返回Dish类???为什么???
if (search(dish.getName())) {
Dish pp = searchDish(dish.getName());
pp.setUnit_price(dish.getUnit_price());
}//如果发现有该菜品则重新定义该单价
else {
dishes.add(dish);
}//没有发现则直接加入dishes列表里面去
} //添加一道菜品信息
public boolean search(String dishName) {
boolean find = false;
for (Dish dish : dishes){
if (dish.getName().equals(dishName)) {
find = true;
break;
} //如果找到就返回boolean
}
return find;
}//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}
//希望能够实现存储每一个table的基本信息
//包括该table的订单和记录
class Table {
ArrayList<Integer> deletes = new ArrayList<>();
Menu menu = new Menu();
int num;//座序号
// int sum = 0;//总价钱
Calendar data = Calendar.getInstance();//时间
Order order;//订单
Record record;//记录
double discount = -1;
int year,month,day,hours,minute,second; //时间存储Date的参数
int week; //用来存储星期数目的
boolean time_error = false; //保存time的格式对错
Table(String num , String Day , String Time,Menu menu) {
this.num = Integer.parseInt(num); //保存序号
String[] dataString = Day.split("/"); //保存日期
this.year = Integer.parseInt(dataString[0]);
this.month = Integer.parseInt(dataString[1]);
this.day = Integer.parseInt(dataString[2]);
String[] timeString = Time.split("/"); //保存时间
this.hours = Integer.parseInt(timeString[0]);
this.minute = Integer.parseInt(timeString[1]);
this.second = Integer.parseInt(timeString[2]);
try {
for (int i = 0 ; i < 3 ; i++) {
if (timeString[i].length()>2) {
time_error = true;
break;
}
}
if (year%1000==0) {
System.out.println(num + " date error");
}
else {
Calendar data_start = Calendar.getInstance();
data_start.set(2022,1,1);
Calendar data_end = Calendar.getInstance();
data_end.set(2023,12,31);
data.set(year,month,day,hours,minute,second);
if (data.after(data_end) || data.before(data_start)) {
System.out.println("not a valid time period");
}
else {
boolean isFirstSunday = (data.getFirstDayOfWeek() == Calendar.SUNDAY);
week = data.get(Calendar.DAY_OF_WEEK);
//若一周第一天为星期天,则-1
if(isFirstSunday){
week = week - 1;
if(week == 0){
week = 7;
}
}
order = new Order(); //同时构造Order类和Record类
record = new Record();
this.menu = menu;
}
}
}
catch (Exception e1) {
System.out.println(num + " date error");
}
}
public void GetToTalPrice() {
if (discount<0) { //没有折扣,说明不在营业时间之内
System.out.println("table " + num + " out of opening hours");
}
else { //有折扣,说明在营业时间之内
int primer_uuu = 0;
int uuu = 0;
for (int i = 0 ; i < order.records.size() ; i++) {
if (!deletes.contains(order.records.get(i).orderNum)) { //把没有删除的进行相加
primer_uuu = primer_uuu + order.records.get(i).getPrice();
if (order.records.get(i).d.getTT()) { //是特色菜,特别处理折扣
uuu = uuu + (int)Math.round(primer_uuu * 0.7);
}
else { //不是特色菜
uuu = uuu + (int)Math.round(primer_uuu * discount);
}
}
}
// int sum_primer = (int)sum;
// sum = (int)Math.round(sum*discount);
System.out.println("table " + num + ": " + primer_uuu + " " + uuu);
}
}
public void Discount() {
if (week>=1 && week<=5) { //在工作日的时间内
if (hours>=17 && hours<20) {
discount = 0.8;
}
else if (hours==20 && minute<30){
discount = 0.8;
}
else if (hours==20 && minute==30 && second==0){
discount = 0.8;
}
else if ((hours>=11 && hours <=13) || (hours==10 && minute>=30)){
discount = 0.6;
}
else if (hours==14 && minute<30) {
discount = 0.6;
}
else if (hours==14 && minute==30 && second==0) {
discount = 0.6;
}
}
else { //周末
if (hours>=10 && hours<=20) {
discount = 1.0;
}
else if (hours==9 && minute>=30){
discount = 1.0;
}
else if ((hours==21 && minute<30) || (hours==21 && minute==30 && second==0)){
discount = 1.0;
}
}
} //判断是否在营业的时间内
}
//订单类:保存用户点的所有菜的信息。
class Order {
Order() {} //构造器
ArrayList<Record> records = new ArrayList<>();//保存订单上每一道的记录
public int getTotalPrice() {
int sum = 0;
for (Record pp : records){
sum=sum+pp.getPrice();
}
return sum;
//打算放到Table里面进行相对应的Date判断,以便进行相对应的日期优惠!!!
//还是使用它,先计算总价位,再来对日期进行相对应的打折
}//计算订单的总价
public void addARecord(Record pp) { //原来为Record返回类型
records.add(pp);
}//添加一条菜品信息到订单中。
public void delARecordByOrderNum(int orderNum) { //例子为int类???
if (findRecordByNum(orderNum)) {
records.remove(find(orderNum));
}//找到删除
else {
System.out.println("delete error");
}//未找到则输出对应的信息
}//根据序号删除一条记录
public boolean findRecordByNum(int orderNum) { //原来为void类型
for (Record pp : records) {
if (pp.orderNum == orderNum) {
return true;
}
}
return false;
}//根据序号查找一条记录
public Record find (int orderNum) { //可以通过订单进行记录的查找
for (Record pp : records) {
if (pp.orderNum == orderNum) {
return pp;
}
}
return null;
}//返回对应的Record类
public Record find_ByName(String name) { //通过名字查找Order中的Record
for (Record pp : records) {
if (pp.d.getName().equals(name)){
return pp;
}
}
return null;
}
}
//点菜记录类:保存订单上的一道菜品记录
class Record {
Record(){
} //空构造器
Record(int orderNum,String dishName,int portion,int num) { //构造器
this.orderNum = orderNum;
this.portion = portion;
this.d = new Dish(dishName);
this.num = num;
setDish(dishName);
} //非空构造器
int orderNum;//序号
Dish d;//菜品
public void setDish(String dishName) {
d = new Dish(dishName);
}
int portion;//份额(1/2/3代表小/中/大份)
int num; //份数,用来存储份数
public int getPrice() {
int Price = 0;
Price = d.getPrice(portion)*num;
return Price;
}//计价,计算本条记录的价格,返回int单个菜品的总价
//注意这里是未打折的总价
}
菜单计价程序4相对于3又有了很多新增内容。
比菜单计价系列-3增加的异常情况:
1、菜谱信息与订单信息混合,应忽略夹在订单信息中的菜谱信息。输出:"invalid dish"
2、桌号所带时间格式合法(格式见输入格式部分说明,其中年必须是4位数字,月、日、时、分、秒可以是1位或2位数),数据非法,比如:2023/15/16 ,输出桌号+" date error"
3、同一桌菜名、份额相同的点菜记录要合并成一条进行计算,否则可能会出现四舍五入的误差。
4、重复删除,重复的删除记录输出"deduplication :"+序号。
5、代点菜时,桌号不存在,输出"Table number :"+被点菜桌号+" does not exist";本次作业不考虑两桌记录时间不匹配的情况。
6、菜谱信息中出现重复的菜品名,以最后一条记录为准。
7、如果有重复的桌号信息,如果两条信息的时间不在同一时间段,(时段的认定:周一到周五的中午或晚上是同一时段,或者周末时间间隔1小时(不含一小时整,精确到秒)以内算统一时段),此时输出结果按不同的记录分别计价。
8、重复的桌号信息如果两条信息的时间在同一时间段,此时输出结果时合并点菜记录统一计价。前提:两个的桌号信息的时间都在有效时间段以内。计算每一桌总价要先合并符合本条件的饭桌的点菜记录,统一计价输出。
9、份额超出范围(1、2、3)输出:序号+" portion out of range "+份额,份额不能超过1位,否则为非法格式,参照第13条输出。
10、份数超出范围,每桌不超过15份,超出范围输出:序号+" num out of range "+份数。份数必须为数值,最高位不能为0,否则按非法格式参照第16条输出。
11、桌号超出范围[1,55]。输出:桌号 +" table num out of range",桌号必须为1位或多位数值,最高位不能为0,否则按非法格式参照第16条输出。
12、菜谱信息中菜价超出范围(区间(0,300)),输出:菜品名+" price out of range "+价格,菜价必须为数值,最高位不能为0,否则按非法格式参照第16条输出。
13、时间输入有效但超出范围[2022.1.1-2023.12.31],输出:"not a valid time period"
14、一条点菜记录中若格式正确,但数据出现问题,如:菜名不存在、份额超出范围、份数超出范围,按记录中从左到右的次序优先级由高到低,输出时只提示优先级最高的那个错误。
15、每桌的点菜记录的序号必须按从小到大的顺序排列(可以不连续,也可以不从1开始),未按序排列序号的输出:"record serial number sequence error"。当前记录忽略。(代点菜信息的序号除外)
16、所有记录其它非法格式输入,统一输出"wrong format"
17、如果记录以“table”开头,对应记录的格式或者数据不符合桌号的要求,那一桌下面定义的所有信息无论正确或错误均忽略,不做处理。如果记录不是以“table”开头,比如“tab le 55 2023/3/2 12/00/00”,该条记录认为是错误记录,后面所有的信息并入上一桌一起计算。
比菜单计价系列-3增加的功能:
菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+基础价格+"T"
例如:麻婆豆腐 9 T
菜价的计算方法:
周一至周五 7折, 周末全价。
注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价:
计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。
最后将所有记录的菜价累加得到整桌菜的价格。
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.Calendar;
import java.util.Date;
public class Main {
public static void main(String[] args) {
Work work = new Work();
work.play();
}
}
class Work {
boolean Stop = false; //用来确定订单和菜单混杂在一起的情况
Menu menu; //单位菜单
Record record; //单位记录
Table table; //单位座位
ArrayList<Table> tables = new ArrayList<>(); //座位数组
Work() { //初始化,用来创建基本的类数组
//只能用一个菜单,别单位化
//对所有的table都开放
menu = new Menu();
//单位化,订单? Record应该是必须得单位化
record = new Record();
//定义一个存储Table的一个ArrayList —— tables的动态数组
tables = new ArrayList<>();
}
public void play() { //play 菜单程序主要运行的程序
Scanner in = new Scanner(System.in);
while (true) {
String Line = in.nextLine();
if (Line.equals("end")) {
break;
}
String[] LineArray = Line.split(" ");
if (LineArray.length == 2) { //一个空格
if (LineArray[1].equals("delete")) { //删除订单
int num = Integer.parseInt(LineArray[0]);
if (table.deletes.contains(num)) {
System.out.println("deduplication " + num);
continue;
}
else {
Record pp =table.order.find(num);
table.order.delARecordByOrderNum(num);
table.deletes.add(num);
}
} else { //菜单添加
if (!Stop) { //菜单还没有输出完
try {
int x = Integer.parseInt(LineArray[1]);
}
catch (Exception e1) {
System.out.println("wrong format");
continue;
}
Dish dish = new Dish(LineArray[0],Integer.parseInt(LineArray[1]));
menu.addDish(dish);
}
else {
System.out.println("invalid dish");
}
}
//continue;
}
else if (LineArray.length == 3) {
if (LineArray[2].equals("T")) { //特色菜
Dish dish = new Dish(LineArray[0],Integer.parseInt(LineArray[1]),LineArray[2]);
menu.addDish(dish);
}
}
else if (LineArray.length == 4) { //三个空格,四个数据
if (LineArray[0].equals("table")) { //座号
try {
table = new Table(LineArray[1], LineArray[2], LineArray[3],menu);
if (table.time_error) {
int yy = Integer.parseInt(LineArray[2]); //用来故意报错
}
table.Discount(); //设定该table的折扣
System.out.println("table " + table.num + ": ");
tables.add(table);
Stop = true;
}
catch (Exception e2) {
System.out.println("wrong format");
break;
}
} else { //添加订单
int number = Integer.parseInt(LineArray[0]);
int portion = Integer.parseInt(LineArray[2]);
int num = Integer.parseInt(LineArray[3]);
if ((3<portion && portion<10)|| portion<1) {
System.out.println(number + " portion out of range " + portion);
if (num>15) {
System.out.println(number + " num out of range " + num);
}
continue;
}
if (portion>=10) {
System.out.println("not a valid time period");
if (num>15) {
System.out.println(number + " num out of range " + num);
}
continue;
}
if (num>15) {
System.out.println(number + " num out of range " + num);
continue;
}
record = new Record(number, LineArray[1], portion, num); //初始化单位record的序号,菜名,份额,数量
if (menu.searchDish(LineArray[1]) != null) { //有该菜
Record oop = table.order.find_ByName(LineArray[1]); //查看Order中是否有该菜名的Record
if (oop!=null && oop.portion == portion) { //如果有该菜名的Record并且portion相等
oop.num += num;
continue;
}
record.d = menu.searchDish(LineArray[1]); //获得该菜名的Dish类
table.order.addARecord(record); //答案在if的前面???
int under_number = table.order.records.size()-1; //存储最后一个的table的下标
//往record中添加菜品,提供单价
//在record里面添加菜品的单价和名字
table.order.records.get(under_number).d = menu.searchDish(LineArray[1]);
//获取record的单个总价
int price = table.order.records.get(under_number).getPrice();
//输出单个record的表出
System.out.println(table.order.records.get(under_number).orderNum + " " +
LineArray[1] + " " +price);
}
}
//continue;
}
else if (LineArray.length == 5) { //代点菜
try {
int number = Integer.parseInt(LineArray[1]);
int portion = Integer.parseInt(LineArray[3]);
int num = Integer.parseInt(LineArray[4]);
record = new Record(number, LineArray[2], portion, num);
if (menu.searchDish(LineArray[2])!=null) { //菜单内有该菜品
//添加record
table.order.addARecord(record);
int under_number = table.order.records.size()-1;
//设定record的菜品单价
table.order.records.get(under_number).d = menu.searchDish(LineArray[2]);
int price = table.order.records.get(under_number).getPrice();
System.out.println(number + " table " + table.num + " pay for table " + LineArray[0] + price);
}
}
catch (Exception e2){
System.out.println("wrong format");
break;
}
}
}
for (int i = 0 ; i < tables.size() ; i++) {
tables.get(i).GetToTalPrice();
}
}
}
// 菜品类:对应菜谱上一道菜的信息。
class Dish { //封装
Dish() { } //空构造器
Dish(String dishName) {
this.name = dishName;
}
Dish(String dishName , int unit_price) {
this.name = dishName;
this.unit_price = unit_price;
} //普通菜的构造器
Dish(String dishName , int unit_price , String pp) {
this.name = dishName;
this.unit_price = unit_price;
if (pp.equals("T")) {
TT = true;
}
} //特色菜的构造器
private String name;//菜品名称
private int unit_price; //单价
private boolean TT = false; //特色菜标志
public int getPrice(int portion) {
double[] size = {1,1.5,2};
double Price = 0;
switch (portion) {
case 1:
Price = this.unit_price * size[0];
break;
case 2:
Price = this.unit_price * size[1];
break;
case 3:
Price = this.unit_price * size[2];
break;
default:;
}
return ((int)Math.round(Price));
}//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }
//封装的读取器
public String getName() {
return name;
}//读取Name
public int getUnit_price() {
return unit_price;
}//读取单价
public boolean getTT() {
return TT;
}// 读取特色菜的标志
public void setUnit_price(int unit_price) {
this.unit_price = unit_price;
} //重新定义单价
}
//菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
class Menu {
Menu() {
}
ArrayList<Dish> dishes = new ArrayList<>(); //菜品数组,保存所有菜品信息
public Dish searchDish(String dishName) {
boolean find = false;
for (Dish dish : dishes){
if (dish.getName().equals(dishName)) {
find = true;
return dish;
} //如果找到就返回dish的类信息
}
System.out.println(dishName + " does not exist");
return null; //没有就返回null,用于判断是否找到
}//根据菜名在菜谱中查找菜品信息,返回Dish对象。
public void addDish(Dish dish) { //开始为返回Dish类???为什么???
if (search(dish.getName())) {
Dish pp = searchDish(dish.getName());
pp.setUnit_price(dish.getUnit_price());
}//如果发现有该菜品则重新定义该单价
else {
dishes.add(dish);
}//没有发现则直接加入dishes列表里面去
} //添加一道菜品信息
public boolean search(String dishName) {
boolean find = false;
for (Dish dish : dishes){
if (dish.getName().equals(dishName)) {
find = true;
break;
} //如果找到就返回boolean
}
return find;
}//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}
//希望能够实现存储每一个table的基本信息
//包括该table的订单和记录
class Table {
ArrayList<Integer> deletes = new ArrayList<>();
Menu menu = new Menu();
int num;//座序号
// int sum = 0;//总价钱
Calendar data = Calendar.getInstance();//时间
Order order;//订单
Record record;//记录
double discount = -1;
int year,month,day,hours,minute,second; //时间存储Date的参数
int week; //用来存储星期数目的
boolean time_error = false; //保存time的格式对错
Table(String num , String Day , String Time,Menu menu) {
this.num = Integer.parseInt(num); //保存序号
String[] dataString = Day.split("/"); //保存日期
this.year = Integer.parseInt(dataString[0]);
this.month = Integer.parseInt(dataString[1]);
this.day = Integer.parseInt(dataString[2]);
String[] timeString = Time.split("/"); //保存时间
this.hours = Integer.parseInt(timeString[0]);
this.minute = Integer.parseInt(timeString[1]);
this.second = Integer.parseInt(timeString[2]);
try {
for (int i = 0 ; i < 3 ; i++) {
if (timeString[i].length()>2) {
time_error = true;
break;
}
}
if (year%1000==0) {
System.out.println(num + " date error");
}
else {
Calendar data_start = Calendar.getInstance();
data_start.set(2022,1,1);
Calendar data_end = Calendar.getInstance();
data_end.set(2023,12,31);
data.set(year,month,day,hours,minute,second);
if (data.after(data_end) || data.before(data_start)) {
System.out.println("not a valid time period");
}
else {
boolean isFirstSunday = (data.getFirstDayOfWeek() == Calendar.SUNDAY);
week = data.get(Calendar.DAY_OF_WEEK);
//若一周第一天为星期天,则-1
if(isFirstSunday){
week = week - 1;
if(week == 0){
week = 7;
}
}
order = new Order(); //同时构造Order类和Record类
record = new Record();
this.menu = menu;
}
}
}
catch (Exception e1) {
System.out.println(num + " date error");
}
}
public void GetToTalPrice() {
if (discount<0) { //没有折扣,说明不在营业时间之内
System.out.println("table " + num + " out of opening hours");
}
else { //有折扣,说明在营业时间之内
int primer_uuu = 0;
int uuu = 0;
for (int i = 0 ; i < order.records.size() ; i++) {
if (!deletes.contains(order.records.get(i).orderNum)) { //把没有删除的进行相加
primer_uuu = primer_uuu + order.records.get(i).getPrice();
if (order.records.get(i).d.getTT()) { //是特色菜,特别处理折扣
uuu = uuu + (int)Math.round(primer_uuu * 0.7);
}
else { //不是特色菜
uuu = uuu + (int)Math.round(primer_uuu * discount);
}
}
}
// int sum_primer = (int)sum;
// sum = (int)Math.round(sum*discount);
System.out.println("table " + num + ": " + primer_uuu + " " + uuu);
}
}
public void Discount() {
if (week>=1 && week<=5) { //在工作日的时间内
if (hours>=17 && hours<20) {
discount = 0.8;
}
else if (hours==20 && minute<30){
discount = 0.8;
}
else if (hours==20 && minute==30 && second==0){
discount = 0.8;
}
else if ((hours>=11 && hours <=13) || (hours==10 && minute>=30)){
discount = 0.6;
}
else if (hours==14 && minute<30) {
discount = 0.6;
}
else if (hours==14 && minute==30 && second==0) {
discount = 0.6;
}
}
else { //周末
if (hours>=10 && hours<=20) {
discount = 1.0;
}
else if (hours==9 && minute>=30){
discount = 1.0;
}
else if ((hours==21 && minute<30) || (hours==21 && minute==30 && second==0)){
discount = 1.0;
}
}
} //判断是否在营业的时间内
}
//订单类:保存用户点的所有菜的信息。
class Order {
Order() {} //构造器
ArrayList<Record> records = new ArrayList<>();//保存订单上每一道的记录
public int getTotalPrice() {
int sum = 0;
for (Record pp : records){
sum=sum+pp.getPrice();
}
return sum;
//打算放到Table里面进行相对应的Date判断,以便进行相对应的日期优惠!!!
//还是使用它,先计算总价位,再来对日期进行相对应的打折
}//计算订单的总价
public void addARecord(Record pp) { //原来为Record返回类型
records.add(pp);
}//添加一条菜品信息到订单中。
public void delARecordByOrderNum(int orderNum) { //例子为int类???
if (findRecordByNum(orderNum)) {
records.remove(find(orderNum));
}//找到删除
else {
System.out.println("delete error");
}//未找到则输出对应的信息
}//根据序号删除一条记录
public boolean findRecordByNum(int orderNum) { //原来为void类型
for (Record pp : records) {
if (pp.orderNum == orderNum) {
return true;
}
}
return false;
}//根据序号查找一条记录
public Record find (int orderNum) { //可以通过订单进行记录的查找
for (Record pp : records) {
if (pp.orderNum == orderNum) {
return pp;
}
}
return null;
}//返回对应的Record类
public Record find_ByName(String name) { //通过名字查找Order中的Record
for (Record pp : records) {
if (pp.d.getName().equals(name)){
return pp;
}
}
return null;
}
}
//点菜记录类:保存订单上的一道菜品记录
class Record {
Record(){
} //空构造器
Record(int orderNum,String dishName,int portion,int num) { //构造器
this.orderNum = orderNum;
this.portion = portion;
this.d = new Dish(dishName);
this.num = num;
setDish(dishName);
} //非空构造器
int orderNum;//序号
Dish d;//菜品
public void setDish(String dishName) {
d = new Dish(dishName);
}
int portion;//份额(1/2/3代表小/中/大份)
int num; //份数,用来存储份数
public int getPrice() {
int Price = 0;
Price = d.getPrice(portion)*num;
return Price;
}//计价,计算本条记录的价格,返回int单个菜品的总价
//注意这里是未打折的总价
}
而菜单计价程序5又与4不同,我就不多加赘述了。
其中考试的相关题目因为没有权限,依靠记忆也实在太扯,我相信大多数人应该跟我一样不想搞,我就偷一下懒。
(3)踩坑心得
要说踩坑我最觉得无语的地方还是期中考试的测试1,主要问题是测试点的精度问题,在Π的问题上我分别试了3.14,3.14159,3.1415926,因为我不知道Π该怎么打,所以用了笨办法,结果精度不够,3.1415926只能半对,要完成·测试点需要更高的精度。。。
测试2,3,4的话都没有什么坑人的地方,圆的精度问题也没那么离谱,在这就不详谈了。
说回菜单计价程序4,5,主要问题还是难,以及复杂,说多了都是泪。
(4)改进建议
改进建议还是一样,去学习自己没学会学懂的地方,以及多使用不同类对各功能进行区分,对之后修改代码更便利。有能力的可以画类图,看得懂,会用的话很好用。
(5)总结
这句话我每次都会说,一个课题学完了为什么不把标准示例给出来呢?留着过年嘛?菜单计价程序难度本来就高,一次落下了我都不知道之后怎么赶回来,还一个劲的加大难度,嫌我们si得不够彻底是吧。

浙公网安备 33010602011771号