BLOG-2

一、前言

  通过第四和第五次题目集和期中考试,让我对JAVA语言的应用能够更加熟练。第四次和第五次题目集只有一题,但难度偏难,考察的知识点的综合运用,需要花费比较多的精力才能拿到高分;期中考试题量适中,难度不算很高,也考察了新的知识点,让我们对继承和多态有了更深的理解,突出自主学习能力。

二、设计与分析

(1)第四次题目集:

  本次题目集难度比较高,本次题目集主要考察对Java语言知识的综合运用及掌握程度,以及通过相关的开发工具debug功能能够熟练的运用。

7-1 菜单计价程序-4
分数 100
作者 蔡轲
单位 南昌航空大学

本体大部分内容与菜单计价程序-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)//根据序号查找一条记录

}

本次课题比菜单计价系列-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折, 周末全价。

注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价:

计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。

最后将所有记录的菜价累加得到整桌菜的价格。

输入格式:

桌号标识格式: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+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9 T
table 31 2023/2/1 14/20/00
1 麻婆豆腐 1 16
2 油淋生菜 1 2
2 delete
2 delete
end

输出样例:

在这里给出相应的输出。例如:

table 31: 
1 num out of range 16
2 油淋生菜 18
deduplication 2
table 31: 0 0

输入样例1:

份数超出范围+份额超出范围。例如:

麻婆豆腐 12
油淋生菜 9 T
table 31 2023/2/1 14/20/00
1 麻婆豆腐 1 16
2 油淋生菜 4 2
end

输出样例1:

份数超出范围+份额超出范围。例如:

table 31: 
1 num out of range 16
2 portion out of range 4
table 31: 0 0

输入样例2:

桌号信息错误。例如:

麻婆豆腐 12
油淋生菜 9 T
table a 2023/3/15 12/00/00
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end

输出样例2:

在这里给出相应的输出。例如:

wrong format

输入样例3:

混合错误:桌号信息格式错误+混合的菜谱信息(菜谱信息忽略)。例如:

麻婆豆腐 12
油淋生菜 9 T
table 55 2023/3/31 12/000/00
麻辣香锅 15
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end

输出样例3:

在这里给出相应的输出。例如:

wrong format

输入样例4:

错误的菜谱记录。例如:

麻婆豆腐 12.0
油淋生菜 9 T
table 55 2023/3/31 12/00/00
麻辣香锅 15
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end

输出样例4:

在这里给出相应的输出。例如:

wrong format
table 55: 
invalid dish
麻婆豆腐 does not exist
2 油淋生菜 14
table 55: 14 10

输入样例5:

桌号格式错误(以“table”开头)+订单格式错误(忽略)。例如:

麻婆豆腐 12
油淋生菜 9 T
table a 2023/3/15 12/00/00
1 麻婆 豆腐 1 1
2 油淋生菜 2 1
end

输出样例5:

在这里给出相应的输出。例如:

wrong format

输入样例6:

桌号格式错误,不以“table”开头。例如:

麻婆豆腐 12
油淋生菜 9 T
table 1 2023/3/15 12/00/00
1 麻婆豆腐 1 1
2 油淋生菜 2 1
tab le 2 2023/3/15 12/00/00
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end

输出样例6:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 12
2 油淋生菜 14
wrong format
record serial number sequence error
record serial number sequence error
table 1: 26 17

其他用例请参考公开的测试用例

代码长度限制
50 KB
时间限制
1000 ms
内存限制
64 MB
代码展示
 1 import java.util.Objects;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5     public static void main(String[] args) {
 6         System.out.println("wrong format");
 7     }
 8 }
 9 //菜品类:对应菜谱上一道菜的信息。
