南航航空大学第二次BLOG
前言
这次从第一次题目难度开始,后面的数次难度激增,我也只有第一次全部写完pta的所有题目,后面就没有拿到过满分。但总体来说,主要知识点还是在设计类和学习java语言,以及用面向对象的思维方式。Java面向对象比c++更模块化,思维方式也不一样。对只接触过一点java语言的我们还是很有挑战的。还有一次期中考试,虽然难度不算大,但考察的内容很全面。
设计与分析
1.菜单计价程序-3
复杂度分析


类图

个人认为这是菜单系列的开端,后面的4和5都是在这一次的基础上进行的修改,并且这次的难度相对简单,代码结构相对清晰,在写的过程中没有遇到特别棘手的问题。
代码如下:
点击查看代码
import java.util.Scanner;
import java.util.Calendar;
class Dish {
String name;
int unit_price;
int getPrice(int portion) {
int price = 0;
if (portion == 1) {
price = unit_price;
} else if (portion == 2) {
price = Math.round((float) (unit_price * 1.5));
} else if (portion == 3) {
price = (unit_price * 2);
}
return price;
}
}
class Menu {
Dish[] dishes = new Dish[10];
int count = 0;
Dish searchDish(String dishName) {
Dish temp = null;
for (int i = count - 1; i >= 0; i--) {
if (dishName.equals(dishes[i].name)) {
temp = dishes[i];
break;
}
}
if (temp == null) {
System.out.println(dishName + " does not exist");
}
return temp;
}
Dish addDish(String dishName, int unit_price) {
Dish dish = new Dish();
dish.name = dishName;
dish.unit_price = unit_price;
count++;
return dish;
}
}
class Record {
int orderNum;
Dish dish = new Dish();
int num = 0;
int portion;
int getPrice() {
return dish.getPrice(portion) * num;
}
}
class Order {
Record[] records = new Record[10];
int count = 0; // 订单数量
void addRecord(int orderNum, String dishName, int portion, int num) {
records[count] = new Record();
records[count].dish.name = dishName;
records[count].orderNum = orderNum;
records[count].portion = portion;
records[count].num = num;
count++;
}
int deleteRecordByOrderNum(int orderNum) {
if (orderNum > count || orderNum <= 0) {
System.out.println("delete error;");
return 0;
} else {
return records[orderNum - 1].getPrice();
}
}
}
class Table {
int tableNum;
String tableDtime;
int year, month, day, week, hh, mm, ss;
int sum = 0;
Order order = new Order();
float discount = -1;
void getTotalPrice() {
if (discount > 0) {
sum = Math.round(sum * discount);
System.out.println("table " + tableNum + ": " + sum);
} else {
System.out.println("table " + tableNum + " out of opening hours");
}
}
void preProcess(String tableDtime) {
this.tableDtime = tableDtime;
processTime();
applyDiscount();
}
void processTime() {
String[] temp = tableDtime.split(" ");
tableNum = Integer.parseInt(temp[1]);
String[] temp1 = temp[2].split("/");
String[] temp2 = temp[3].split("/");
year = Integer.parseInt(temp1[0]);
month = Integer.parseInt(temp1[1]);
day = Integer.parseInt(temp1[2]);
Calendar c = Calendar.getInstance();
c.set(year, (month - 1), day);
week = c.get(Calendar.DAY_OF_WEEK);
if (week == 1)
week = 7;
else
week--;
hh = Integer.parseInt(temp2[0]);
mm = Integer.parseInt(temp2[1]);
ss = Integer.parseInt(temp2[2]);
}
void applyDiscount() {
if (week >= 1 && week <= 5) {
if (hh >= 17 && hh < 20)
discount = 0.8F;
else if (hh == 20 && mm < 30)
discount = 0.8F;
else if (hh == 20 && mm == 30 && ss == 0)
discount = 0.8F;
else if (hh >= 11 && hh <= 13 || hh == 10 && mm >= 30)
discount = 0.6F;
else if (hh == 14 && mm < 30)
discount = 0.6F;
else if (hh == 14 && mm == 30 && ss == 0)
discount = 0.6F;
} else {
if (hh >= 10 && hh <= 20)
discount = 1.0F;
else if (hh == 9 && mm >= 30)
discount = 1.0F;
else if (hh == 21 && mm < 30 || hh == 21 && mm == 30 && ss == 0)
discount = 1.0F;
}
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Menu menu = new Menu();
Table[] tables = new Table[10];
int menuCount = 0; // 菜单数
int orderCount = 0; // 订单数
Dish tempDish;
int tableNum = 0; // 桌号
int count;
String[] temp;
int a1, a2, a3, a4, a5;
while (true) {
String st = sc.nextLine();
temp = st.split(" ");
if (st.equals("end"))
break;
count = temp.length;
if (count == 2) {
if (temp[1].equals("delete")) {
a1 = Integer.parseInt(temp[0]);
int c = tables[tableNum].order.deleteRecordByOrderNum(a1);
tables[tableNum].sum -= c;
} else {
a2 = Integer.parseInt(temp[1]);
menu.dishes[menuCount] = menu.addDish(temp[0], a2);
menuCount++;
}
} else if (count == 4) {
if (temp[0].equals("table")) {
tableNum++;
orderCount = 0;
tables[tableNum] = new Table();
tables[tableNum].preProcess(st);
System.out.println("table " + tableNum + ": ");
} else {
a3 = Integer.parseInt(temp[0]);
a4 = Integer.parseInt(temp[2]);
a5 = Integer.parseInt(temp[3]);
tables[tableNum].order.addRecord(a3, temp[1], a4, a5);
tempDish = menu.searchDish(temp[1]);
if (tempDish != null) {
tables[tableNum].order.records[orderCount].dish = tempDish;
int a = tables[tableNum].order.records[orderCount].getPrice();
System.out.println(tables[tableNum].order.records[orderCount].orderNum + " " + tempDish.name + " " + a);
tables[tableNum].sum += a;
}
orderCount++;
}
} else if (count == 5) {
a1 = Integer.parseInt(temp[1]);
a2 = Integer.parseInt(temp[3]);
a3 = Integer.parseInt(temp[4]);
tables[tableNum].order.addRecord(a1, temp[2], a2, a3);
tempDish = menu.searchDish(temp[2]);
if (tempDish != null) {
tables[tableNum].order.records[orderCount].dish.unit_price = tempDish.unit_price;
int b = tables[tableNum].order.records[orderCount].getPrice();
System.out.println(temp[1] + " table " + tables[tableNum].tableNum + " pay for table " + temp[0] + " " + b);
tables[tableNum].sum += b;
}
orderCount++;
}
}
for (int i = 1; i < tableNum + 1; i++) {
tables[i].getTotalPrice();
}
}
}
- Record类:表示点餐记录,包含订单序号、菜品、数量、份额等属性,以及计算价格的方法。还有一些用于检查输入数据是否合法的方法。
- Order类:表示订单,包含一个点餐记录数组,保存订单上的每一道菜品记录。有添加记录、删除记录和计算订单总价的方法。
- Table类:表示桌子,包含桌号、是否有效、点餐时间、订单总价等属性。有处理时间、计算折扣、检查是否需要合并计算等方法。
- Main类:主类,包含main方法,用于接收用户输入并进行相应的操作。通过Scanner类获取用户输入的指令,根据指令调用相应的方法进行处理。
这一题难度较大,我是参考其他的代码写的,自己在做的时候没有理清逻辑,导致测试点很多无法通过,在研究了他人的代码后,多少理解了一点题目。值得注意的是,在筛选时用了正则表达式。
代码如下:
点击查看代码
import java.util.Scanner;
import java.util.Calendar;
import java.time.YearMonth;
class Dish {
String name;//菜品名称
boolean isSpecial = false;//是不是特色菜
int unit_price; //单价
boolean exist = true;
//int num;
int getPrice(int portion) {
int peic = 0;
if (portion == 1) {
peic = unit_price ;
} else if (portion == 2) {
peic = Math.round((float) (unit_price * 1.5)) ;
} else if (portion == 3) {
peic = (unit_price * 2) ;
}
return peic;//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}
}
class Menu {
Dish[] dishs = new Dish[10];//菜品数组,保存所有菜品信息
int count = 0;
Dish searthDish(String dishName){
Dish temd = null;
for(int i=count-1;i>=0;i--){
if(dishName.equals(dishs[i].name)&&dishs[i].exist){
temd = dishs[i];
break;
}
}
if(temd==null){
System.out.println(dishName+" does not exist");
}
return temd;
}//根据菜名在菜谱中查找菜品信息,返回Dish对象。
Dish addDish(String dishName,int unit_price){
Dish dh = new Dish();
dh.name = dishName;
dh.unit_price = unit_price;
count++;
if(unit_price<1||unit_price>300) {
dh.exist = false;
System.out.println(dishName+" price out of range "+unit_price);
}
return dh;
}//添加一道菜品信息
}
class Record {
int orderNum;//序号\
Dish d = new Dish();//菜品\
int num = 0;
int portion;//份额(1/2/3代表小/中/大份)\
boolean noNeed = true;
int exist = 1;
float realdiscnt = 1;
//int asum = 0;
boolean isTaked = false;//是否是给别人点的
int getPrice(){
return Math.round(d.getPrice(portion)*num);
}//计价,计算本条记录的价格\
float Checkportion(float discnt){//数量输入检查,计算价格
if(portion>3||portion<1) {
System.out.println(orderNum + " portion out of range " + portion);
exist = 0;
noNeed = false;
}else if(num<1||num>15) {
System.out.println(orderNum + " num out of range" +" "+num);
exist = 0;
noNeed = false;
}else{
if(d.isSpecial)
if(discnt==0.8F||discnt==0.6F)
realdiscnt = 0.7F;
if(exist==1&&!isTaked) {
System.out.println(orderNum + " " + d.name + " " + getPrice());
}
}
return realdiscnt;
}
boolean Checkahead(){
if(num<1||num>15) {
return false;
}else return portion <= 3 && portion >= 1;
}
}
class Order {
Record[] records = new Record[100];//保存订单上每一道的记录
int count = 0;//订单数量
int getTotalPrice(){
int sum=0;
for(int i=0;i<count;i++){
if(records[i].exist==0)
continue;
sum=sum+records[i].getPrice();
}
return sum;
}//计算订单的总价
Record addARecord(int orderNum, String dishName, int portion, int num){
boolean flag = true;
for(int i=0;i<count;i++){//不能点份额一样的菜
if (records[i].d.name.equals(dishName) && records[i].portion == portion) {
flag = false;
break;
}
}
count++;
records[count] = new Record();
records[count].d.name = dishName;
records[count].orderNum = orderNum;
records[count].portion = portion;
records[count].num = num;
records[count].noNeed = flag;
return records[count];
}//添加一条菜品信息到订单中。
Record TakeOdfor(int mynum,Table[] table, int AnotherNum, int orderNum, String dishName, int portion, int num){
boolean flag = false;
for(Table t : table) {
if(t==null)
continue;
if (t.tableNum != mynum&&t.tableNum==AnotherNum) {
flag = true;
break;
}
}
if(flag) {
count++;
records[count] = new Record();
records[count].d.name = dishName;
records[count].orderNum = orderNum;
records[count].portion = portion;
records[count].num = num;
return records[count];
}else{
System.out.println("Table number :" + AnotherNum + " does not exist");
return null;
}
}
void delARecordByOrderNum(int orderNum){
if(orderNum>count||orderNum<=0){
System.out.println("delete error;");
}else {
if(records[orderNum-1].exist==0) {
System.out.println("deduplication "+orderNum);
return;
}
records[orderNum-1].exist = 0;
}
}//根据序号删除一条记录
}
class Table {
int tableNum;
boolean inputIsvalid = false;
boolean istoSum = false;//判断是否要合并计算
String tableDtime;
int year,month,day,week,hh,mm,ss;
int sum = 0;//一桌价格 ;
int primesum = 0;
Order odt = new Order();
float discnt = -1;
float rediscnt = 1;
void Gettottalprice(){
if(discnt>0){
primesum = odt.getTotalPrice();
if(primesum==0)
sum=0;
System.out.println("table " + tableNum + ": " +primesum+" "+sum);
}
}
void AheadProcess(String tableDtime){
this.tableDtime = tableDtime;
processTime();
discount();
}
void processTime(){//处理时间
String[] temp = tableDtime.split(" ");
tableNum = Integer.parseInt(temp[1]);
String[] temp1 = temp[2].split("/");
String[] temp2 = temp[3].split("/");
year = Integer.parseInt(temp1[0]);
month = Integer.parseInt(temp1[1]);
day = Integer.parseInt(temp1[2]);
Calendar c = Calendar.getInstance();
c.set(year, (month-1), day);
week = c.get(Calendar.DAY_OF_WEEK);
if(week==1)
week = 7;
else
week--;
hh = Integer.parseInt(temp2[0]);
mm = Integer.parseInt(temp2[1]);
ss = Integer.parseInt(temp2[2]);
}
boolean DateisValid(){
if(year<1000)
return false;
if(month<1||month>12)
return false;
YearMonth mytime = YearMonth.of(year,month);
return mytime.isValidDay(day);
}
boolean Daterande(){
boolean flag = year >= 2022 && year <= 2023;
if(!flag){
System.out.println("not a valid time period");
inputIsvalid = false;
}
return flag;
}
void discount(){
if(week>=1&&week<=5)
{
if(hh>=17&&hh<20)
discnt=0.8F;
else if(hh==20&&mm<30)
discnt=0.8F;
else if(hh==20&&mm==30&&ss==0)
discnt=0.8F;
else if(hh>=11&&hh<=13||hh==10&&mm>=30)
discnt=0.6F;
else if(hh==14&&mm<30)
discnt=0.6F;
else if(hh==14&&mm==30&&ss==0)
discnt=0.6F;
}
else
{
if(hh>=10&&hh<=20)
discnt= 1.0F;
else if(hh==9&&mm>=30)
discnt= 1.0F;
else if(hh==21&&mm<30||hh==21&&mm==30&&ss==0)
discnt= 1.0F;
}
}
boolean CheckSameTime(Table table){
if(tableNum!=table.tableNum)
return false;
if(week==table.week&&week>=1&&week<=5){
return discnt == table.discnt;
}else if(week==table.week&&week==6||week==7){
int subtime = hh*3600+mm*60+ss-table.hh*3600-table.mm*60-ss;
return Math.abs(subtime) < 3600;
}
return false;
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Menu mu = new Menu();
Table[] tablemes = new Table[57];//桌号1-55;
int j = 0;//菜单数
int l = 0;//订单数
//代点菜数
//遍历桌
int cntTab = 0;//桌号
String[] temp;//字符串存储
int tempordernum = 0;//临时存上一个有效序号
String input;
String regex = "[\\u4e00-\\u9fa5]* \\d*";//非特色菜菜谱
String regex1 = "[\\u4e00-\\u9fa5]* \\d* T";//特色菜谱
String regex2 = "\\d (delete)";//删除情况
String regex3 = "(table) ([1-4][0-9]*|5[0-5]*) \\d{4}/\\d+/\\d{1,2} ([0-1]?[0-9]|2[0-3])/([0-5][0-9])/([0-5][0-9])";//添桌子的情况
String regex4 = "([1-9]|[1-9][0-9]*) [\\u4e00-\\u9fa5]+ \\d+ \\d+";//点菜记录的添加;
String regex5 = "([1-4][0-9]*|5[0-5]*|[1-9]) \\d [\\u4e00-\\u9fa5]+ [123] (1[0-5]|[1-9])";//代点菜
while (true) {
int count;//空格数量;
input = sc.nextLine();//获取输入,每行
if(input.equals("end"))
break;
if(input.isEmpty()) {
System.out.println("wrong format");
continue;
}
temp = input.split(" ");//分割
/*
* 判断输入的类型*/
count = temp.length;
if(count==2){//非特色菜菜谱,或者删除菜;
if(input.matches(regex2)){//删除的情况桌子有效才删除
if (tablemes[cntTab] != null && tablemes[cntTab].inputIsvalid) {
tablemes[cntTab].odt.delARecordByOrderNum(Integer.parseInt(temp[0]));//删除
}
}else if(input.matches(regex)){//非特色菜谱添加
if (cntTab == 0) {
mu.dishs[j] = new Dish();
mu.dishs[j] = mu.addDish(temp[0], Integer.parseInt(temp[1]));
j++;
} else if(tablemes[cntTab].inputIsvalid){
System.out.println("invalid dish");
}
}else {
System.out.println("wrong format");
}
}else if(count==3){//特色菜菜谱
if(input.matches(regex1)) {
if(cntTab!=0) {
if(tablemes[cntTab].inputIsvalid)
System.out.println("invalid dish");
else
continue;
}
mu.dishs[j] = new Dish();
mu.dishs[j] = mu.addDish(temp[0], Integer.parseInt(temp[1]));
mu.dishs[j].isSpecial = true;//是特色菜
j++;
}else
System.out.println("wrong format");
}
//桌子的添加,点菜记录的添加,
else if(temp[0].equals("table")||input.contains("/")) {
cntTab++;
tablemes[cntTab] = new Table();
if(temp[0].equals("table")){
if(input.matches(regex3))
tablemes[cntTab].AheadProcess(input);
tablemes[cntTab].inputIsvalid=true;
if (input.matches(regex3)) {
if(tablemes[cntTab].inputIsvalid&&!tablemes[cntTab].DateisValid()){//检查日期
System.out.println(tablemes[cntTab].tableNum+" date error");
tablemes[cntTab].inputIsvalid=false;
continue;
}
if(tablemes[cntTab].inputIsvalid&&!tablemes[cntTab].Daterande()){
tablemes[cntTab].inputIsvalid=false;
continue;
}
for(int i =1;i<cntTab;i++){
if (tablemes[i].inputIsvalid && tablemes[cntTab].CheckSameTime(tablemes[i])) {//同一时间段
tablemes[cntTab].istoSum = true;
} else {
l = 0;
}
tempordernum = 0;
}
if(tablemes[cntTab].discnt>0)
System.out.println("table " + tablemes[cntTab].tableNum + ": ");
else {
System.out.println("table " + tablemes[cntTab].tableNum + " out of opening hours");
tablemes[cntTab].inputIsvalid = false;
}
continue;
} else {//第一个是table但不合法
tablemes[cntTab].inputIsvalid = false;
if(!temp[1].isEmpty() &&temp[1].charAt(0)>='1'&&temp[1].charAt(0)<='9'&&!temp[1].contains("/")){
if(Integer.parseInt(temp[1])<1||Integer.parseInt(temp[1])>55){
System.out.println(Integer.parseInt(temp[1])+" table num out of range");
continue;
}
}
}
}
System.out.println("wrong format");
tablemes[cntTab].inputIsvalid = false;
if(!temp[0].equals("table"))
tablemes[cntTab].istoSum = true;
}else if(count==4){
if (tablemes[cntTab] != null && input.matches(regex4) && (tablemes[cntTab].inputIsvalid || tablemes[cntTab].istoSum)) {//点菜记录
Dish tem;
int aheadcntTab = cntTab - 1;
if (!tablemes[cntTab].istoSum) {//不需要合并
tablemes[cntTab].odt.records[l] = new Record();
tablemes[cntTab].odt.records[l] = tablemes[cntTab].odt.addARecord(Integer.parseInt(temp[0]), temp[1], Integer.parseInt(temp[2]), Integer.parseInt(temp[3]));
if (l - 1 >= 0) {//判断记录序号是否递增
tempordernum = getTempordernum(tablemes, l, cntTab, temp, tempordernum);
} else {//特殊情况
if (tablemes[cntTab].odt.records[l].Checkahead())
tempordernum = tablemes[cntTab].odt.records[l].orderNum;
}
if ((tem = mu.searthDish(temp[1])) != null) {
float temdiscnt;//临时储存折扣
tablemes[cntTab].odt.records[l].d = tem;
temdiscnt = tablemes[cntTab].odt.records[l].Checkportion(tablemes[cntTab].discnt);
if (temdiscnt != 1F)
tablemes[cntTab].rediscnt = temdiscnt;//最终折扣
if (tablemes[cntTab].odt.records[l].exist == 1 && tablemes[cntTab].odt.records[l].noNeed) {
if (tablemes[cntTab].rediscnt != 1) {
tablemes[cntTab].sum += Math.round(tablemes[cntTab].odt.records[l].getPrice() * tablemes[cntTab].rediscnt);
tablemes[cntTab].rediscnt = 1.0F;
} else
tablemes[cntTab].sum += Math.round(tablemes[cntTab].odt.records[l].getPrice() * tablemes[cntTab].discnt);
}
}
if (!tablemes[cntTab].istoSum) {//如果份额名字未重复;
l++;
}
} else {//需要合并计算
tablemes[aheadcntTab].odt.records[l] = new Record();
tablemes[aheadcntTab].odt.records[l] = tablemes[aheadcntTab].odt.addARecord(Integer.parseInt(temp[0]), temp[1], Integer.parseInt(temp[2]), Integer.parseInt(temp[3]));
if (l - 1 >= 0) {//判断记录序号是否递增
tempordernum = getTempordernum(tablemes, l, aheadcntTab, temp, tempordernum);
}
if ((tem = mu.searthDish(temp[1])) != null) {
float temdiscnt;//临时储存折扣
tablemes[aheadcntTab].odt.records[l].d = tem;
temdiscnt = tablemes[aheadcntTab].odt.records[l].Checkportion(tablemes[aheadcntTab].discnt);//计算折扣
if (temdiscnt == 0.7F)//如果需要调整
tablemes[aheadcntTab].rediscnt = temdiscnt;//最终折扣//更改折扣
if (tablemes[aheadcntTab].odt.records[l].exist == 1) {//必须存在
if (tablemes[aheadcntTab].rediscnt != 1) {
tablemes[aheadcntTab].sum += Math.round(tablemes[aheadcntTab].odt.records[l].getPrice() * tablemes[aheadcntTab].rediscnt);
tablemes[aheadcntTab].rediscnt = 1.0F;
} else
tablemes[aheadcntTab].sum += Math.round(tablemes[aheadcntTab].odt.records[l].getPrice() * tablemes[cntTab].discnt) - 1;
}
}
l++;
}
}
}
else if (tablemes[cntTab] != null && count == 5 && tablemes[cntTab].inputIsvalid) {//代点菜
int temSum = 0;
if (input.matches(regex5)) {
int AnothNum = Integer.parseInt(temp[0]);
tablemes[cntTab].odt.records[l] = tablemes[cntTab].odt.TakeOdfor(tablemes[cntTab].tableNum, tablemes, AnothNum, Integer.parseInt(temp[1]), temp[2], Integer.parseInt(temp[3]), Integer.parseInt(temp[4]));
Dish tem;
if ((tem = mu.searthDish(temp[2])) != null && tablemes[cntTab].odt.records[l] != null) {
tablemes[cntTab].odt.records[l].isTaked = true;//给别人diade
float temdiscnt;//临时储存折扣
tablemes[cntTab].odt.records[l].d = tem;
temdiscnt = tablemes[cntTab].odt.records[l].Checkportion(tablemes[cntTab].discnt);
if (temdiscnt != 1F)
tablemes[cntTab].rediscnt = temdiscnt;//最终折扣
if (tablemes[cntTab].odt.records[l].exist == 1 && tablemes[cntTab].odt.records[l].noNeed) {
if (tablemes[cntTab].rediscnt != 1) {
tablemes[cntTab].sum += Math.round((temSum = tablemes[cntTab].odt.records[l].getPrice()) * tablemes[cntTab].rediscnt);
tablemes[cntTab].rediscnt = 1.0F;
} else
tablemes[cntTab].sum += Math.round((temSum = tablemes[cntTab].odt.records[l].getPrice()) * tablemes[cntTab].discnt);
}
System.out.println(temp[1] + " table " + tablemes[cntTab].tableNum + " pay for table " + temp[0] + " " + temSum);
}
if (tablemes[cntTab].odt.records[l] != null)
l++;
} else
System.out.println("wrong format");
}
}
for(int i=1;i<=cntTab;i++){
if(tablemes[i].inputIsvalid&&!tablemes[i].istoSum)
tablemes[i].Gettottalprice();
}
}
private static int getTempordernum(Table[] tablemes, int l, int cntTab, String[] temp, int tempordernum) {
if (Integer.parseInt(temp[0]) <= tempordernum) {
System.out.println("record serial number sequence error");
tablemes[cntTab].odt.records[l].exist = 0;
} else if (tablemes[cntTab].odt.records[l] != null && tablemes[cntTab].odt.records[l].noNeed)
tempordernum = tablemes[cntTab].odt.records[l].orderNum;
return tempordernum;
}
}
3.菜单计价程序-5
复杂度分析


类图

-
首先定义了一个Dish类,表示菜品。菜品有名称(name)、单价(unitPrice)和类型(type)属性。菜品类型使用枚举类DishType表示,包括川菜(Chuan)、晋菜(Jin)和浙菜(Zhe)。
-
然后定义了一个Menu类,表示菜单。菜单中可以添加菜品(addDish),并且可以根据菜品名称查找菜品(searchDish)。
-
接着定义了一个Record类,表示订单中的一条记录。记录包含订单号(orderNum)、菜品(dish)、份数(portion)、数量(quantity)、口味等级(level)、是否合法(flag)和赠送的桌号(givenId)等属性。记录还有计算价格的方法(getPrice)和打印信息的方法(print)。
-
然后定义了一个Table类,表示餐桌。餐桌有桌号(tableId)、客人姓名(name)、联系电话(phone)、就餐日期(date)、就餐时间(time)、是否合法(flag)等属性。餐桌可以根据就餐时间计算折扣系数(getCoefficient),计算总价(getTotalPrice)和应付金额(getCheckedPrice),获取平均口味等级(getAveLevel),添加订单记录(addRecord),删除订单记录(delRecordByOrderNum),打印餐桌信息(printId、printInfo)等。
-
最后在主函数中,通过Scanner类获取用户输入。创建菜单(menu)、餐桌(tables)和临时菜品(tempDish)等变量。根据用户输入的指令进行相应的操作,包括添加菜品、添加订单记录、删除订单记录等。最后输出每个餐桌的信息和客人的消费金额。
菜单5依旧是在菜单3的基础上进行了修改,但是难度依旧不小,我也是参考了别人的代码,但还是没能完全达到题目的要求拿到满分。
代码如下:
点击查看代码
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args) throws ParseException {
Menu menu = new Menu();
// 读入菜单信息
Scanner scanner = new Scanner(System.in);
String menuLine = scanner.nextLine();
while (!menuLine.startsWith("table")) {
String[] menuInfo = menuLine.split(" ");
if (menuInfo.length == 2) {
String name = menuInfo[0];
int unitPrice = Integer.parseInt(menuInfo[1]);
if (menu.searchDish(name) == null) {
menu.addDish(name, unitPrice);
}
} else if (menuInfo.length == 4 && menuLine.endsWith("T")) {
String name = menuInfo[0];
String type = menuInfo[1];
int unitPrice = Integer.parseInt(menuInfo[2]);
Map<String, String> map = new HashMap<>() {
{
put("川菜", "Chuan");
put("晋菜", "Jin");
put("浙菜", "Zhe");
}
};
DishType dishType = DishType.valueOf(map.get(type));
if (menu.searchDish(name) == null) {
menu.addDish(name, unitPrice, dishType);
}
} else {
System.out.println("wrong format");
}
menuLine = scanner.nextLine();
}
ArrayList<Table> tables = new ArrayList<>();
ArrayList<String> names = new ArrayList<>();
// 读入订单信息
int tableId = 0;
String name;
String phone;
Date date;
Date time;
boolean legalTime = true;
boolean legalFormat = true;
String orderLine = menuLine;
while (!orderLine.equals("end")) {
String[] orderInfo = orderLine.split(" ");
// 解析桌号标识
if (orderLine.startsWith("table")) {
legalFormat = true;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
SimpleDateFormat timeFormat = new SimpleDateFormat("HH/mm/ss");
tableId = Integer.parseInt(orderInfo[1]);
name = orderInfo[3];
phone = orderInfo[4];
try {
date = dateFormat.parse(orderInfo[5]);
time = timeFormat.parse(orderInfo[6]);
} catch (Exception e) {
legalFormat = false;
System.out.println("wrong format");
orderLine = scanner.nextLine();
continue;
}
String regex = "^1(80|81|89|33|35|36)\\d{8}$";
Table table = new Table(tableId, name, phone, date, time);
tables.add(table);
if (name.length() > 10 || !phone.matches(regex)) {
legalFormat = false;
System.out.println("wrong format");
orderLine = scanner.nextLine();
continue;
}
if (!names.contains(name)) {
names.add(name);
}
if (table.getCoefficient(true) == 0) {
legalTime = false;
System.out.println("table " + table.getTableId() + " out of opening hours");
} else {
System.out.println(table.printId());
}
} else {
if (legalFormat) {
int orderNum;
try {
orderNum = Integer.parseInt(orderInfo[0]);
} catch (Exception e) {
System.out.println("wrong format");
orderLine = scanner.nextLine();
continue;
}
if (orderLine.endsWith("delete")) {
if (!tables.get(tableId - 1).delRecordByOrderNum(orderNum)) {
System.out.println("delete error");
}
} else {
if (orderInfo.length == 4) {
String dishName = orderInfo[1];
int portion = Integer.parseInt(orderInfo[2]);
int quantity = Integer.parseInt(orderInfo[3]);
Dish dish = menu.searchDish(dishName);
if (dish == null) {
System.out.println(dishName + " does not exist");
orderLine = scanner.nextLine();
continue;
}
Record record = new Record(tableId, orderNum, dish, portion, quantity);
tables.get(tableId - 1).addRecord(record);
if (legalTime) {
System.out.println(record.print(tableId));
}
} else if (orderInfo.length == 5) {
String dishName = orderInfo[1];
int level = Integer.parseInt(orderInfo[2]);
int portion = Integer.parseInt(orderInfo[3]);
int quantity = Integer.parseInt(orderInfo[4]);
Dish dish = menu.searchDish(dishName);
if (dish == null) {
System.out.println(dishName + " does not exist");
orderLine = scanner.nextLine();
continue;
}
Record record = new Record(tableId, orderNum, dish, level, portion, quantity);
tables.get(tableId - 1).addRecord(record);
if (legalTime) {
System.out.println(record.print(tableId));
}
} else if (orderInfo.length == 6) {
int givenId = Integer.parseInt(orderInfo[1]);
String dishName = orderInfo[2];
int level = Integer.parseInt(orderInfo[3]);
int portion = Integer.parseInt(orderInfo[4]);
int quantity = Integer.parseInt(orderInfo[5]);
Dish dish = menu.searchDish(dishName);
if (dish == null) {
System.out.println(dishName + " does not exist");
orderLine = scanner.nextLine();
continue;
}
Record record1 = new Record(givenId, orderNum, dish, level, portion, quantity);
Record record2 = new Record(givenId, orderNum, dish, level, 0, quantity);
tables.get(tableId - 1).addRecord(record1);
tables.get(givenId - 1).addRecord(record2);
if (legalTime) {
System.out.println(record1.print(tableId));
}
} else {
System.out.println("wrong format");
}
}
}
}
// 读入下一个桌号标识
orderLine = scanner.nextLine();
}
scanner.close();
for (Table table : tables) {
if (table.isFlag() && table.getTotalPrice() != 0) {
System.out.println(table.printInfo());
}
}
names.sort(Comparator.naturalOrder());
for (String customerName : names) {
int sum = 0;
String customerPhone = null;
for (Table table : tables) {
if (table.getName().equals(customerName)) {
sum += table.getCheckedPrice();
customerPhone = table.getPhone();
}
}
if (sum != 0) {
System.out.println(customerName + " " + customerPhone + " " + Math.round(sum));
}
}
}
}
enum DishType {
Chuan,
Jin,
Zhe,
}
class Dish {
private final String name;
private final int unitPrice;
private DishType type;
public Dish(String name, int unitPrice, DishType type) {
this.name = name;
this.unitPrice = unitPrice;
this.type = type;
}
public Dish(String name, int unitPrice) {
this.name = name;
this.unitPrice = unitPrice;
}
@Override
public String toString() {
return name;
}
public Object getName() {
return name;
}
public DishType getType() {
return type;
}
public int getUnitPrice() {
return unitPrice;
}
}
class Menu {
private final ArrayList<Dish> dishes = new ArrayList<>();
public Dish searchDish(String dishName) {
for (Dish dish : dishes) {
if (dish.getName().equals(dishName)) {
return dish;
}
}
return null;
}
public void addDish(String dishName, int unitPrice) {
dishes.add(new Dish(dishName, unitPrice));
}
public void addDish(String dishName, int unitPrice, DishType type) {
dishes.add(new Dish(dishName, unitPrice, type));
}
}
class Record {
private final int orderNum;
private final Dish dish;
private final int portion;
private final int quantity;
private final int level;
private final boolean flag;
private final int givenId;
public Record(int givenId, int orderNum, Dish dish, int portion, int quantity) {
this.orderNum = orderNum;
this.dish = dish;
this.portion = portion;
this.quantity = quantity;
this.level = -1;
this.flag = true;
this.givenId = givenId;
}
public Record(int givenId, int orderNum, Dish dish, int level, int portion, int quantity) {
this.orderNum = orderNum;
this.dish = dish;
this.portion = portion;
this.quantity = quantity;
this.level = level;
this.flag = checkLevel();
this.givenId = givenId;
}
private boolean checkLevel() {
switch (dish.getType()) {
case Chuan:
return level <= 5 && level >= 0;
case Jin:
return level <= 4 && level >= 0;
case Zhe:
return level <= 3 && level >= 0;
default:
return true;
}
}
public double getPrice() {
if (!flag)
return 0;
double coefficient = 0;
switch (portion) {
case 1:
coefficient = 1;
break;
case 2:
coefficient = 1.5;
break;
case 3:
coefficient = 2;
break;
}
return Math.round(dish.getUnitPrice() * coefficient) * quantity;
}
public int getCheckedPrice(double coefficient) {
return (int) Math.round(getPrice() * coefficient);
}
public String print(int tableId) {
if (!flag) {
switch (dish.getType()) {
case Chuan:
return "spicy num out of range :" + level;
case Jin:
return "acidity num out of range :" + level;
case Zhe:
return "sweetness num out of range :" + level;
default:
return null;
}
} else {
if (givenId == tableId) {
return orderNum + " " + dish.toString() + " " + Math.round(getPrice());
}
return orderNum + " table " + tableId + " pay for table " + givenId + " " + Math.round(getPrice());
}
}
@Override
public String toString() {
return "Record [orderNum=" + orderNum + ", dish=" + dish + ", portion=" + portion + ", quantity=" + quantity
+ ", level=" + level + ", flag=" + flag + ", givenId=" + givenId + "]";
}
public int getLevel() {
return level;
}
public Dish getDish() {
return dish;
}
public boolean isFlag() {
return flag;
}
public int getGivenId() {
return givenId;
}
public int getQuantity() {
return quantity;
}
public int getOrderNum() {
return orderNum;
}
}
class Table {
private final ArrayList<Record> records = new ArrayList<>();
private final int tableId;
private final String name;
private final String phone;
private final Date date;
private final Date time;
private boolean flag;
public Table(int tableId, String name, String phone, Date date, Date time) {
this.name = name;
this.phone = phone;
this.date = date;
this.time = time;
this.tableId = tableId;
this.flag = true;
}
public double getCoefficient(boolean special) throws ParseException {
double coefficient = 0;
SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm");
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
// 营业时间
if (dayOfWeek == 1 || dayOfWeek == 7) {
if (time.after(sdfTime.parse("9:29")) && time.before(sdfTime.parse("21:31"))) {
coefficient = 1;
}
} else {
if (time.after(sdfTime.parse("16:59")) && time.before(sdfTime.parse("20:31"))) {
if (special) {
coefficient = 0.7;
} else {
coefficient = 0.8;
}
} else if (time.after(sdfTime.parse("10:29")) && time.before(sdfTime.parse("14:31"))) {
if (special) {
coefficient = 0.7;
} else {
coefficient = 0.6;
}
}
}
if (coefficient == 0) {
flag = false;
}
return coefficient;
}
public int getTotalPrice() {
int sum = 0;
for (Record record : records) {
sum += (int) record.getPrice();
}
return sum;
}
public int getCheckedPrice() throws ParseException {
int sum = 0;
for (Record record : records) {
if (record.getLevel() != -1) {
sum += record.getCheckedPrice(getCoefficient(true));
} else {
sum += record.getCheckedPrice(getCoefficient(false));
}
}
return sum;
}
public String getAveLevel(DishType type) {
String[] spicy = {"不辣", "微辣", "稍辣", "辣", "很辣", "爆辣"};
String[] acidity = {"不酸", "微酸", "稍酸", "酸", "很酸"};
String[] sweetness = {"不甜", "微甜", "稍甜", "甜"};
double sum = 0;
double num = 0;
for (Record record : records) {
if (record.getDish().getType() == type) {
if (record.isFlag() && tableId == record.getGivenId()) {
num += record.getQuantity();
sum += record.getLevel() * record.getQuantity();
}
}
}
if (num == 0) {
return "";
}
int ave = (int) Math.round(sum / num);
switch (type) {
case Chuan:
return " 川菜 " + (int) num + " " + spicy[ave];
case Jin:
return " 晋菜 " + (int) num + " " + acidity[ave];
case Zhe:
return " 浙菜 " + (int) num + " " + sweetness[ave];
default:
return null;
}
}
public void addRecord(Record record) {
records.add(record);
}
public boolean delRecordByOrderNum(int orderNum) {
return records.removeIf(record -> record.getOrderNum() == orderNum);
}
public String printId() {
return "table " + tableId + ": ";
}
public String printInfo() throws ParseException {
String chuan = getAveLevel(DishType.Chuan);
String jin = getAveLevel(DishType.Jin);
String zhe = getAveLevel(DishType.Zhe);
if (chuan.isEmpty() && jin.isEmpty() && zhe.isEmpty()) {
return "table " + tableId + ": " + getTotalPrice() + " " + getCheckedPrice() + " ";
} else {
StringBuilder sb = new StringBuilder();
sb.append("table ").append(tableId).append(": ").append(getTotalPrice()).append(" ").append(getCheckedPrice());
if (!chuan.isEmpty()) {
sb.append(chuan);
}
if (!jin.isEmpty()) {
sb.append(jin);
}
if (!zhe.isEmpty()) {
sb.append(zhe);
}
return sb.toString();
}
}
public boolean isFlag() {
return flag;
}
public int getTableId() {
return tableId;
}
public Object getName() {
return name;
}
public String getPhone() {
return phone;
}
}
点击查看代码
import java.util.Scanner;
abstract class Shape {
public abstract double getArea();
}
class Circle extends Shape {
private double radius;
Circle(){
}
public Circle(double radius) {
this.radius = radius;
}
public void setRadius(double radius){
this.radius = radius;
}
public double getRadius(){
return this.radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
}
class Rectangle extends Shape {
private Point topLeftPoint;
private Point lowerRightPoint;
Rectangle(Point topLeftPoint, Point lowerRightPoint) {
this.topLeftPoint = topLeftPoint;
this.lowerRightPoint = lowerRightPoint;
}
public Point getTopLeftPoint(){
return this.topLeftPoint;
}
public void setTopLeftPoint(Point topLeftPoint){
this.topLeftPoint = topLeftPoint;
}
public Point getLowerRightPoint(){
return this.lowerRightPoint;
}
public void setLowerRightPoint(Point lowerRightPoint){
this.lowerRightPoint = lowerRightPoint;
}
public double getLength() {
return Math.abs(topLeftPoint.getX() - lowerRightPoint.getX());
}
public double getHeight() {
return Math.abs(topLeftPoint.getY() - lowerRightPoint.getY());
}
public double getArea() {
double length = getLength();
double height = getHeight();
return length * height;
}
}
class Point {
private double x;
private double y;
Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x){
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y){
this.y = y;
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int choice = input.nextInt();
switch (choice) {
case 1: // Circle
double radius = input.nextDouble();
Shape circle = new Circle(radius);
printArea(circle);
break;
case 2: // Rectangle
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
Point leftTopPoint = new Point(x1, y1);
Point lowerRightPoint = new Point(x2, y2);
Shape rectangle = new Rectangle(leftTopPoint, lowerRightPoint);
printArea(rectangle);
break;
}
}
public static void printArea(Shape shape) {
double area = shape.getArea();
System.out.printf("%.2f\n", area);
}
}