BLOG-1
一、题目集分析
本次博客将对PTA的前三次题目集进行分析,情况如下:
(1)题量分析:
- 第一次练习共计9题
- 第二次练习共计4题
- 第三次练习共计7题
从题量而言,数量适中。
(2)知识点分析:
- 第一次题目集更侧重于编程基础,主要涉及基本数据类型,也涉及部分引用类型,其次还多用到流程控制当中的if-else语句以及循环控制语句,数组应用参入其中。
- 第二次题目集出现了菜单题目1和2,开始涉及类的书写。同时还出了一道日期应用题,在日期的题目中考察了同学们对时间计算的原理的理解,最后一题为小明跳格子,考察递推。总体难度上调。
- 第三次题目集延续题目集二出现了菜单3的题目,此题综合性较强,涉及知识点的灵活运用程度较高。第二三题则涉及数组的遍历与查重和重复数据的删除。紧接一道封装性问题。最后是一道数据类型转换题和日期计算题。题目涉及面较广,内容上综合性不断提升。
二、相关题目源码分析
- 菜单计价1
- 题目:



2.题目类图

3.题目分析
菜单一的点菜十分简单,由于已经给出了菜谱上的四种菜品,并且声明大,中,小份菜价的相关计算。故可直接采用if-else的多分支语句进行判断,再根据份量对应的计价标准进行先计算每一份菜品的单价,最后随着while循环的进行依次相加。期间,若遇到不存在的菜品,则直接输出菜名外加上“does not exist”。最后遇到“end”结束循环,输出计算的总价格。
4.源代码
import java.util.Scanner;
public class Main{
public static void main(String[] args){
//创建输入对象
Scanner input = new Scanner(System.in);
//用户输入量
String name = input.next();
//计算用量
int sum = 0;
double price = 0;
double[] num = {1,1.5,2};
//循环
while(!name.equals("end")){
int fen = input.nextInt();
if(name.equals("西红柿炒蛋")){
price = 15 * num[fen-1];
}else if(name.equals("清炒土豆丝")){
price = 12 * num[fen-1];
}else if(name.equals("麻婆豆腐")){
price = 12 * num[fen-1];
}else if(name.equals("油淋生菜")){
price = 9 * num[fen-1];
}else{
price = 0;
System.out.println(name+" does not exist");
}
sum += Math.round(price);
name = input.next();
}
System.out.println(sum);
}
}
菜单计价2
1.题目



2.题目类图