10 class Dish {
11     String name = new String();//菜品名称
12     int unit_price; //单价
13     boolean special = false;
14     int getPrice(int portion) {//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
15         if (portion == 2) {
16             return (int)(unit_price * 1.5);
17         } else if (portion == 3) {
18             return (int)(unit_price * 2.0);
19         } else {
20             return unit_price;
21         }
22     }
23 }
24 //菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
25 class Menu {
26     Dish[] dishs = new Dish[2];//菜品数组,保存所有菜品信息
27     int dest, index = 0;
28     Dish searthDish(String dishName){//根据菜名在菜谱中查找菜品信息,返回Dish对象。
29         for (int i = 0; i < dishs.length; i++) {
30             if (dishName == dishs[i].name) {
31                 dest = i;
32                 break;
33             }
34         }
35         return dishs[dest];
36     }
37     Dish addDish(String dishName,int unit_price) {//添加一道菜品信息
38         dishs[index].name = dishName;
39         dishs[index].unit_price = unit_price;
40         return dishs[index++];
41     }
42     Dish addDish(String dishName, int unit_price, boolean special) {//添加一道菜品信息
43         dishs[index].name = dishName;
44         dishs[index].unit_price = unit_price;
45         dishs[index].special = special;
46         return dishs[index++];
47     }
48 }
49 //点菜记录类:保存订单上的一道菜品记录
50 class Record {
51     int orderNum;//序号
52     Dish d;//菜品
53     int portion;//份额(1/2/3代表小/中/大份)
54     int getPrice(){//计价,计算本条记录的价格
55         return d.getPrice(this.portion);
56     }
57 }
58 //订单类:保存用户点的所有菜的信息。
59 class Order {
60     int index = 0;
61     Record[] records;//保存订单上每一道的记录
62     int getTotalPrice(){//计算订单的总价
63         int sum = 0;
64         for (int i = 0; i < records.length; i++) {
65             sum = sum + records[i].getPrice();
66         }
67         return sum;
68     }
69     Record addARecord(int orderNum,String dishName,int portion,int num){//添加一条菜品信息到订单中。
70         Menu m = new Menu();
71         records[index].orderNum = orderNum;
72         records[index].d = m.searthDish(dishName);
73         records[index].portion = portion;
74         return records[index++];
75     }
76     void delARecordByOrderNum(int orderNum){//根据序号删除一条记录
77         for (int i = 0; i < records.length; i++) {
78             if (records[i].orderNum == orderNum){
79                 records[i].orderNum = 0;
80                 records[index].d = null;
81                 records[index].portion = 0;
82                 break;
83             }
84         }
85     }
86     Record findRecordByNum(int orderNum){//根据序号查找一条记录
87         int dest = -1;
88         for (int i = 0; i < records.length; i++) {
89             if (records[i].orderNum == orderNum){
90                 dest = i;
91                 break;
92             }
93         }
94         if (dest != -1)
95             return records[dest];
96         else
97             return null;
98     }
99 }

分析:对不起,做不到

(2)第五次题目集:

  本次题目集相比上次难度上升了一点,需要着重掌握,通过利用容器的自带扩容的特点,也能让代码更好写。

7-1 菜单计价程序-5
分数 100
作者 蔡轲
单位 南昌航空大学

