- A+
(1)前言:在pta第4.5.6次大作业和期中考试所包含的知识点主要有:理解类的概念,创建类和实例化对象。定义方法,方法的参数传递和返回值。使用条件语句(if-else)、循环语句(for、while)等来控制菜单存储和用户输入。用于存储菜单选项和处理用户的选择的数组或类数组。题目的难度根据题目不同也有所不同,第四题的菜单题只需要做基本的菜单显示和用户输入处理,随后的5.6两道题目要求考虑异常输入的处理并需要使用更复杂的数据结构来实现菜单功能。题量相对适中,第4道pta题目可能较为简单,两道大题主要是针对对类的设计和方法实现,另外两道题目针对遍历排序和日期比较考察了部分基础知识和库函数知识。第5.6道题目大幅度增加复杂度了而减少题目数量,其编程设计需要考虑更多的设计和实现细节。
(2) 设计与分析:
菜品包含特色口味输出类的代码时间复杂度大体上是O(n),其中n为输入菜品记录的数量。在程序中定义了
菜品:dishname菜名,price单价,Kind:菜的种类
菜单:包含菜品数组
桌子类:table_number: 桌号orders: 已点菜品列表
用户类:name: 用户名,pay用户需付价格
菜品记录类:order_number: 序号items: 已点菜品列表
这些类的属性和方法都比较简单,因此这段代码的整体逻辑清晰,易于理解和调试。在程序的主函数中,使用了Scanner类从用户的输入读取输入信息,根据Match判断的返回值判断其输入格式是否正确后转入相应的if语句中执行相应的操作。各自调用相关类的各种方法结合Dish中存储的菜品价格和菜品类型计算所点菜品的价格最后得到订单总价和用户所需要付的价格后统一输出,其中折扣判断在桌号数据行输入后日期折扣判断已经完成,而后在计算时根据是否是特色菜结合日期判断的折扣值计算价格。通过将不同的功能分别封装在不同的类中,可以使得程序结构更加清晰,并且易于扩展和维护。
对于多种错误输入的菜品输入的题目,由于其判断代码出现失误,导致输入语句在接收后不知道语句进入了哪个判断语句,完全无法判断错误输入。最后总结为思路错误,无法适应错误输入的数据并完成相应的输出判断。最后写的代码全部作废,写不下去了。
关于期中考试的实验题,之前的实验题都是根据给出的类来完善主函数,而这次考试则是根据主函数来完善类中数据接口,导致有些措手不及。
而对于第四次pta题目,对于第五第六次的题目而言实在是小巫见大巫,没有可比性。
(3)踩坑心得:在对输入数据的处理过程中,一定要选择合适的输入数据判断方法,一定要能够兼顾完成对正常数据的输入和异常数据的判断和处理输出,以应对题目需求。
Exception in thread "main" java.lang.NullPointerException: Cannot load from object array because "cou.stu" is null at Main.Match(Main.java:178) at Main.main(Main.java:278):在main函数中对类的声明后没有初始化便开始调用,使得指针尝试将值存储到一个空对象数组时出错,为了避免此类情况的发生,对于对象类数组的调用一定要先确保其已经被正确初始化并分配了足够的空间。
(4)主要困难以及改进建议:对于对输入数据的处理与判别尤其需要细心并且细致讨论各类情况,防止非法输入导致程序无法正常运行。
(5)总结:关于此次解题经验,我总结了部分要点:
1.明确题目要求与意义:根据题目说明和所提供的示例输入输出等辅助信息理解题目要求与目的。
2.理清解题思路再写代码:在理解了题意后,先理清题目的解题思路,避免在编写代码的过程中出现错误。
3.考虑边界条件和异常情况:在编写题目时要考虑到各种可能的输入情况,包括边界值和异常情况,以保证代码的稳定性。
4.不断学习更新知识:题目的编写过程也是对自己知识的回顾和巩固,通过编写题目可以不断学习并更新自己的知识体系,只有这样才能适应多变的题型。
总的来说,这次写题目对我来说是一次很有收获的经历。通过这次写题目,我锻炼了自己的问题设计和解决能力,并提高了对编程知识的理解和应用能力。希望在以后的学习和实践中能够继续加油,不断提升自己的技术水平。
以下附特色口味菜品输入源码:
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Calendar;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.Comparator;
public class Main{
public static class Dish
{
String name;//菜品名称
int level=-1;
int kind=-1;
int unit_price; //单价
String[][] tastes = {
{"不辣","微辣","稍辣", "辣", "很辣", "爆辣"},
{"不酸","微酸","稍酸","酸","很酸"},
{"不甜","微甜","稍甜","甜"}
};
String[] tastprint={"spicy","acidity","sweetness"};
int getPrice(int portion)
{
int x=0;
double temp=1;
double prise=0;
if(portion==2)
{temp=1.5;}
else if(portion==3)
{temp=2;}
prise=this.unit_price*temp;
x=Math.round((float)prise);
return x;
}
//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }
//菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
}
public static class Menu {
Dish[] dishs=new Dish[10];//菜品数组,保存所有菜品信息
int count = 0;
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
{
for(int i=0;i<count;i++)
{
if(dishs[i].name!=null) {
if(dishs[i].name.equals(dishName)) {
return dishs[i];
}
}
}
// System.out.print(dishName+" does not existn");
return null;
}
int searthdish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
{
for(int i=0;i<count;i++)
{
if(dishs[i].name!=null) {
if(dishs[i].name.equals(dishName)) {
return i;
}
}
}
// System.out.print(dishName+" does not existn");
return -6;
}
void addDish(String[] word)//添加一道菜品信息
{
int unit_price=0;String dishName;
if (this.dishs[count] == null)
{
this.dishs[count] = new Dish();
}
dishName=word[0];
if(word.length==4)
{
unit_price=Integer.parseInt(word[2]);
}
else
{
if(word.length==2){
unit_price=Integer.parseInt(word[1]);}
else
{System.out.print("wrong formatn");
return;}
}
if (count > 1)
{
int i = searthdish(dishName);
if (i != -6)
{
this.dishs[i].name = dishName;
this.dishs[i].unit_price = unit_price;
}
else {
this.dishs[count].name = dishName;
this.dishs[count].unit_price = unit_price;
switch (word[1]) {
case "川菜":
this.dishs[count].kind=0;
break;
case "晋菜" :
this.dishs[count].kind=1;
break;
case "浙菜":
this.dishs[count].kind=2;
break;
}
count++;
}
}
else
{
this.dishs[count].name = dishName;
this.dishs[count].unit_price = unit_price;
switch (word[1]) {
case "川菜":
this.dishs[count].kind=0;
break;
case "晋菜" :
this.dishs[count].kind=1;
break;
case "浙菜":
this.dishs[count].kind=2;
break;
}
count++;
}
}
}
//点菜记录类:保存订单上的一道菜品记录
public static class Record {
int orderNum;//序号
int orderX=0;//订单份数
Dish d;//菜品\
int replace=0;
int replaced=0;
int portion=0;//份额(1/2/3代表小*1/中*1.5/大份*2)\
int getPrice()//计价,计算本条记录的价格\
{
int ds=d.getPrice(portion);
return ds;
}
}
public static class User
{
String name,tele;
int pay=0;
}
//订单类:保存用户点的所有菜的信息。
public static class Order {
User user=new User();
Record[] records=new Record[50];//保存订单上每一道的记录
int ordercount=0;
int temp=0;
int[] time=new int[8];
int[] taste={0,0,0};
int[] tastecount={0,0,0};
int getTotalPrice(int i)//计算订单的总价
{
int price=0;
if(i<ordercount){
if(records[i]!=null)
{price=price+records[i].getPrice()*records[i].orderX;}
}
return price;
}
void addARecord(int judge,int orderNum,String dishName,int portion,int num,int tense,Menu menu)//添加一条菜品信息到订单中。
{
if(this.records[this.ordercount]==null)
{this.records[this.ordercount]=new Record();}
this.records[this.ordercount].replace=judge;
this.records[this.ordercount].orderNum=orderNum;
this.records[this.ordercount].orderX=num;
this.records[this.ordercount].portion=portion;
if (menu.searthDish(dishName)!= null)
{
if (this.records[this.ordercount].replace!= 0)//代点菜
{
this.records[this.ordercount].d = new Dish();
this.records[this.ordercount].d =menu.searthDish(dishName);
if(this.records[this.ordercount].d.kind!=-1) {
this.records[this.ordercount].d.level=tense;
if(this.records[this.ordercount].d.tastes[this.records[this.ordercount].d.kind].length<=tense)
{
System.out.print(this.records[this.ordercount].d.tastprint[this.records[this.ordercount].d.kind]+" num out of range : "+tense+"n");
this.ordercount--;
}
else
{
System.out.print(orderNum + " table " + (this.time[0]) + " pay for table " + this.records[this.ordercount].replace+ " " + this.records[this.ordercount].getPrice() * this.records[this.ordercount].orderX + "n");
}
}
else
{
System.out.print(orderNum + " table " + (this.time[0]) + " pay for table " + this.records[this.ordercount].replace + " " + this.records[this.ordercount].getPrice() * this.records[this.ordercount].orderX + "n");
}
}
else//自点菜
{
this.records[this.ordercount].d = new Dish();
this.records[this.ordercount].d=menu.searthDish(dishName);
if(this.records[this.ordercount].d.kind!=-1) {
this.records[this.ordercount].d.level=tense;
if(this.records[this.ordercount].d.tastes[this.records[this.ordercount].d.kind].length<=tense)
{
System.out.print(this.records[this.ordercount].d.tastprint[this.records[this.ordercount].d.kind]+" num out of range :"+tense+"n");
this.ordercount--;
}
else
{
this.taste[this.records[this.ordercount].d.kind]=this.taste[this.records[this.ordercount].d.kind]+tense*this.records[this.ordercount].orderX;
this.tastecount[this.records[this.ordercount].d.kind]=this.tastecount[this.records[this.ordercount].d.kind]+this.records[this.ordercount].orderX;
// System.out.print(" "+this.taste[this.records[this.ordercount].d.kind]+" "+this.records[this.ordercount].orderX+"nn");
System.out.print(this.records[this.ordercount].orderNum + " " + this.records[this.ordercount].d.name + " " + this.records[this.ordercount].getPrice() * this.records[this.ordercount].orderX + "n");
}
}
else
{
System.out.print(this.records[this.ordercount].orderNum + " " + this.records[this.ordercount].d.name + " " + this.records[this.ordercount].getPrice() * this.records[this.ordercount].orderX + "n");
}
}
this.ordercount++;
}
else if (menu.searthDish(dishName) == null)
{
System.out.print(dishName + " does not existn");
}
}
void delARecordByOrderNum(int orderNum,Menu menu)//根据序号删除一条记录
{
if(records[orderNum]!=null)
{
if(records[orderNum].d!=null) {
if (menu.searthDish(records[orderNum].d.name) != null) {
records[orderNum].orderX = 0;
records[orderNum].d.kind=-1;
}
}
else
{
System.out.print("delete error;n");
}
}
else
System.out.print("delete error;n");
}
int addtable(String str,long[] num)
{
for (int j = 0; j < 8; j++)
{
if (j == 1)
{
this.time[j+1] =(int)num[j+1];
j++;
}
else
{
this.time[j] =(int)num[j];
}
}
String[] word=str.split("\s+");
this.user.name=word[3];
this.user.tele=word[4];
if(word[4].length()!=11)
{System.out.print("wrong formatn");
return 0;}
if (judgetime(this.time,(int)num[0])==0) {
System.out.print("table " + num[0]+ " out of opening hoursn");
return 0;
}
else
{
System.out.print("table " + num[0] + ": n");
return 1;
}
}
}//Order
public static int Match(String x)
{
int num=99;
String regex1="\S{1,10} \d{1,2}$";
String regex11="\S{1,10} \p{IsHan}{1,10} \d{1,2} T$";
String regex2="table \d{1} : [a-z]{1,10} \d{1,11} \d{4}/\d{1,2}/\d{1,2} \d{1,2}/\d{1,2}/\d{1,2}$";
String regex3="\d{1} \S{1,10} [1-3] \d{1,2}$";//zz普通菜
String regex4="\d{1} \d{1} \S{1,10} [1-3] \d{1,2}$";//dd普通菜
String regex31="\d{1} \S{1,10} \d{1} [1-3] \d{1,2}$";//zz特色菜
String regex41="\d{1} \d{1,2} \S{1,10} \d{1} [1-3] \d{1,2}$";//dd特色菜
String regex32="\d{1,2} \S{1,10} \d{1} [1-3] \d{1,2}$";//zz
String regex42="\d{1,2} \d{1,2} \S{1,10} \d{1} [1-3] \d{1,2}$";//dd
String regex5="\d{1} delete$";
Pattern pattern1=Pattern.compile(regex1);
Pattern pattern11=Pattern.compile(regex11);//T
Pattern pattern2=Pattern.compile(regex2);
Pattern pattern3=Pattern.compile(regex3);
Pattern pattern4=Pattern.compile(regex4);
Pattern pattern31=Pattern.compile(regex31);
Pattern pattern41=Pattern.compile(regex41);
Pattern pattern32=Pattern.compile(regex32);
Pattern pattern42=Pattern.compile(regex42);
Pattern pattern5=Pattern.compile(regex5);
Matcher matcher1=pattern1.matcher(x);
Matcher matcher11=pattern11.matcher(x);//T
Matcher matcher2=pattern2.matcher(x);
Matcher matcher3=pattern3.matcher(x);
Matcher matcher4=pattern4.matcher(x);
Matcher matcher5=pattern5.matcher(x);
Matcher matcher31=pattern31.matcher(x);
Matcher matcher41=pattern41.matcher(x);
if(matcher1.matches())
{
num=0;}//麻婆豆腐 12
else if(matcher2.matches())
{
num=1;}
else if(matcher3.matches())
{
num=2;}//3 麻辣鸡丝 1 2
else if(matcher4.matches())
{
num=3;}//1 4 麻婆豆腐 1 1代付菜
else if(matcher5.matches())
{
num=4;}//1 delete
else if(matcher11.matches())
{
num=11;
}
else if(matcher31.matches())
{
num=31;
}
else if(matcher41.matches())
{
num=41;
}
return num;
}
public static double judgetime(int[] time,int table)
{
/*周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。
周末全价,营业时间:9:30-21:30*/
double n=0;
double temp=0;
Calendar calendar = Calendar.getInstance();
calendar.set(time[2],(time[3]-1),time[4]);
int weekday = calendar.get(Calendar.DAY_OF_WEEK);
//获取星期几,周日为1,周一为2
n=time[5]*3600+time[6]*60+time[7];
//17:00-20:30 61200-73800
//10:30-14:30 37800-52200
if(weekday>1&&weekday<7)
{
if (n>=37800&&n<=52200)
{
temp=0.6;
}
else if(n>=61200&&n<=73800)
{
temp=0.8;
}
else
{
temp=0;
}
}
//9:30-21:30 34200-77400
else if(weekday==1||weekday==7)
{
if (n>=34200&&n<=77400)
{
temp=1;
}
else
{
temp=0;
}
}
return temp;
}
public static boolean isTimeInRange(LocalDateTime time, LocalTime startTime, LocalTime endTime) {
LocalTime givenTime = time.toLocalTime();
return givenTime.isAfter(startTime) && givenTime.isBefore(endTime);
}
public static double discountnum(Order order,double judge,int num)
{
double dis=0;
if(order.records[num].d.kind!=-1)
{
if(judge==0.8||judge==0.6)
{dis=0.7;}
else if(judge==1)
{dis=1;}
}
else
{
dis=judge;
}
return dis;
}
/*
周一至周五营业时间晚上(17:00-20:30)8折,
周一至周五中午(10:30--14:30)6折,其余时间不营业。
周末全价,营业时间:9:30-21:30
例如:麻婆豆腐 川菜 9 T
菜价的计算方法:
周一至周五 7折, 周末全价。
*/
public static void dishout(Order order)
{
Dish dish=new Dish();
int aver=0;
if(order.tastecount[0]!=0)
{
aver=(int)Math.round((double)order.taste[0]/(double)order.tastecount[0]);
//System.out.print(" nntaste"+order.taste[0]+" count"+order.tastecount[0]+" aver"+aver+"nn");
System.out.print(" 川菜 "+order.tastecount[0]+" "+dish.tastes[0][aver]);
}
if(order.tastecount[1]!=0)
{
aver=(int)Math.round((double)order.taste[1]/(double)order.tastecount[1]);//
System.out.print(" 晋菜 "+order.tastecount[1]+" "+dish.tastes[1][aver]);
}
if(order.tastecount[2]!=0)
{
aver=(int)Math.round((double)order.taste[2]/(double)order.tastecount[2]);//
System.out.print(" 浙菜 "+order.tastecount[2]+" "+dish.tastes[2][aver]);
}
if(order.tastecount[0]==0&&order.tastecount[1]==0&&order.tastecount[2]==0)
{
System.out.print(" ");
}
}
public static void userout(Order[] order,int[] tablex,double[] price, int x)
{
User[] users=new User[20];
int count=0;
int judge=0;
String[] word=new String[20];
for (int i = 0; i < x; i++)
{
if (count == 0)
{
word[count]=order[tablex[i]].user.name;
count++;
}
else
{
for (int j = 0; j < count; j++) {
if (order[tablex[i]].user.name.equals(word[j])) {
judge=1;
break;
}
}
if (judge == 0) {
word[count]=order[tablex[i]].user.name;
count++;
} else if (judge == 1) {
judge = 0;
}
}
}
// Arrays.sort(word);
Arrays.sort(word, Comparator.nullsLast(Comparator.naturalOrder()));
for (int i = 0; i < count; i++)
{
if(users[i]==null)
{users[i]=new User();}
for (int j = 0; j < x; j++)
{
if(word[i].equals(order[tablex[j]].user.name))
{
users[i].name=order[tablex[j]].user.name;
users[i].tele=order[tablex[j]].user.tele;
users[i].pay=users[i].pay+(int)price[j];
}
}
}
System.out.print("n");
for(int i=0;i<count;i++)
{
System.out.print(users[i].name+" "+users[i].tele+" "+users[i].pay);
if(i+1<count){
System.out.print("n");}
}
}
public static void main(String[] args)
{
Order[] order=new Order[20];
Menu menu=new Menu();
User[] user=new User[20];
Scanner scan=new Scanner(System.in);
String regexf="\p{IsHan}{1,10}";
String regexn="\d{1,12}";
Pattern patternf=Pattern.compile(regexf);
Pattern patternx=Pattern.compile(regexn);
String str;//输入数据存储
String dishname = null;
int n=0;//判断输入格式返回值
int table=0;//桌号计数
long[] num=new long[9];//临时点菜存储数据
int[] tablex=new int[10];
int[][] delet=new int[10][2];
int del=0;//删除单号数据
int[] price=new int[10];//总价存储数组
double[] disprice=new double[10];
double dis=0,dis1=0;
while(true)
{
str=scan.nextLine();
if(str.equals("end"))
{
for(int i=0;i<table;i++)
{
dis1=judgetime(order[tablex[i]].time,i);
if (dis1!=0)//输出价格
{
for (int j = 0; j < order[tablex[i]].ordercount; j++) {
dis=discountnum(order[tablex[i]],dis1,j);
price[i]=price[i]+order[tablex[i]].getTotalPrice(j);
disprice[i]=order[tablex[i]].getTotalPrice(j)*dis+disprice[i];
disprice[i]=Math.round(disprice[i]);
}
System.out.print("table "+(tablex[i])+": "+price[i]+" "+Math.round(disprice[i]));
dishout(order[tablex[i]]);
if(i+1<table)
System.out.print("n");
}
else
{
System.out.print("table "+(tablex[i])+" out of opening hoursn");
}
}
userout(order,tablex,disprice,table);
break;
}
else
{
Matcher matcher1 = patternf.matcher(str);
Matcher matcher2 = patternx.matcher(str);
String[] word=str.split("\s+");
n = Match(str);
if (word[0].matches("\p{IsHan}{1,10}"))
{
menu.addDish(word);
}
else if(n==1)//桌号与时间
{
int i = 0;
while (matcher2.find())
{
num[i] = Long.parseLong(matcher2.group());
i++;
}
tablex[table]=(int)num[0];
if (order[tablex[table]] == null||order[tablex[table]].user==null)
{
order[tablex[table]] = new Order();
order[tablex[table]].user=new User();
}
i=order[tablex[table]].addtable(str,num);
table=i+table;
}
else if(n == 2 || n == 31)//点菜
{
if(table==0)
{break;}
int s = 0;
while (matcher1.find()) {
dishname = matcher1.group();
}
while (matcher2.find()) {
num展开 = Integer.parseInt(matcher2.group());
s++; }
if(n==2)
{
order[tablex[table-1]].addARecord(0,(int)num[0], dishname, (int)num[1], (int) num[2],-1, menu);
}
else
{
order[tablex[table-1]].addARecord(0,(int)num[0], dishname, (int)num[2], (int) num[3], (int)num[1], menu);
}
}
else if (n == 3 || n == 41) //代付菜
{
if(table==0)
{break;}
while (matcher1.find()) {
dishname = matcher1.group();
}
int r = 0;
while (matcher2.find()) {
num[r] = Integer.parseInt(matcher2.group());
r++;
}
if(n==3)
{
order[tablex[table-1]].addARecord(0,(int)num[0], dishname, (int)num[1], (int) num[2],-1, menu);
}
else
{
order[tablex[table-1]].addARecord(0,(int)num[0], dishname, (int)num[2], (int) num[3], (int)num[1], menu);
}
}
else if (n == 4)//删除
{
System.out.print("nn进入删除");
while (matcher2.find())
{
delet[del][1] = Integer.parseInt(matcher2.group());
delet[del][0] = table;
del++;
}
order[tablex[table-1]].delARecordByOrderNum(delet[del-1][1], menu);
}
}//非end else
}//while
}//main
}//main