3.题目分析
(1)根据题目所给的模板,先写出四个基本类:菜品类,菜谱类,点菜记录类,订单类的相关属性和方法。其中,菜谱类中建立出菜品类的对象数组,订单类中建立出点菜记录类的对象数组。
(2) 再开始书写主类,首先对输入进行构架。由题意可知每一次输出都由“end”才截至。故须采用while循环,当输入语句不是“end“时循环读取一行数据。
(3)由于菜单的构建和订单的构建的组成成分互不相同,所以采用整行输入,读入后用slip方法对整行字符串进行拆分,通过拆分后所得字符串数组的长度来决定是将最新录入的信息存入Dish数组还Records数组。
(4)在对每次信息的输入进行处理时,其中遇到数字为字符的形式时,要采用Integer.parseInt的方法,将相关数据转为整形进行储存。
(5)再对各个类中的方法进行分析:<1>Dish类中除了默认的构造方法外加入了一个传参构造,外加一个根据份量计算菜品单价的方法。<2>Menu类中含有一个Dish类的数组作为变量属性,外加一个根据菜谱名在Dish数组中寻找特定的Dish对象的方法。<3>record类较为简单,除构造方法外加入一个计算单条记录的价格,这个价格是在根据份量大小计算出的一份菜品的基础上再乘以份数。<4>Order类中含有一个record的对象数组,外加一个计算所有记录的单品价格的总价和一个输出方法,用于输出总价。
4.源代码(由于很难找到菜单2的源代码,故改为了进阶般的菜单代码)import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Menu m = new Menu();
Order[] order = new Order[55];
int cent1 = 0;//用于记录桌数
Scanner input = new Scanner(System.in);
String s = input.nextLine();
while(!s.equals("end")) {
//用一句话读入,再用slip分割
//先建立菜单,再建立table,再建立订单,期间均用第一个字符进行区别
//菜单
if(s.charAt(0)!='t'&&(s.charAt(0)<'1'||s.charAt(0)>'9')) {
//将一句话的各个成分拆开,从而以各种形式建立dish
String[] str1 = s.split(" ");
if(str1.length==2) {
int price1 = Integer.parseInt(str1[1]);
m.addDish(str1[0],price1);
}else if(str1.length==4) {
int price2 = Integer.parseInt(str1[2]);
int tese = 0;
if(str1[3].equals("T")) {
tese = 1;
}
m.addDish(str1[0],str1[1],price2,tese);
}else {
System.out.println("wrong format");
}
}
if(s.charAt(0)=='t') {
String[] str2 = s.split(" ");
//判断用户信息是否合法
if(str2[3].length()<10&&str2[4].length()==11) {
int tableNumber = Integer.parseInt(str2[1]);
order[cent1] = new Order(tableNumber,str2[3],str2[4],str2[5],str2[6]);
cent1++;
}else {
System.out.println("wrong format");
}
}
if((s.charAt(0)-'0')>=1&&(s.charAt(0)-'0')<=9&¢1-1>=0&&order[cent1-1]!=null) {
String[] str3 = s.split(" ");
if(str3.length==4) {
//数据整数话,名字找dish
int recordNumber = Integer.parseInt(str3[0]);
int portion = Integer.parseInt(str3[2]);
int fenshu = Integer.parseInt(str3[3]);
Dish a = m.searthDish(str3[1]);
if(a!=null) {
order[cent1-1].addARecord(recordNumber,a,portion,fenshu);
}
}else if(str3.length==5){
int recordNumber = Integer.parseInt(str3[0]);
int degree = Integer.parseInt(str3[2]);
int portion = Integer.parseInt(str3[3]);
int fenshu = Integer.parseInt(str3[4]);
Dish a = m.searthDish(str3[1]);
if(a!=null) {
order[cent1-1].addARecord(recordNumber,a,degree,portion,fenshu);
}
}
}
s = input.nextLine();
}
//输出每个用户的订单
for(int i=0;i<cent1;i++) {
if(order[i].ifOpen()!=0) {
order[i].showOrder(m);
}else {
//table 1 out of opening hours
System.out.println("table "+order[i].getOrderNum()+" out of opening hours");
}
}
//输出每桌价格以及口味
for(int i=0;i<cent1;i++) {
if(order[i].ifOpen()!=0) {
order[i].totalTaste();
order[i].showTaste();
}
}
//按拼音输出用户信息
//从小到大输出
for(int i=0;i<cent1;i++) {
int flag=i;
for(int j=i+1;j<cent1;j++) {
if(order[flag].getName().charAt(0)>order[j].getName().charAt(0)) {
flag=j;
}
}
Order temp = order[i];
order[i] = order[flag];
order[flag] = temp;
}
for(int i=0;i<cent1;i++) {
for(int j=i+1;j<cent1;j++) {
if(order[i].getName().equals(order[j].getName())) {
//int n1 = order[i].getTotalPrice()[1];
//int n2 = order[j].getTotalPrice()[1];
//int n = n1+n2;
//int n=100;
int n = order[j].getTotalPrice()[1];
int a= 1;
int b=2;
int c=3;
System.out.println(a=b+c);
System.out.println(a);
System.out.println(order[i].getTotalPrice()[1]=order[i].getTotalPrice()[1]+n);
System.out.println(order[i].getTotalPrice()[1]);
//order[i].getTotalPrice()[1]=n;
}
}
if(order[i].ifOpen()!=0) {
System.out.println(order[i].getName()+" "+order[i].getPhnoeNumber()+" "+order[i].getTotalPrice()[1]);
}
}
}
}
class Menu {
private Dish[] dishs = new Dish[100];//菜品数组,保存所有菜品信息
private static int cent=0;
//特色菜的菜品添加方法
public void addDish(String name,double unit_price){
dishs[cent]=new Dish(name,unit_price);
cent++;
}
//非特色菜的菜品添加方法
public void addDish(String name,String taste,double unit_price,int tese){
dishs[cent]=new Dish(name,taste,unit_price,tese);
cent++;
}
//根据菜名在菜谱中查找菜品信息,返回Dish对象
public Dish searthDish(String dishName) {
int flag=-1;
for(int i=0;i<cent;i++) {
if(dishs[i].getName().compareTo(dishName)==0) {
flag=i;
break;
}
}
if(flag!=-1) {
return dishs[flag];
}else {
System.out.println(dishName+" does not exist");
return null;
}
}
}
class Order {
private int[] price = new int[2];
//订单对应用户信息
private int orderNum;
private String name;
private String phnoeNumber;
private String time1;
private String time2;
public String getName() {
return name;
}
public int getOrderNum() {
return orderNum;
}
//各种口味菜的份数
private int chuancai;
private int jincai;
private int zhecai;
//各种口味菜的平均酸甜辣度
private String chuancaiDegree ;
private String jincaiDegree;
private String zhecaiDegree;
//每个用户信息都对应一组点菜记录
private Record[] records = new Record[100];
private int cent=0;
Order(int n,String s1,String s2,String time1,String time2){
this.orderNum=n;
this.name=s1;
this.phnoeNumber=s2;
this.time1=time1;
this.time2=time2;
}
public String getPhnoeNumber() {
return phnoeNumber;
}
public void addARecord(int orderNum,Dish dish,int portion,int num) {
records[cent] = new Record(orderNum,dish,portion,num);
cent++;
}
public void addARecord(int num,Dish dish,int degree,int portion,int fen) {
records[cent] = new Record(num,dish,degree,portion,fen);
cent++;
}
//计算各种菜系的份数以及每种菜系的平均酸辣甜度
public void totalTaste() {
int sum1=0;//川菜口味度总和
int sum2=0;//晋菜口味度总和
int sum3=0;//浙菜口味度总和
int n1;//川菜平均口味度
int n2;//晋菜平均口味度
int n3;//浙菜平均口味度
for(int i=0;i<cent;i++) {
String s = this.records[i].getDish().getTaste();
if(s!=null) {
if(s.equals("川菜")) {
sum1+=this.records[i].getDegree()*this.records[i].getFen();
this.chuancai+=records[i].getFen();
}else if(s.equals("晋菜")) {
sum2+=this.records[i].getDegree()*this.records[i].getFen();
this.jincai+=this.records[i].getFen();
}else if(s.equals("浙菜")) {
sum3+=this.records[i].getDegree()*this.records[i].getFen();
this.zhecai+=this.records[i].getFen();
}
}
}
String[] chuancai = {"不辣","微辣","稍辣","辣","很辣","爆辣"};
String[] jincai = {"不酸","微酸","稍酸","酸","很酸"};
String[] zhecai = {"不甜","微甜","稍甜","甜"};
if(this.chuancai!=0) {
n1=Math.round(sum1/this.chuancai);
this.chuancaiDegree=chuancai[n1];
}
if(this.jincai!=0) {
n2=Math.round(sum2/this.jincai);
this.jincaiDegree=jincai[n2];
}
if(this.zhecai!=0) {
n3=Math.round(sum3/this.zhecai);
this.zhecaiDegree=zhecai[n3];
}
}
//返回周几
public int dateToWeek() {
SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd");
int[] weekDays = {7,1,2,3,4,5,6};
Calendar cal = Calendar.getInstance();
Date date;
try {
date = f.parse(this.time1);
cal.setTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
// 一周的第几天
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0)
w = 0;
return weekDays[w];
}
//先判断具体时间,根据时间确定是否营业以及营业的具体时间用于计算折扣
public double ifOpen() {
double flag = 0;
String[] s1 = this.time1.split("/");
String[] s2 = this.time2.split("/");
int hour = Integer.parseInt(s2[0]);
int mintue = Integer.parseInt(s2[1]);
if(this.dateToWeek()>=1&&this.dateToWeek()<=5) {
if((hour>=17&&hour<20)||(hour==20&&mintue<=30)) {
flag=0.8;
}else if((hour>10&&hour<14)||(hour==10&&mintue>=30)||(hour==14&&mintue<=30)) {
flag=0.6;
}
}else {
if((hour>9&&hour<21)||(hour==9&&mintue>=30)||(hour==21&&mintue<=30)) {
flag=1;
}
}
return flag;
}
//计算订单的总价
public int[] getTotalPrice(){
//首先计算每桌菜的总价,再用总价乘以折扣
double price1=0;
double price2=0;
double price3=0;
int[] sum = new int[2];
sum[0]=0;
sum[1]=0;
//计算打折前的总价格(小数)
for(int i=0;i<cent;i++) {
price1+=this.records[i].getPrice();
}
//折扣计算:每条记录菜品在乘以份额后的价格后四舍五入,再乘以折扣后在四舍五入
//再把所有条记录加和取整
for(int i=0;i<cent;i++) {
//非特色菜
if(this.records[i].getDish().getTese()==0) {
price2+=Math.round(records[i].getPrice()*this.ifOpen());
}else {//特色菜
if(this.dateToWeek()>=1&&this.dateToWeek()<=5) {
price3+=Math.round(records[i].getPrice()*0.7);
}else {
price3+=Math.round(records[i].getPrice()*1);
}
}
}
sum[0]=(int)price1;//折扣前的总价格
sum[1]=(int)price2+(int)price3;//折扣后的总价格
return sum;
}
//每桌订单的输出
public void showOrder(Menu menu) {
System.out.println("table "+orderNum+": ");
for(int i=0;i<cent;i++) {
System.out.println(this.records[i].getNum()+" "+this.records[i].getDish().getName()+" "+(int)this.records[i].getPrice());
}
}
//每桌价格以及折后价以及口味的输出
public void showTaste() {
if(this.chuancai==0&&this.jincai==0&&this.zhecai==0) {
System.out.println("table "+orderNum+": "+this.getTotalPrice()[0]+" "+this.getTotalPrice()[1]);
}else if(this.chuancai!=0&&this.jincai==0&&this.zhecai==0) {
System.out.println("table "+orderNum+": "+this.getTotalPrice()[0]+" "+this.getTotalPrice()[1]+" 川菜 "+this.chuancai+" "+this.chuancaiDegree);
}else if(this.chuancai==0&&this.jincai!=0&&this.zhecai==0) {
System.out.println("table "+orderNum+": "+this.getTotalPrice()[0]+" "+this.getTotalPrice()[1]+" 晋菜 "+this.jincai+" "+this.jincaiDegree);
}else if(this.chuancai==0&&this.jincai==0&&this.zhecai!=0) {
System.out.println("table "+orderNum+": "+this.getTotalPrice()[0]+" "+this.getTotalPrice()[1]+" 浙菜 "+this.zhecai+" "+this.zhecaiDegree);
}else if(this.chuancai!=0&&this.jincai!=0&&this.zhecai==0) {
System.out.println("table "+orderNum+": "+this.getTotalPrice()[0]+" "+this.getTotalPrice()[1]+" 川菜 "+this.chuancai+" "+this.chuancaiDegree+" 晋菜 "+this.jincai+" "+this.jincaiDegree);
}else if(this.chuancai!=0&&this.jincai==0&&this.zhecai!=0) {
System.out.println("table "+orderNum+": "+this.getTotalPrice()[0]+" "+this.getTotalPrice()[1]+" 川菜 "+this.chuancai+" "+this.chuancaiDegree+" 浙菜 "+this.zhecai+" "+this.zhecaiDegree);
}else if(this.chuancai==0&&this.jincai!=0&&this.zhecai!=0) {
System.out.println("table "+orderNum+": "+this.getTotalPrice()[0]+" "+this.getTotalPrice()[1]+" 晋菜 "+this.jincai+" "+this.jincaiDegree+" 浙菜 "+this.zhecai+" "+this.zhecaiDegree);
}else if(this.chuancai!=0&&this.jincai!=0&&this.zhecai!=0) {
System.out.println("table "+orderNum+": "+this.getTotalPrice()[0]+" "+this.getTotalPrice()[1]+" 川菜 "+this.chuancai+" "+this.chuancaiDegree+" 晋菜 "+this.jincai+" "+this.jincaiDegree+" 浙菜 "+this.zhecai+" "+this.zhecaiDegree);
}
}
//根据序号删除一条记录
public void delARecordByOrderNum(int orderNum) {
}
}
class Record {
private int num;
private Dish dish;
private int degree;
private int portion;
private int fen;
public int getNum() {
return num;
}
public Dish getDish() {
return dish;
}
public int getDegree() {
return degree;
}
public int getFen() {
return fen;
}
//有两种建立订单的方式
//其一:2 油淋生菜 2 1
//其二:3 麻婆豆腐 2 3 2
Record(int num,Dish dish,int portion,int fen){
this.num=num;
this.dish=dish;
this.portion=portion;
this.fen=fen;
}
Record(int num,Dish dish,int degree,int portion,int fen){
this.num=num;
this.dish=dish;
this.degree=degree;
this.portion=portion;
this.fen=fen;
}
//计价,计算本条记录的价格
public double getPrice() {
double sum=0;
sum+=Math.round(this.dish.getPrice(this.portion))*this.fen;
return sum;
}
}
class Dish {
private String name;
private String taste;
private double unit_price;
private int tese=0;
public String getName() {
return name;
}
public String getTaste() {
return taste;
}
public int getTese() {
return tese;
}
//建立一道菜有两种形式
//其一:油淋生菜 9
//其二:东坡肉 浙菜 25 T
Dish(String name,double unit_price) {
this.name=name;
this.unit_price=unit_price;
}
Dish(String name,String taste,double unit_price,int tese) {
this.name=name;
this.taste=taste;
this.unit_price=unit_price;
this.tese=tese;
}
public int getPrice(int portion) {
double []a = new double [3];
a[0]=1;
a[1]=1.5;
a[2]=2;
double sum=0;
sum+=this.unit_price*a[portion-1];
double price = Math.round(sum);
return (int)price;
}
}
- 菜单计价3
1.题目