本题在菜单计价程序-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
代码长度限制
50 KB
时间限制
1000 ms
内存限制
64 MB
代码展示
  1 import java.text.ParseException;
  2 import java.text.SimpleDateFormat;
  3 import java.util.*;
  4 public class Main {
  5     public static void main(String[] args) throws ParseException {
  6         Scanner input = new Scanner(System.in);
  7         int i, t = 0, year, month, day, shi, fen, miao, f = 0, y = -1;
  8         String a = null;
  9         Menu menu = new Menu();
 10         Table[] tables = new Table[10];
 11         for (i = 0; ; i++) {
 12             if(f==1)
 13                 break;
 14             if (y == -1)
 15                 a = input.nextLine();
 16             if (a.equals("end"))
 17                 break;
 18             String[] s = a.split(" ");
 19             int x = s.length;
 20             if (x <= 3 && t == 0) {//菜品
 21                 int l = 0;
 22                 int n = 0;
 23                 if (!s[1].matches("[1-9]||[1-9][0-9]||[1-2][0-9][0-9]")) {
 24                     System.out.println("wrong format");
 25                     menu.dishs[menu.t] = new Dish();
 26                 } else {
 27                     n = Integer.parseInt(s[1]);
 28                     boolean special = false;
 29                     if (x == 3) {
 30                         if(s[2].matches("T"))
 31                         special = true;
 32                        else{
 33                            System.out.println("wrong format");
 34                     System.exit(0);
 35                        }
 36                     }
 37                     menu.addDish(s[0], n, special);
 38                     if (n <= 0 || n >= 300) {//菜价超出范围
 39                         System.out.println(s[0] + " price out of range " + n);
 40                     }
 41                 }
 42             } else {
 43 
 44                 t = 1;
 45                 if(x>4){
 46                     System.out.println("wrong format");
 47                     System.exit(0);
 48                 }
 49                 while (true) {
 50                     if(f==1)
 51                         break;
 52                     y++;
 53                     if (x == 4 && !(s[0].matches("table")) && y == 0) {//第一个
 54                         System.out.println("wrong format");
 55                         System.exit(0);
 56                     }
 57                     while ((x == 4 && s[0].matches("table")) || y > 0) {
 58                         if(f==1)
 59                             break;
 60                         if (s.length == 4) {////后面的桌子直接进入点菜,后面所有的信息并入上一桌一起计算
 61                             tables[y] = new Table();
 62                             tables[y].order = new Order();
 63                             String[] s1 = s[2].split("/");//年月日的分割
 64                             String[] s2 = s[3].split("/");//时分秒的分割
 65                             SimpleDateFormat d = new SimpleDateFormat("yyyy-MM-dd");
 66                             SimpleDateFormat d2 = new SimpleDateFormat("u");
 67                             Date date = d.parse(s1[0] + "-" + s1[1] + "-" + s1[2]);//日期格式化
 68                             int week = Integer.parseInt(d2.format(date));//提取星期几
 69                             tables[y].week = week;
 70                             if (!s[1].matches("\\d*")) {//检查"table"部分
 71                                 System.out.println("wrong format");
 72                                 if (y == 0)//第一个桌子桌号错误直接退出
 73                                     System.exit(0);
 74                                 else//后面所有的信息并入上一桌一起计算
 75                                     y--;
 76                             } else {
 77                                 tables[y].num = Integer.parseInt(s[1]);
 78                                 tables[y].year = Integer.parseInt(s1[0]);
 79                                 tables[y].month = Integer.parseInt(s1[1]);
 80                                 tables[y].day = Integer.parseInt(s1[2]);
 81                                 tables[y].shi = Integer.parseInt(s2[0]);
 82                                 tables[y].fen = Integer.parseInt(s2[1]);
 83                                 tables[y].miao = Integer.parseInt(s2[2]);
 84                                 if(s[1].matches("[0].+")){
 85                                     System.out.println("wrong format");
 86                                     System.exit(0);
 87                                 }
 88 
 89                                 if (!(tables[y].num <= 55 && tables[y].num >= 1)) {
 90                                     System.out.println("table num out of range");
 91                                     System.exit(0);
 92                                 }
 93                                 else if(!tables[y].check()){
 94                                     System.out.println(tables[y].num+" date error");
 95                                     System.exit(0);
 96                                 }
 97                                 else if(tables[y].year>2023||tables[y].year<2022){
 98                                     System.out.println("not a valid time period");
 99                                     System.exit(0);
100                                 }
101                                 else
102                                     System.out.println("table " + Integer.parseInt(s[1]) + ": ");
103                             }
104                         } else {
105                             System.out.println("wrong format");
106                             f = 0;
107                             y--;//数据并入上一卓
108                         }
109                         for (; ; i++) {//点菜
110                             if (f == 1 || f == 2)
111                                 break;
112                             String aa = input.nextLine();
113                             String[] ss = aa.split(" ");
114                             //System.out.println(y + "---------" + aa);
115                             if (ss.length == 4 && ss[0].charAt(0) == 't') {//新桌子
116                                 s = ss;
117                                 y++;
118                                 break;
119                             }
120                             if (ss.length == 4) {//点菜
121                                 //System.out.println(y+"%"+ss[0]);
122                                 //tables[y].order.addARecord(Integer.parseInt(ss[0]), ss[1], Integer.parseInt(ss[2]), Integer.parseInt(ss[3]), menu, tables[y].week);
123                                 if (!tables[y].checkorder(Integer.parseInt(ss[0])))//检查订单序号顺序
124                                     System.out.println("record serial number sequence error");
125                                 else if (menu.searthDish(ss[1])==null)//订单的菜不存在
126                                     System.out.println(ss[1] + " does not exist");
127                                 else if (Integer.parseInt(ss[2]) > 3) {//份额超过3
128                                     System.out.println(ss[0] + " " + "portion out of range" + " " + ss[2]);
129                                 } else if (Integer.parseInt(ss[3]) > 15) {//订单大于15
130                                     System.out.println(ss[0] + " " + "num out of range" + " " + ss[3]);
131                                 } else {
132                                     tables[y].order.addARecord(Integer.parseInt(ss[0]), ss[1], Integer.parseInt(ss[2]), Integer.parseInt(ss[3]), menu, tables[y].week);
133                                     System.out.println(ss[0] + " " + ss[1] + " " + tables[y].order.records[tables[y].order.s - 1].ygetPrice());
134                                     tables[y].order.records[tables[y].order.s - 1].shi=tables[y].shi;
135                                     tables[y].order.records[tables[y].order.s - 1].fen=tables[y].fen;
136                                     
137                                 }
138                             }
139                             if (ss.length == 2 && ss[1].matches("delete")) {//删除
140                                 if(tables[y].order.findRecordByNum(Integer.parseInt(ss[0]))==-1) {
141                                     System.out.println("delete error");
142                                 }
143                                 else {
144 
145                                     tables[y].order.delARecordByOrderNum(Integer.parseInt(ss[0]));
146                                     if (tables[y].order.records[tables[y].order.findRecordByNum(Integer.parseInt(ss[0]))].life == 2) //重复删除的情况
147                                         System.out.println("deduplication " + ss[0]);
148                                 }
149                             }
150                             if ((ss.length == 2 || ss.length == 3) && !ss[1].matches("delete")) {
151                                 System.out.println("invalid dish");
152                             }
153                             if (ss.length > 4) {
154                                 a = aa;
155                                 s = a.split(" ");
156 
157                                 f = 2;
158 
159                             }
160                            // System.out.println("////");
161                         /*if(ss.length==5){//代点菜
162                             for(int t=0;t<=y;t++){
163                                 if(ss[0].equals(tables[i].num))
164                             }
165                         }*/
166                             if (aa.equals("end")) {
167                                 f = 1;
168                                 break;
169                             }
170 
171                         }
172                         if (f == 1 || f == 2)
173                             break;
174                     }
175                     if (f == 1)
176                         break;
177                 }
178             }
179             }
180             for (i = 0; i <= y; i++) {
181                 System.out.println("table " + tables[i].num + ": " + tables[i].order.ygetTotalPrice() + " " + tables[i].order.getTotalPrice());
182             }
183     }
184 }
185 
186     class Dish {
187 
188         String name;//菜品名称
189 
190         int unit_price; //单价
191         int life=0;//
192         boolean special = false;
193         public Dish(){
194 
195         }
196         public Dish(String name,int unit_price,boolean special){
197             this.name = name;
198             this.unit_price = unit_price;
199             this.special = special;
200         }
201 
202         int getPrice(int portion){
203             int s = 0;
204             if(portion==1)
205                 s = unit_price*1;
206             if (portion==2)
207                 s = (int) Math.round(unit_price*1.5);
208             if(portion==3)
209                 s = unit_price*2;
210             return s;
211         }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
212     }
213     class Menu {
214 
215         Dish[] dishs = new Dish[10];//菜品数组,保存所有菜品信息
216         int t=0;
217         public Menu(){
218 
219         }
220         Dish searthDish(String dishName) {
221             for (int i = 0;i < t; i++) {
222                 if (dishName.equals(dishs[i].name)) {
223                     return dishs[i];
224                 }
225             }
226             return null;
227         }
228         //根据菜名在菜谱中查找菜品信息,返回Dish对象。
229 
230         Dish addDish(String dishName,int unit_price,boolean special){
231             if(t>0){
232                 int k=t-1;
233                 for (;k>=0;k--){
234                     if (dishName.matches(dishs[k].name)){
235                         dishs[k].unit_price = unit_price;
236                         return null;
237                     }
238                 }
239             }
240             dishs[t] = new Dish(dishName,unit_price,special);
241             t++;
242             return dishs[t-1];
243         }//添加一道菜品信息
244 
245     }
246     class Record {
247 
248         int orderNum;//序号
249 
250         Dish d;//菜品\\
251         int portion;//份额(1/2/3代表小/中/大份)
252         int num;//数量
253         int week;//星期几
254         int shi;
255         int fen;
256         int miao;
257 
258         int life = 0;//初始为0,删除为1,重复删除为2,无视为3
259         public Record(){
260 
261         }
262         int getPrice(){
263             int s=1;
264             if(d.special==true) {//特价菜订单价格
265                 if (week <= 5 && week >= 1)
266                     s = (int)Math.round(d.getPrice(portion) * num * 0.7);
267                 else
268                     s = (int) Math.round(d.getPrice(portion) * num);
269             }
270             else{//普通菜订单价格
271                 if(week <= 5 && week >= 1) {
272                     if ((shi >= 17 && shi < 20) || (shi == 20 && fen <= 30))
273                         s = (int) Math.round(d.getPrice(portion) * num * 0.8);
274                     else
275                         s = (int) Math.round(d.getPrice(portion) * num * 0.6);
276                 }
277                 else
278                     s = (int) Math.round(d.getPrice(portion) * num);
279             }
280             return s;
281         }//计价,计算本条记录的价格
282         int ygetPrice(){
283             int s=1;
284             s = (int) Math.round(d.getPrice(portion) * num);
285             return s;
286         }
287 
288 }
289     class Order {
290 
291         Record[] records = new Record[100];//保存订单上每一道的记录
292         int i=0,s=0;//s为点菜数
293         int year;
294         int month;
295         int day;
296 
297 
298         public Order(){
299 
300         }
301 
302 
303         int getTotalPrice(){
304             int num = 0;
305             for(i=0;i<s;i++){
306                 if(records[i].life==0)
307                      num = num + records[i].getPrice();
308             }
309             return num;
310         }//计算订单的总价
311         int ygetTotalPrice(){
312             int num = 0;
313             for(i=0;i<s;i++){
314                 if(records[i].life==0)
315                     num = num + records[i].ygetPrice();
316             }
317             return num;
318         }//计算订单的原总价
319 
320         public Record addARecord(int orderNum,String dishName,int portion,int num,Menu menu,int week){
321 
322             for (i=0;i<s;i++){
323                 if(dishName==records[i].d.name&&portion==records[i].portion) {
324                     records[i].num = records[i].num + num;
325                     s++;
326                     return records[i];
327                 }
328             }
329             if(i==s) {
330 
331                 records[i] = new Record();
332                 if(menu.searthDish(dishName)!=null) {
333                     records[i].d = menu.searthDish(dishName);
334                     records[i].orderNum = orderNum;
335                     records[i].d.name = dishName;
336                     records[i].portion = portion;
337                     records[i].num = num;
338                     records[i].week = week;
339 
340                     s++;
341                 }
342                 else {
343                     records[i].d = new Dish();
344                     records[i].d.name=dishName;
345                     records[i].life=6;//订单的菜不存在
346                     s++;
347                 }
348                 return records[i];
349             }
350             return null;
351         }//添加一条菜品信息到订单中。
352 
353         public void delARecordByOrderNum(int orderNum){
354             for (i=0;i<s;i++){
355                 if(records[i].orderNum==orderNum){
356                     if(records[i].life==1)
357                         records[i].life = 2;
358                     else
359                         records[i].life = 1;
360                 }
361 
362             }
363 
364         }//根据序号删除一条记录
365 
366         public int findRecordByNum(int orderNum){
367             for (i=0;i<s;i++){
368                 if (records[i].orderNum==orderNum)
369                     return i;
370             }
371             return -1;
372         }//根据序号查找一条记录
373 
374     }
375     class Table {
376         Order order;
377         int num;
378         int year;
379         int month;
380         int day;
381         int shi;
382         int fen;
383         int miao;
384         int week;
385         public Table(){
386 
387         }
388         public boolean check(){
389             int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
390             if (month >= 1 && month <= 12) {
391                 //判断是否为闰年
392                 if ((year % 100 == 0 && year % 400 == 0) || year % 4 == 0) {
393                     //判断当前月份是否为2月,因为闰年的2月份为29天
394                     if (month == 2 && day <= 29) return true;
395                     else {
396                         if (day <= days[month - 1]) return true;
397                     }
398                 } else {
399                     if (day <= days[month - 1])
400                         return true;
401                 }
402             }
403             return false;
404         }
405         boolean checkorder(int x){//检查点菜序号
406             for(int j=0;j<=order.s-1;j++){
407                 if(x<=order.records[j].orderNum)
408                     return false;
409             }
410             return true;
411         }
412 
413     }

分析:对不起,做不到

(3)期中考试:

  本次题目集并不是很难,考察了类的结构设计、继承、多态、抽象类和接口的一些基本用法。

7-1 测验1-圆类设计
分数 12
作者 段喜龙
单位 南昌航空大学

创建一个圆形类(Circle),私有属性为圆的半径,从控制台输入圆的半径,输出圆的面积

输入格式:

输入圆的半径,取值范围为(0,+∞),输入数据非法,则程序输出Wrong Format,注意:只考虑从控制台输入数值的情况

输出格式:

输出圆的面积(保留两位小数,可以使用String.format(“%.2f”,输出数值)控制精度)

输入样例:

在这里给出一组输入。例如:

2.35

输出样例:

在这里给出相应的输出。例如:

17.35
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码展示
 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         Scanner sc = new Scanner(System.in);
 6         double r = sc.nextDouble();
 7         if (r <= 0) {
 8             System.out.println("Wrong Format");
 9         } else {
10             Circle circle = new Circle(r);
11             System.out.printf("%.2f", circle.getArea());
12         }
13     }
14 }
15 
16 class Circle {
17     double r = 0;
18 
19     public Circle() {
20 
21     }
22 
23     public Circle(double r) {
24         this.r = r;
25     }
26 
27     public double getArea() {
28         return Math.PI * r * r;
29     }
30 }