2.题目类图

3.题目分析
本体相较于菜单二多出了table的时间安排(包括对营业时间的限制)以及删除订单中不存在的菜名的相关信息以及开辟桌子进行代点菜的功能。基本解决思路为新建一个table类,每一个table类的开辟都与主类中order数组的对象实例化相对应。即再循环输入的过程中作出限制,在进行每行信息处理的过程中对每一行字符串的第一个字符进行判断,如果第一个字母是"t"则实例化一个新的order对象于此同时实例化一个table对象。(Ps:本次实验中的不好之处在此处体现,由于本人在此次实验的输入代码处理过程中采用了边分割字符串信息,边处理字符串信息,于是使主类的代码过于冗杂,没有什么章法。同时在分割处理信息的过程中在主类上也穿插了对时间信息的判断。)

但在营业时间的合法性继续选择了在table类中进行判断,同时table类中还加入了根据日期返回对应周几,小时以及分钟的方法:



再根据所计算的时间分段对所计算出的菜品价格进行折扣处理,从而完成总价计算。
于此同时本类中还有一个ifOpen方法,通过if-else分支语句完成对时间合理性的判断。

4.源代码
import java.util.Scanner;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Main {
//判断日期的数值是否正确的方法
public static boolean ifDate(String s1,String s2) {
boolean flag=true;
//首先拆分,其次对值
String[] str1 = s1.split("/");
String[] str2 = s2.split("/");
int year = Integer.parseInt(str1[0]);
int month = Integer.parseInt(str1[1]);
int day = Integer.parseInt(str1[2]);
int hour = Integer.parseInt(str2[0]);
int mintue = Integer.parseInt(str1[1]);
int second = Integer.parseInt(str1[2]);
if(hour<0||hour>60||mintue<0||mintue>60||second<0||second>60||month<0||month>12) {
return false;
}
//判断闰年
int a1=0;
if((year%4==0&&year%100!=0)||(year%400==0)){
a1=1;
}
//判断大小月
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
if(day<0||day>31){
flag=false;
}
if(month==2){
if(a1==0&&(day<0||day>28)){
flag=false;
}else if(a1==1&&(day<0||day>29)){
flag=false;
}
}else if(month==4||month==6||month==9||month==11){
if(day<0||day>30){
flag=false;
}
}
}
return flag;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String s = input.next();
//菜单只有一份
caidan m = new caidan();
//设置控制数量变化
int num=0;
//桌号最多有55桌
Table[] a = new Table[55];
//订单最多有55份
Order[] dingdan = new Order[55];
//标记的作用:(1)因为出了桌子就没有菜单了,所以标记一下:只要出了桌子再出现菜单的语句时就非法输入
//(2)用Flag可以区分二次输入,及裁剪出菜单中的菜是否为特色菜
int Flag=0;
//标记由于(1)桌号输入错误(2)由于日期的位数输出错误而导致输出wrong format且跳出循环的情况
int Flagyi=1;
//标记由于日期的数据输入错误而导致的输出
int Flager=1;
while(!s.equals("end")&&Flagyi==1&&Flager==1) {
if (s.charAt(0)!='t'&&(s.charAt(0)<'1'||s.charAt(0)>'9')) {
if(Flag==0) {
String q = input.nextLine();
//通过字符串去查输入的菜是否为特色菜
boolean biaoji = q.contains("T");
//通过字符串查点判断输入是否是浮点数
boolean status = q.contains(".");
if(status) {
System.out.println("wrong format");
}else {
//把q字符串拆开取前一部分计价
String[] str1 = q.split(" ");
//System.out.println(str1[1]);
int n=Integer.parseInt(str1[1]);
if(biaoji) {
m.addDish(s,n,1);
}else {
m.addDish(s,n);
}
}
}else {
String qita = input.nextLine();
System.out.println("invalid dish");
}
}
//只要开了一张桌子就要与此同时开一张订单
if(s.charAt(0)=='t') {
Flag=1;
String zhuohao = input.next();
if(zhuohao.charAt(0)-'0'>=1&&zhuohao.charAt(0)-'0'<=9) {
int n1 = Integer.parseInt(zhuohao);
//判断日期格式是否正确
String s1 = input.next();
String s2 = input.next();
String[] str1 = s1.split("/");
String[] str2 = s2.split("/");
//第一个要求数据的格式要正确
if(str1[0].length()==4&&str1[1].length()<=2&&str1[2].length()<=2&&str2[0].length()<=2&&str2[1].length()<=2&&str2[2].length()<=2) {
//第二个要求数据的数值要合法
boolean DateTrue=ifDate(s1,s2);
if(DateTrue) {
num++;
a[num] = new Table(n1,s1,s2);
dingdan[num] = new Order();
if(a[num].InTime()) {
System.out.println("table "+a[num].getNumber()+": ");
}else {
System.out.println("not a valid time period");
}
}else {
Flager=0;
System.out.println("table "+n1+": "+" date error");
}
}else {
Flagyi=0;
}
}else {
//本行读入的第二个数据有两种情况
//(1)table a 2023/3/15 12/00/00*****第二次输入后会产生一个空格
//(2)tab le 2 2023/3/15 12/00/00*****第二次输入后一起读会产生两个空格
//读入后面的非法无效数据
String feifa = input.nextLine();
String[] str3 = feifa.split(" ");
if(str3.length==3) {
Flagyi=0;
}else {
//"table"格式非法->输出wrong format,但后面的记录上一桌
System.out.println("wrong format");
}
}
}
//***//订单里面有输出
if((s.charAt(0)-'0')>=1&&(s.charAt(0)-'0')<=9&&Flagyi==1&&Flager==1) {
Dish a1 = new Dish();
int n2 = Integer.parseInt(s);
String s2 = input.next();
if(!s2.equals("delete")) {
a1 = m.searthDish(s2);
int n3 = input.nextInt();
int n4 = input.nextInt();
if(a1!=null) {
dingdan[num].addARecord(n2, a1, n3, n4);
}
}else {
dingdan[num].delARecordByOrderNum(n2);
}
}
s = input.next();
}
//总的输出
if(Flagyi==1&&Flager==1) {
for(int i=1;i<=num;i++) {
System.out.println("table "+a[i].getNumber()+": "+(int)dingdan[i].getTotalPrice()+" "+(int)dingdan[i].getTotalPrice(a[i].ifOpen()));
}
}else {
if(Flager==1) {
System.out.println("wrong format");
}
}
input.close();
}
}
//菜单由一条或多条菜品记录组成,每条记录一行
class caidan {
private Dish[] dishs = new Dish[100];//菜品数组,保存所有菜品信息
public Dish[] getDishs() {
return dishs;
}
public void setDishs(Dish[] dishs) {
this.dishs = dishs;
}
private static int cent=0;
//根据菜名在菜谱中查找菜品信息,返回Dish对象。
public Dish searthDish(String dishName){
int flag=-1;
for(int i=0;i<cent;i++) {
if(dishs[i].getName().compareTo(dishName)==0) {
flag=i;
break;
}
}
if(flag!=-1) {
return dishs[flag];
}else {
System.out.println(dishName+" does not exist");
return null;
}
}
//特色菜的菜品添加方法
public void addDish(String dishName,double unit_price,int tese){
dishs[cent]=new Dish(dishName,unit_price,tese);
cent++;
}
//非特色菜的菜品添加方法
public void addDish(String dishName,double unit_price){
dishs[cent]=new Dish(dishName,unit_price);
cent++;
}
public void ShowCaidan() {
for(int i=0;i<cent;i++) {
System.out.println(dishs[i].getName()+" "+dishs[i].getprice());
}
}
}
//每条菜品记录包含:菜名、基础价格 两个信息。
class Dish {
private String name;
private double unit_price;
private int tese=0;
public Dish(String name, double unit_price, int tese) {
super();
this.name = name;
this.unit_price = unit_price;
this.tese = tese;
}
public Dish(String name, double unit_price) {
super();
this.name = name;
this.unit_price = unit_price;
}
public Dish() {
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public double getprice() {
return unit_price;
}
public int getTese() {
return tese;
}
//判断单份菜价是否合理
public boolean Inprice() {
boolean flag=false;
if(this.unit_price<=300&&this.unit_price>=0) {
flag=true;
}
return flag;
}
//计算单道菜的价格(加上份额)
public double getPrice(int portion) {
double sum=0;
double[] a = new double[3];
a[0]=1;
a[1]=1.5;
a[2]=2;
sum=this.getprice()*a[portion-1];
return Math.round(sum);
}
}
//订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。
class Order {
private Record[] records = new Record[100];//保存订单上每一道的记录
private static int cent1 = 0;
public static int getCent1() {
return cent1;
}
//计算打折前的总价格
public double getTotalPrice(){
double sum = 0;
for(int i=0;i<cent1;i++) {
if(records[i].flag==1) {
sum+=records[i].getPrice();
}
}
return Math.round(sum);
}
//计算打折后的总价格(由时间段产生的折扣和特色菜产生的折扣)
//菜价的计算方法:
//周一至周五 7折, 周末全价。
//所以传参要传它是周几
public double getTotalPrice(double flag){
double sum = 0;
if(flag!=-1) {
for(int i=0;i<cent1;i++) {
if(records[i].flag==1) {
if(flag==0.8||flag==0.6) {//周一到周五
if(records[i].getD().getTese()==1) {//特色菜情况
sum+=records[i].getPrice()*0.7;
}else {//非特色菜情况
sum+=records[i].getPrice()*flag;
}
}else if(flag==1) {//周末
sum+=records[i].getPrice();
}
}
}
}
return Math.round(sum);
}
public void addARecord(int orderNum,Dish d,int portion,int fenshu){//添加一条菜品信息到订单中
//订单顺序的序号必须按照从小到大输入
if(cent1==0) {
records[cent1]=new Record(orderNum,d,portion,fenshu);
records[cent1].showTheResultOfRecord();
cent1++;
}else if(cent1!=0&&records[cent1-1].getOrderNum()<orderNum) {
records[cent1]=new Record(orderNum,d,portion,fenshu);
records[cent1].showTheResultOfRecord();
cent1++;
}else {
System.out.println("record serial number sequence error");
}
}
//根据序号删除一条记录
//还需产生记录重复删除的数组,通过比对数字中的数据确定是否为重复删除
private int[] chachong = new int[55];
public void delARecordByOrderNum(int orderNum){
//首先判断是否为重复删除
int flag=0;
int j;
for(j=0;this.chachong[j]!=0;j++) {
if(this.chachong[j]==orderNum) {
flag=1;//找到说明已经删除过
break;
}
}
if(flag==1) {
System.out.println("deduplication "+orderNum);
}else {
this.chachong[j]=orderNum;
//其次在所有记录中寻找该条记录
if(this.findRecordByNum(orderNum)) {
records[orderNum-1].flag=0;
}else {
System.out.println("delete error");
}
}
}
public boolean findRecordByNum(int orderNum){//根据序号查找一条记录
boolean flag=false;
for(int i=0;i<cent1;i++) {
if(records[i].getOrderNum()==orderNum) {
flag=true;
break;
}
}
return flag;
}
}
//点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。
class Record {
private int orderNum;//序号
private Dish d;//菜名
private int portion;//份额
private int fenshu;//份数
public int flag=1;//用于标记记录是否被删除
public Record(int orderNum, Dish d, int portion, int fenshu) {
super();
this.orderNum = orderNum;
this.d = d;
this.portion = portion;
this.fenshu = fenshu;
}
public int getOrderNum() {
// TODO Auto-generated method stub
return this.orderNum;
}
public Dish getD() {
// TODO Auto-generated method stub
return this.d;
}
public int getPortion() {
return this.portion;
}
public int getFenshu() {
return this.fenshu;
}
public int getPrice(){//计价,计算本条记录的价格
int sum=0;
sum+=this.d.getPrice(this.portion)*this.fenshu;
return sum;
}
public void setOrderNum(int orderNum) {
this.orderNum = orderNum;
}
public void setD(Dish d) {
this.d = d;
}
public void setPortion(int portion) {
this.portion = portion;
}
public void setFenshu(int fenshu) {
this.fenshu = fenshu;
}
//判断份额是否超标
public boolean Inportion() {
boolean flag=false;
if(this.portion>=1&&this.portion<=3) {
flag=true;
}
return flag;
}
//份数是否超标
public boolean Infenshu() {
boolean flag=false;
if(this.fenshu<=15) {
flag=true;
}
return flag;
}
//实现对一条记录的判出
public void showTheResultOfRecord() {
if(this.Inportion()&&this.Infenshu()) {
System.out.println(this.getOrderNum()+" "+this.getD().getName()+" "+this.getPrice());
}else if(!this.Inportion()){
this.flag=0;
System.out.println(this.getOrderNum()+" portion out of range "+this.getPortion());
}else if(!this.Infenshu()) {
this.flag=0;
System.out.println(this.getOrderNum()+" num out of range "+this.getFenshu());
}
}
}
//桌号标识独占一行,包含两个信息:桌号、时间。
//桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。
class Table {
private int number;
private String time1;
private String time2;
//带参构造器
public Table(int number, String time1, String time2) {
super();
this.number = number;
this.time1 = time1;
this.time2 = time2;
}
public int getNumber() {
return number;
}
//最先判断时间的有效性
public boolean InTime() {
boolean a=false;
String[] str1 = time1.split("/");
int year = Integer.parseInt(str1[0]);
//System.out.println(year);
if(year>=2022&&year<=2023) {
a=true;
}
return true;
}
//返回周几
public int dateToWeek() {
SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd");
int[] weekDays = {7,1,2,3,4,5,6};
Calendar cal = Calendar.getInstance();
Date date;
try {
date = f.parse(this.time1);
cal.setTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
// 一周的第几天
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0)
w = 0;
return weekDays[w];
}
//返回小时
public int dateToHour() {
SimpleDateFormat f = new SimpleDateFormat("HHHH/mm/ss");
Calendar cal = Calendar.getInstance();
Date date;
try {
date = f.parse(this.time2);
cal.setTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
//24时中的第几个小时
int w = cal.get(Calendar.HOUR_OF_DAY);
return w;
}
//返回分钟
public int dateToMINTUE() {
SimpleDateFormat f = new SimpleDateFormat("HHHH/mm/ss");
Calendar cal = Calendar.getInstance();
Date date;
try {
date = f.parse(this.time2);
cal.setTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
//第几分钟
int w = cal.get(Calendar.MINUTE);
return w;
}
/*折扣的计算方法(注:以下时间段均按闭区间计算):
周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。
周末全价,营业时间:9:30-21:30
如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"*/
//首先能营业则返回等于0的数,不能营业则返回折扣数
public double ifOpen() {
double flag=-1;
if(this.dateToWeek()>=1&&this.dateToWeek()<=5) {
if((this.dateToHour()>=17&&this.dateToHour()<20)||(this.dateToHour()==20&&this.dateToMINTUE()<=30)) {
flag=0.8;
}else if(this.dateToHour()>=10&&this.dateToHour()<=14) {
if((this.dateToHour()==10&&this.dateToMINTUE()<30)||(this.dateToHour()==14&&this.dateToMINTUE()>30)) {
flag=-1;
}else {
flag=0.6;
}
}
}else {
if(this.dateToHour()>=9&&this.dateToHour()<=21) {
if((this.dateToHour()==9&&this.dateToMINTUE()<30)||(this.dateToHour()==21&&this.dateToMINTUE()>30)) {
flag=-1;
}else {
flag=1;
}
}
}
if(flag==-1) {
System.out.println("table "+this.number+" out of opening hours");
}
return flag;
}
//判断桌号是否合法
public boolean Intable() {
boolean flag=false;
if(this.number>=1&&this.number<=55) {
flag=true;
}
return flag;
}
}
三、踩坑心得
(1)在第一次写菜单题目的时候并没有体会到java语言面向对象解决问题的好处,而是延续了C语言的思想去解决问题,当条件较为简单的时候用就基本的选择分支和循环语句就可以解决,但随着菜单难度的逐步提升,在解决现实问题的过程中相关条件的复杂度逐渐提升,故而java面向对象进行解决问题的优势得以体现。以一类一类的对象为攻克对象,更加符合平常逻辑。
(2)在写度数转换的时候发现在java中小数的默认类型为double类型,而若想用float类型要在小数后加上f。
四、主要困难和改进意见
当面对较为复杂的实际问题时,分析问题的能力较弱。当要构建出多个类并实现类之间的相互联系的时候,思维能力较弱。对对象数组的使用不够熟练。改进意见:应多敲代码。
五、总结
通过前三次的作业,我逐渐做到:
1、 掌握类与对象的基本概念;
2、 掌握类的声明、创建与使用方法;
3、 掌握类的构造方法的定义与使用方法
4、 掌握类的成员变量、成员方法的定义与使用方法;
5、 理解类变量、类方法与实例变量、实例方法的区别;
6、 理解Java语言中包的概念以及package、import语句的使用;
7、 理解引用变量与对象实例之间的关系与区别;
8、 理解方法调用时引用类型参数的传递过程;

浙公网安备 33010602011771号