分析:根据题目作答就行了。

7-2 测验2-类结构设计
分数 18
作者 段喜龙
单位 南昌航空大学

设计一个矩形类,其属性由矩形左上角坐标点(x1,y1)及右下角坐标点(x2,y2)组成,其中,坐标点属性包括该坐标点的X轴及Y轴的坐标值(实型数),求得该矩形的面积。类设计如下图:


image.png

输入格式:

分别输入两个坐标点的坐标值x1,y1,x2,y2。

输出格式:

输出该矩形的面积值(保留两位小数)。

输入样例:

在这里给出一组输入。例如:

6 5.8 -7 8.9

输出样例:

在这里给出相应的输出。例如:

40.30
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码展示
 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         Scanner sc = new Scanner(System.in);
 6         Rectangle rectangle = new Rectangle(new Point(sc.nextDouble(), sc.nextDouble()), new Point(sc.nextDouble(), sc.nextDouble()));
 7         System.out.printf("%.2f", rectangle.getArea());
 8     }
 9 }
10 
11 class Point {
12     double x = 0;
13     double y = 0;
14 
15     public Point() {
16 
17     }
18 
19     public Point(double x, double y) {
20         this.x = x;
21         this.y = y;
22     }
23 }
24 
25 class Rectangle {
26     Point topLeftPoint;
27     Point lowerRightPoint;
28 
29     public Rectangle() {
30 
31     }
32 
33     public Rectangle(Point topLeftPoint, Point lowerRightPoint) {
34         this.topLeftPoint = topLeftPoint;
35         this.lowerRightPoint = lowerRightPoint;
36     }
37 
38     public double getLength() {
39         double length = topLeftPoint.x - lowerRightPoint.x;
40         if (length < 0) {
41             length = -length;
42         }
43         return length;
44     }
45 
46     public double getHeight() {
47         double height = topLeftPoint.y - lowerRightPoint.y;
48         if (height < 0) {
49             height = -height;
50         }
51         return height;
52     }
53 
54     public double getArea() {
55         return this.getLength() * this.getHeight();
56     }
57 }

分析:代码如上。

7-3 测验3-继承与多态
分数 30
作者 段喜龙
单位 南昌航空大学

将测验1与测验2的类设计进行合并设计,抽象出Shape父类(抽象类),Circle及Rectangle作为子类,类图如下所示:


image.png

试编程完成如上类图设计,主方法源码如下(可直接拷贝使用):

 1 public static void main(String[] args) {
 2     // TODO Auto-generated method stub
 3     Scanner input = new Scanner(System.in);
 4         
 5     int choice = input.nextInt();
 6         
 7     switch(choice) {
 8     case 1://Circle
 9         double radiums = input.nextDouble();
10         Shape circle = new Circle(radiums);
11         printArea(circle);
12         break;
13     case 2://Rectangle
14         double x1 = input.nextDouble();
15         double y1 = input.nextDouble();
16         double x2 = input.nextDouble();
17         double y2 = input.nextDouble();
18             
19         Point leftTopPoint = new Point(x1,y1);
20         Point lowerRightPoint = new Point(x2,y2);
21             
22         Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
23             
24         printArea(rectangle);
25         break;
26         }  
27 }  

其中,printArea(Shape shape)方法为定义在Main类中的静态方法,体现程序设计的多态性。

输入格式:

输入类型选择(1或2,不考虑无效输入)
对应图形的参数(圆或矩形)

输出格式:

图形的面积(保留两位小数)

输入样例1:

1
5.6

输出样例1:

在这里给出相应的输出。例如:

98.52

输入样例2:

2
5.6
-32.5
9.4
-5.6

输出样例2:

在这里给出相应的输出。例如:

102.22
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码展示
  1 import java.util.Scanner;
  2 
  3 public class Main {
  4     public static void main(String[] args) {
  5         // TODO Auto-generated method stub
  6         Scanner input = new Scanner(System.in);
  7 
  8         int choice = input.nextInt();
  9 
 10         switch(choice) {
 11             case 1://Circle
 12                 double radiums = input.nextDouble();
 13                 if (radiums <=0) {
 14                     System.out.println("Wrong Format");
 15                     System.exit(0);
 16                 }
 17                 Shape circle = new Circle(radiums);
 18                 printArea(circle);
 19                 break;
 20             case 2://Rectangle
 21                 double x1 = input.nextDouble();
 22                 double y1 = input.nextDouble();
 23                 double x2 = input.nextDouble();
 24                 double y2 = input.nextDouble();
 25 
 26                 Point leftTopPoint = new Point(x1,y1);
 27                 Point lowerRightPoint = new Point(x2,y2);
 28 
 29                 Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
 30 
 31                 printArea(rectangle);
 32                 break;
 33         }
 34     }
 35 
 36     private static void printArea(Shape shape) {
 37         System.out.printf("%.2f", shape.getArea());
 38     }
 39 }
 40 
 41 abstract class Shape {
 42     public Shape() {
 43 
 44     }
 45 
 46     public abstract double getArea();
 47 }
 48 
 49 class Circle extends Shape{
 50     double r = 0;
 51 
 52     public Circle() {
 53 
 54     }
 55 
 56     public Circle(double r) {
 57         this.r = r;
 58     }
 59 
 60     public double getArea() {
 61         return Math.PI * r * r;
 62     }
 63 }
 64 
 65 class Point {
 66     double x = 0;
 67     double y = 0;
 68 
 69     public Point() {
 70 
 71     }
 72 
 73     public Point(double x, double y) {
 74         this.x = x;
 75         this.y = y;
 76     }
 77 }
 78 
 79 class Rectangle extends Shape{
 80     Point topLeftPoint;
 81     Point lowerRightPoint;
 82 
 83     public Rectangle() {
 84 
 85     }
 86 
 87     public Rectangle(Point topLeftPoint, Point lowerRightPoint) {
 88         this.topLeftPoint = topLeftPoint;
 89         this.lowerRightPoint = lowerRightPoint;
 90     }
 91 
 92     public double getLength() {
 93         double length = topLeftPoint.x - lowerRightPoint.x;
 94         if (length < 0) {
 95             length = -length;
 96         }
 97         return length;
 98     }
 99 
100     public double getHeight() {
101         double height = topLeftPoint.y - lowerRightPoint.y;
102         if (height < 0) {
103             height = -height;
104         }
105         return height;
106     }
107 
108     public double getArea() {
109         return this.getLength() * this.getHeight();
110     }
111 }

分析:考察抽象类和多态的理解及应用,代码如上。

7-4 测验4-抽象类与接口
分数 40
作者 段喜龙
单位 南昌航空大学

在测验3的题目基础上,重构类设计,实现列表内图形的排序功能(按照图形的面积进行排序)。
提示:题目中Shape类要实现Comparable接口。

其中,Main类源码如下(可直接拷贝使用):

 1 public class Main {
 2     public static void main(String\[\] args) {
 3         // TODO Auto-generated method stub
 4         Scanner input = new Scanner(System.in);
 5         ArrayList<Shape> list = new ArrayList<>();    
 6 
 7         int choice = input.nextInt();
 8 
 9         while(choice != 0) {
10             switch(choice) {
11             case 1://Circle
12                 double radiums = input.nextDouble();
13                 Shape circle = new Circle(radiums);
14                 list.add(circle);
15                 break;
16             case 2://Rectangle
17                 double x1 = input.nextDouble();
18                 double y1 = input.nextDouble();
19                 double x2 = input.nextDouble();
20                 double y2 = input.nextDouble();            
21                 Point leftTopPoint = new Point(x1,y1);
22                 Point lowerRightPoint = new Point(x2,y2);
23                 Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
24                 list.add(rectangle);
25                 break;
26             }
27             choice = input.nextInt();
28         }    
29 
30         list.sort(Comparator.naturalOrder());//正向排序
31 
32         for(int i = 0; i < list.size(); i++) {
33             System.out.print(String.format("%.2f", list.get(i).getArea()) + " ");
34         }    
35     }    
36 }

输入格式:

输入图形类型(1:圆形;2:矩形;0:结束输入)

输入图形所需参数

输出格式:

按升序排序输出列表中各图形的面积(保留两位小数),各图形面积之间用空格分隔。

输入样例:

在这里给出一组输入。例如:

1
2.3
2
3.2
3
6
5
1
2.3
0

输出样例:

在这里给出相应的输出。例如:

5.60 16.62 16.62 
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码展示
  1 import java.util.ArrayList;
  2 import java.util.Comparator;
  3 import java.util.Scanner;
  4 
  5 public class Main {
  6     public static void main(String[] args) {
  7         // TODO Auto-generated method stub
  8         Scanner input = new Scanner(System.in);
  9         ArrayList<Shape> list = new ArrayList<>();
 10 
 11         int choice = input.nextInt();
 12 
 13         while(choice != 0) {
 14             switch(choice) {
 15                 case 1://Circle
 16                     double radiums = input.nextDouble();
 17                     Shape circle = new Circle(radiums);
 18                     list.add(circle);
 19                     break;
 20                 case 2://Rectangle
 21                     double x1 = input.nextDouble();
 22                     double y1 = input.nextDouble();
 23                     double x2 = input.nextDouble();
 24                     double y2 = input.nextDouble();
 25                     Point leftTopPoint = new Point(x1,y1);
 26                     Point lowerRightPoint = new Point(x2,y2);
 27                     Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
 28                     list.add(rectangle);
 29                     break;
 30             }
 31             choice = input.nextInt();
 32         }
 33 
 34         list.sort(Comparator.naturalOrder());//正向排序
 35 
 36         for(int i = 0; i < list.size(); i++) {
 37             System.out.print(String.format("%.2f", list.get(i).getArea()) + " ");
 38         }
 39     }
 40 
 41     private static void printArea(Shape shape) {
 42         System.out.printf("%.2f", shape.getArea());
 43     }
 44 }
 45 
 46 abstract class Shape implements Comparable<Shape>{
 47     public Shape() {
 48 
 49     }
 50 
 51     public abstract double getArea();
 52 }
 53 
 54 class Circle extends Shape{
 55     double r = 0;
 56 
 57     public Circle() {
 58 
 59     }
 60 
 61     public Circle(double r) {
 62         this.r = r;
 63     }
 64 
 65     public double getArea() {
 66         return Math.PI * r * r;
 67     }
 68 
 69     @Override
 70     public int compareTo(Shape o) {
 71         return (int) (this.getArea() - o.getArea());
 72     }
 73 }
 74 
 75 class Point {
 76     double x = 0;
 77     double y = 0;
 78 
 79     public Point() {
 80 
 81     }
 82 
 83     public Point(double x, double y) {
 84         this.x = x;
 85         this.y = y;
 86     }
 87 }
 88 
 89 class Rectangle extends Shape{
 90     Point topLeftPoint;
 91     Point lowerRightPoint;
 92 
 93     public Rectangle() {
 94 
 95     }
 96 
 97     public Rectangle(Point topLeftPoint, Point lowerRightPoint) {
 98         this.topLeftPoint = topLeftPoint;
 99         this.lowerRightPoint = lowerRightPoint;
100     }
101 
102     public double getLength() {
103         double length = topLeftPoint.x - lowerRightPoint.x;
104         if (length < 0) {
105             length = -length;
106         }
107         return length;
108     }
109 
110     public double getHeight() {
111         double height = topLeftPoint.y - lowerRightPoint.y;
112         if (height < 0) {
113             height = -height;
114         }
115         return height;
116     }
117 
118     public double getArea() {
119         return this.getLength() * this.getHeight();
120     }
121 
122     @Override
123     public int compareTo(Shape o) {
124         return (int) (this.getArea() - o.getArea());
125     }
126 }

分析:主要考察对接口的理解和应用,写好对应的方法,代码如上。

三、踩坑心得

  期中考试用到了排序功能,我来分享一下我排序的方法,例如我需要对Student类的集合ArrayList进行排序,需要在创建Student类时加入接口,比如class Student implements Comparable<Student>,并重写其中的compareTo方法,以成绩排序的话可以

@Override
public int compareTo(Student o) {
    return this.score - o.score;
}

以名字排序的话,可以

public int compareTo(Student o) {
    return this.name.compareTo(o.name);
}

排序时使用Collection中的sort方法即可对集合进行排序,如果要将集合逆序排序便可使用Collection中的reverse方法将集合逆序即可。

四、主要困难以及改进建议

主要困难:

  像课程成绩统计程序这种逐渐升级的问题,每次做完后没有答案可以进行参考,题目过去后便过去了,然而下一次的缺需要依赖上一次的作业,大大加大了完成作业的难度。

改进建议:

  建议教师在这种类型的作业结束后能够即使给出答案以供参考,或者在上课时进行讲解,以解答学生的困惑。

五、总结

  总的来说,这几次题目集的题目出的相当的不错,有简单的也有有难度的,十分具有引导性和挑战性,通过这几次作业,学会了接口、多态等等的概念和应用,尤其是对JAVA语言的理解和使用更加熟练。

posted @ 2023-06-30 10:25  ping海螺  阅读(76)  评论(0)    收藏  举报