pta题目集4-5以及期中考试总结性Blog

一、前言:pta题目集4难度大,在上一次菜单计价程序基础上增加了异常情况和特色菜,pta题目集5难度大,注意不是菜单计价程序-4,本题和菜单计价程序-4同属菜单计价程序-3的两个不同迭代分支,菜品分有不同菜系和口味程度;期中考试难度较低,主要考察了类的应用、继承和多态、抽象类与接口和compareTo方法重写。

二、设计与分析:

 

  题目集4:

   7-1 菜单计价程序-4

详情分析:

 

 

 

  1. 首先,代码通过Scanner类从标准输入接收用户输入的菜谱和订单信息。
  2. 接下来,使用Menu类和Dish类来创建菜单并添加菜品信息。
  3. 然后,使用Order类和Record类来创建订单,并根据用户输入的菜品信息添加记录。
  4. 在创建订单时,根据订单的时间信息计算菜单打折的比例。
  5. 最后,根据订单的记录和打折比例计算订单的总价,并按要求输出结果。

 

代码中的其他方法包括:

 

  • legala方法:判断日期是否合法。
  • legalb方法:判断时间是否合法。
  • runNian方法:判断是否是闰年。
  • vaildTime方法:判断时间是否在有效范围内。
  • canParseInt方法:判断字符串是否可以转换为整数。

 

代码逻辑上比较清晰,通过多个类的相互调用来实现菜单和订单的管理。代码也考虑了一些错误输入的情况,并给出相应的错误提示。

  题目集5:

   7-1 菜单计价程序-5

详情分析:

  1. 首先,代码通过Scanner类从标准输入接收用户输入的菜谱和订单信息。
  2. 接下来,使用Menu类和Dish类来创建菜单并添加菜品信息。
  3. 然后,使用Order类和Record类来创建订单,并根据用户输入的菜品信息添加记录。
  4. 在创建订单时,根据订单的时间信息计算菜单打折的比例。
  5. 创建Table类来保存桌子的信息,包括桌号和订单信息。
  6. 创建Customer类来保存客户的信息,包括姓名、电话和消费金额。
  7. 在处理订单信息时,根据用户输入的菜品信息进行相应的操作,如添加记录、删除记录等。
  8. 最后,根据订单的记录和打折比例计算订单的总价,并按要求输出结果。

代码中的其他方法包括:

  • canParseInt方法:判断字符串是否可以转换为整数。
  • account方法:根据日期和时间判断是否在营业时间内,并返回打折比例。
  • week方法:根据日期字符串计算星期几。

代码逻辑上比较清晰,使用了多个类来管理菜单、订单、桌子和客户的信息。代码也考虑了一些错误输入的情况,并给出相应的错误提示。

 

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
    public static void main(String[] args) throws ParseException {
        Scanner in = new Scanner(System.in);
        Menu menu=new Menu();
        Dish d;
        String a ;//接受内容
        a = in.nextLine();
    //创建菜单
        while(!a.equals("end")) {
            if(a.charAt(0)!='t'){
                //菜谱
                String[] b = a.split(" ");
                if(b.length==2) {
                    d=new Dish(b[0],Integer.parseInt(b[1]));
                    menu.add(d);
                }
                else if(b.length==4) {
                    if((b[1].equals("川菜")||b[1].equals("晋菜")||
                            b[1].equals("浙菜"))&&b[3].equals("T")){
                        d=new Dish(b[0],Integer.parseInt(b[2]),b[1]);
                        menu.add(d);
                    }
                    else
                        System.out.println("wrong format");
                }
                else
                    System.out.println("wrong format");
            }
            else
                break;
            a=in.nextLine();
        }
    //订单,此时的a="table......"
        ArrayList<Table> tables = new ArrayList<>();
        ArrayList<Customer> clients = new ArrayList<>();
        while(!a.equals("end")) {
    //接受订单信息
            Boolean p=false;//p正则过
            String[] b = a.split(" ");
            if(b.length==7&&b[0].equals("table")&&b[2].equals
                    (":")&&b[3].length()<=10&&b[4].length()==11) {
                Boolean flag=true;
                if(new Order().account(b[5],b[6])==0) {
                    System.out.println("table "+b[1]+" out of "
                            + "opening hours");
                    flag=!flag;
                    p=!p;//p正
                }
                else {
//                    switch(b[4].substring(0, 3)) {
//                        case "180":
//                        case "181":
//                        case "189":
//                        case "133":
//                        case "135":
//                        case "136":
//                            break;
//                        default:
//                            System.out.println("wrong format");
//                            p=!p;//p正
//                            flag=!flag;
//                    }
                    if(flag) {
                //处理订单信息
                    //处理客户
                        Customer c = new Customer(b[3],b[4]);
                        if(clients.size()==0) {
                            clients.add(c);
                        }
                        else {
                            boolean t=true;//假则有此客户,真要创建客户
                            for(int i=0;i<clients.size()&&t;i++)
                                if(clients.get(i).name.equals(b[3])) {
                                    t=!t;
                                    c=clients.get(i);
                                }
                            if(t)
                                clients.add(c);
                        }
                    //处理桌子
                        Order o = new Order(menu);
                        o.account(b[5], b[6]);
                        Table t = new Table(Integer.parseInt(b[1]),o);
                        tables.add(t);
                        System.out.println("table "+b[1]+": ");
                        a=in.nextLine();
                        while(a.charAt(0)!='t'&&a.charAt(0)!='e') {
                            String[] m = a.split(" ");
                            if(m.length==2)
                                o.delARecordByOrderNum(Integer.parseInt(m[0]));
                            else if(m.length==4) {
                                int orderNum = Integer.parseInt(m[0]);
                                String dishName = m[1];
                                int portion = Integer.parseInt(m[2]);
                                int num = Integer.parseInt(m[3]);
                                //查找是否有此菜名
                                d = menu.searthDish(dishName);//接受菜品
                                if(d==null)//未找到,说明没有该菜品
                                    System.out.println(dishName+" does not exist");
                                else {//找到了,添加订单
                                    Record r = o.addARecord(orderNum, dishName, portion, num);
                                    System.out.println(orderNum+" "+dishName+" "+r.getPrice());
                                }
                            }
                            else if(m.length==6) {
                                //代点特色菜
                                int orderNum = Integer.parseInt(m[1]);
                                String dishName = m[2];
                                Dish dish = menu.searthDish(dishName);
                                int du = Integer.parseInt(m[3]);
                                int portion = Integer.parseInt(m[4]);
                                int num = Integer.parseInt(m[5]);
                                int ta = Integer.parseInt(m[0]);
                                //假设一定能找到这张桌子
                                boolean u=true;
                                for(int i=0;i<tables.size()&&u;i++) {
                                    if(ta==tables.get(i).table) {
                                        ta=i;
                                        u=!u;
                                    }
                                }
                                if(tables.get(ta).addTC(dish.type, du, num)) {
                                    //查找是否有此菜名
                                    d = menu.searthDish(dishName);//接受菜品
                                    if(d==null)//未找到,说明没有该菜品
                                        System.out.println(dishName+" does not exist");
                                    else {//找到了,添加订单
                                        Record r = o.addARecord(orderNum, dishName, portion, num);
                                        System.out.println(orderNum+" table "+t.table
                                                +" pay for table "+m[0]+" "+r.getPrice());
                                    }
                                }
                            }
                            else {
                                if(!canParseInt(m[1])){
                                    //特色菜
                                    int orderNum = Integer.parseInt(m[0]);
                                    String dishName = m[1];
                                    Dish dish = menu.searthDish(dishName);
                                    int du = Integer.parseInt(m[2]);
                                    int portion = Integer.parseInt(m[3]);
                                    int num = Integer.parseInt(m[4]);
                                    if(t.addTC(dish.type, du, num)) {
                                        //查找是否有此菜名
                                        d = menu.searthDish(dishName);//接受菜品
                                        if(d==null)//未找到,说明没有该菜品
                                            System.out.println(dishName+" does not exist");
                                        else {//找到了,添加订单
                                            Record r = o.addARecord(orderNum, dishName, portion, num);
                                            System.out.println(orderNum+" "+dishName+" "+r.getPrice());
                                        }
                                    }
                                }
                                else {
                                    //代点普通菜
                                    int orderNum = Integer.parseInt(m[1]);
                                    String dishName = m[2];
                                    int portion = Integer.parseInt(m[3]);
                                    int num = Integer.parseInt(m[4]);
                                    //查找是否有此菜名
                                    d = menu.searthDish(dishName);//接受菜品
                                    if(d==null)//未找到,说明没有该菜品
                                        System.out.println(dishName+" does not exist");
                                    else {//找到了,添加订单
                                        Record r = o.addARecord(orderNum, dishName, portion, num);
                                        System.out.println(orderNum+" table "+t.table
                                                +" pay for table "+m[0]+" "+r.getPrice());
                                    }
                                }
                            }
                            a=in.nextLine();
                        }
                        c.getTotalPrice(t);
                    }
                }
            }
            else {
                p=!p;//p正
                System.out.println("wrong format");
            }
            if(p) {
        //过过过,直至下一次的table出现或end
                a=in.nextLine();
                while(a.charAt(0)!='t'&&a.charAt(0)!='e') {
                    a=in.nextLine();
                }
            }
        }
        
        for(int i=0;i<tables.size();i++) 
        {
            String n = "table "+tables.get(i).table+": " +tables.get(i).order.getTotalPrice1()+
                    " "+tables.get(i).order.getTotalPrice2()+" ";
            int t=0;
            if(tables.get(i).tc[0][1]!=0) {
                int b=(int)(Math.round(1.0*tables.get(i).tc[0][0]/tables.get(i).tc[0][1]));
                n=n+"川菜 "+tables.get(i).tc[0][1];
                switch(b) {
                    case 0:
                        n=n+" 不辣";break;
                    case 1:
                        n=n+" 微辣";break;
                    case 2:
                        n=n+" 稍辣";break;
                    case 3:
                        n=n+" 辣";break;
                    case 4:
                        n=n+" 很辣";break;
                    case 5:
                        n=n+" 爆辣";break;
                }
                t++;
            }
            if(tables.get(i).tc[1][1]!=0) {
                int b=(int)(Math.round(1.0*tables.get(i).tc[1][0]/tables.get(i).tc[1][1]));
                if(t==0)
                    n=n+"晋菜 "+tables.get(i).tc[1][1];
                else
                    n=n+" 晋菜 "+tables.get(i).tc[1][1];
                switch(b) {
                    case 0:
                        n=n+" 不酸";break;
                    case 1:
                        n=n+" 微酸";break;
                    case 2:
                        n=n+" 稍酸";break;
                    case 3:
                        n=n+" 酸";break;
                    case 4:
                        n=n+" 很酸";break;
                }
                t++;
            }
            if(tables.get(i).tc[2][1]!=0) {
                int b=(int)(Math.round(1.0*tables.get(i).tc[2][0]/tables.get(i).tc[2][1]));
                if(t==0)
                    n=n+"浙菜 "+tables.get(i).tc[2][1];
                else
                    n=n+" 浙菜 "+tables.get(i).tc[2][1];
                switch(b) {
                    case 0:
                        n=n+" 不甜";break;
                    case 1:
                        n=n+" 微甜";break;
                    case 2:
                        n=n+" 稍甜";break;
                    case 3:
                        n=n+" 甜";break;
                }
            }
            //return a;
            System.out.println(n);
        }
        for(int i=0;i<clients.size()-1;i++) {
            for(int j=0;j<clients.size()-1-i;j++) {
                if(clients.get(j).compareTo(clients.get(j+1))>0) {
                    Customer c=clients.get(j);
                    clients.set(j, clients.get(j+1));
                    clients.set(j+1, c);
                }
            }
        }
        for(int i=0;i<clients.size();i++) 
            System.out.println(clients.get(i).toString());
        in.close();
    }
    static boolean canParseInt(String s)
    {
        for(int i=s.length();--i>=0;)
        {
            int ch = s.charAt(i);
            if(ch<48||ch>57)
                return false;
        }
        return true;
    }
}

//菜品类:对应菜谱上一道菜的信息。
class Dish {
    Boolean t=false;
    String type;
    String name;// 菜品名称
    int unit_price; // 单价
    
    Dish(String name,int price){
        this.name = name;
        this.unit_price = price;
    }
    Dish(String name,int price,String type){
        this(name,price);
        t=!t;
        this.type=type;
    }
    
    int getPrice(int portion){
// 计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
        float bl[]= {1,1.5f,2};
        return Math.round(unit_price*bl[portion-1]);
    }
}

//菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
class Menu {
    ArrayList<Dish> dishs = new ArrayList<Dish>();// 菜品数组,保存所有菜品信息
    public void add(Dish dish){
        //菜单加一道菜
        for(int i=0;i<dishs.size();i++) {
            if(dish.name.equals(dishs.get(i).name)) {
                //找到了相同菜名,就替换
                dishs.set(i, dish);
                return ;
            }
        }
        //未找到相同菜名,就增加
        dishs.add(dish);
    }
    Dish searthDish(String dishName){
        // 根据菜名在菜谱中查找菜品信息,返回Dish对象。
        for(int i=0;i<dishs.size();i++) {
            if(dishs.get(i).name.equals(dishName))
                return dishs.get(i);
        }
        return null;
    }
}

//点菜记录类:保存订单上的一道菜品记录
class Record {
    int orderNum;//序号
    Dish d;// 菜品
    int portion;// 份额(1/2/3代表小/中/大份)
    int num;//份数1,2,3,4,5
    public Record(int orderNum,Dish d,int portion,int num){
        this.orderNum=orderNum;
        this.d=d;
        this.portion=portion;
        this.num=num;
    }
    
    int getPrice(){
        // 计价,计算本条记录的价格
        return d.getPrice(portion)*num;
    }
}

//订单类:保存用户点的所有菜的信息。
class Order {
    ArrayList<Record> records = new ArrayList<Record>();// 保存订单上每一道的记录
    Menu menu;
    float acc;
    float acct=1;
    float account(String bi,String time) throws ParseException {
         //   double result;
           //将时间字符串转化成时间
            if(week(bi)>=1&&week(bi)<=5)
            {
            String begin = "17/00/00";
            String end = "20/30/00";
            String bgi = "10/30/00";
            String en = "14/30/00";
            if(time.equals(begin)||time.equals(end))
            {
                acct = 0.7f;
               acc = 0.8f;
            }
            if(time.equals(bgi)||time.equals(en))
            {
                this.acc = 0.6f;
               this.acct = 0.7f;
            }
            SimpleDateFormat df = new SimpleDateFormat("HH/mm/ss");
            try {
                //转换成时间格式
                Date beginTime = df.parse(begin);
                Date endTime = df.parse(end);
                Date Time = df.parse(time);
                Date b2 = df.parse(bgi);
                Date e2 = df.parse(en);
                //取出当前时间的时分秒编码再解码
                Date date = df.parse(df.format(new Date()));
                //通过日历形式开始比较
                Calendar c = Calendar.getInstance();
                c.setTime(Time);
                Calendar b = Calendar.getInstance();
                b.setTime(beginTime);
                Calendar e = Calendar.getInstance();
                e.setTime(endTime);
                Calendar bg = Calendar.getInstance();
                bg.setTime(b2);
                Calendar eg = Calendar.getInstance();
                eg.setTime(e2);
                //当前时间晚于开始时间,早于结束时间则表明在指定的时间段内
                if (c.after(b) && c.before(e)) 
                {
                    acct = 0.7f;
                    acc = 0.8f;
                  //  System.out.println("123");
                }
                if(c.after(bg)&&c.before(eg))
                {
                    this.acc = 0.7f;
                    this.acct = 0.6f;
                }
            } 
            catch (ParseException e1) 
            {
                e1.printStackTrace();
            }
            }
            else
            {
                String begin1 = "09/30/00";
                String end1 = "21/30/00";
                SimpleDateFormat df = new SimpleDateFormat("HH/mm/ss");
                if(time.equals(begin1)||time.equals(end1))
                {
                    this.acc = 1;
                    this.acct = 1;
                }
                try 
                {
                    Date beginTime1 = df.parse(begin1);
                    Date endTime1 = df.parse(end1);
                    Date Time = df.parse(time);
                    Date date = df.parse(df.format(new Date()));
                    //通过日历形式开始比较
                    Calendar c = Calendar.getInstance();
                    c.setTime(Time);
                    Calendar b = Calendar.getInstance();
                    b.setTime(beginTime1);
                    Calendar e = Calendar.getInstance();
                    e.setTime(endTime1);
                    if (c.after(b) && c.before(e)) 
                    {
                        this.acc = 1;
                        this.acct = 1;
                    }
                }
                catch (ParseException e1) 
                {
                    e1.printStackTrace();
                }
            }
            return acc;
         }
        int week(String m) throws ParseException
        {
    SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
    Calendar cal=Calendar.getInstance();
    Date date = format.parse(m);
    cal.setTime(date);
    int w=cal.get(Calendar.DAY_OF_WEEK)-1;
    if(w<=0)
        w=7;
    return w;
        }
    int getTotalPrice1() {
    // 计算订单的总价
        int total=0;
        if(records==null)
            return 0;
        for(int i=0;i<records.size();i++)
            total+=records.get(i).getPrice();
        return total;
    }
    int getTotalPrice2(){
    //计算订单打折后价格
        int totala=0;//特色菜
        int totalb=0;//
        if(records==null)
            return 0;
        for(int i=0;i<records.size();i++) {
            int price=records.get(i).getPrice();
            if(records.get(i).d.t)//若为特色菜
                totala+=Math.round(price*acct);
            else
                totalb+=Math.round(price*acc);
        }
        return totala+totalb;
    }
    
    public Order(Menu menu){
        this.menu = menu;
    }
    
    public Order() {
        
    }
    
    //根据菜名点菜
    Record addARecord(int orderNum,String dishName,int portion,int num) {
        //不用判断菜品是否存在,main里会判断,在这里一定会存在
        Record r = new Record(orderNum,menu.searthDish(dishName),portion,num);
        records.add(r);
        return r;
    }
    void delARecordByOrderNum(int orderNum){
        //根据序号删除一条记录
        for(int i=0;i<records.size();i++) {
            if(records.get(i).orderNum==orderNum) {
                records.remove(i);
                return ;//删除成功
            }
        }
        System.out.println("delete error;");//删除失败
    }
}

//桌子信息
class Table{
    int table;
    Order order;
    int[][] tc = new int[3][2];
    
    Table(int table,Order order) {
        this.order=order;
        this.table=table;
    }
    
    boolean addTC(String type,int du,int num){
        if(type.equals("川菜")) {
            if(du>=0&&du<=5) {
                tc[0][0]+=du*num;
                tc[0][1]+=num;
                return true;
            }
            else
                System.out.println("spicy num out of range :"+du);
        }
        else if(type.equals("晋菜")) {
            if(du>=0&&du<=4) {
                tc[1][0]+=du*num;
                tc[1][1]+=num;
                return true;
            }
            else
                System.out.println("acidity num out of range :"+du);
        }
        else if(type.equals("浙菜")) {
            if(du>=0&&du<=3) {
                tc[2][0]+=du*num;
                tc[2][1]+=num;
                return true;
            }
            else
                System.out.println("sweetness num out of range :"+du);
        }
        return false;
    }
 }
//客户信息
class Customer{
    String name;
    String tel;
    int price;
    
    Customer(String name,String tel){
        this.name=name;
        this.tel=tel;
    }
    int compareTo(Customer c) {
        return this.name.substring(0, 1).compareTo(c.name.substring(0, 1));
    }
    void getTotalPrice(Table table) {
        price+=table.order.getTotalPrice2();
    }
    @Override
    public String toString() {
        return name + " " + tel + " " + price;
    }
}

 

 

 

  期中考试

   7-1 测验1-圆类设计

 详情分析:难度较低,

题目要求创建一个圆形类(Circle),其中包含一个私有属性为圆的半径。需要从控制台输入圆的半径,并输出圆的面积。

可以按照以下步骤进行实现:

  1. 创建一个名为Circle的类,包含一个私有属性radius(半径)。
  2. 在Circle类中添加一个公有的构造方法,用于从控制台接收圆的半径作为参数,并将其赋值给radius属性。
  3. 在Circle类中添加一个公有的方法calculateArea(),用于计算圆的面积。
  4. 在calculateArea()方法中,使用Math.PI常量和半径radius计算圆的面积,并返回结果。
  5. 在主函数中,使用Scanner类从控制台接收圆的半径作为输入。
  6. 创建一个Circle对象,将输入的半径作为参数传递给构造方法。
  7. 调用Circle对象的calculateArea()方法,获取并输出圆的面积。

实现以上步骤后,就可以通过输入圆的半径来获取圆的面积了。

   7-2 测验2-类结构设计
详情分析:难度较低,

题目要求设计一个矩形类,该类的属性由矩形的左上角坐标点(x1,y1)和右下角坐标点(x2,y2)组成。需要计算并输出矩形的面积。

可以按照以下步骤进行实现:

  1. 创建一个名为Rectangle的类,包含四个私有属性x1、y1、x2、y2,分别表示矩形的左上角和右下角的坐标点。
  2. 在Rectangle类中添加一个公有的构造方法,用于从控制台接收矩形的坐标点作为参数,并将其赋值给相应的属性。
  3. 在Rectangle类中添加一个公有的方法calculateArea(),用于计算矩形的面积。
  4. 在calculateArea()方法中,根据矩形的左上角和右下角坐标点,计算矩形的宽度和高度,然后将宽度乘以高度得到矩形的面积。
  5. 在主函数中,使用Scanner类从控制台接收矩形的坐标点作为输入。
  6. 创建一个Rectangle对象,将输入的坐标点作为参数传递给构造方法。
  7. 调用Rectangle对象的calculateArea()方法,获取并输出矩形的面积。

实现以上步骤后,就可以通过输入矩形的坐标点来获取矩形的面积了。

   7-3 测验3-继承与多态

 详情分析:难度较低

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

   7-4 测验4-抽象类与接口

 详情分析:在测验3的题目基础上,重构类设计,实现列表内图形的排序功能(按照图形的面积进行排序)。
提示:题目中Shape类要实现Comparable接口。
三、踩坑心得
  1、处理数据时建议构造一个解析类,便于数据处理
  2、注意精度问题
四、主要困难以及改进建议

困难:

    对java中的一些便捷方法不够了解,不能快速选出合适的方法进行代码的简化,菜单计价程序题难以搞清各个类之间的关系,直接调用一些现成的类需要知道位于哪些包中。对String类中的构造方法掌握度提高后可以便利地对数据进行处理。

  对作业、实验的改进建议:

    1、建议每道菜单题都单独讲解一下

    2、在同一周有实验的基础上可以增加pta习题的时间

   菜单计价程序-3

改进:在订单类中创建一个ArrayList<Record> records = new ArrayList<Record>();// 保存订单上每一道的记录,在Main函数中创建ArrayList<Order> order = new ArrayList<Order>();保存每一份订单,同时将桌号存入订单中,对折扣处理部分独立构造方法计算折扣,并在Order类中创建新的方法计算折扣后总价;构造解析类,便于处理数据。

五、总结

1、类是描述某一对象的统称,对象是这个类的一个实例而已。有类之后就能根据这个类来产生具体的对象。一类对象所具备的共同属性和行为(方法)都在类中定义。
2、String的构造方法中
  boolean equals(Object obj):比较字符串的内容是否相同
  boolean startsWith(String str): 判断字符串对象是否以指定的str开头
  boolean endsWith(String str): 判断字符串对象是否以指定的str结尾

  char[] toCharArray():把字符串转换为字符数组

  String toLowerCase():把字符串转换为小写字符串
  String toUpperCase():把字符串转换为大写字符串

  去除字符串两端空格:String trim()
  按照指定符号分割字符串:String[] split(String str)
   int length():获取字符串的长度,其实也就是字符个数
   char charAt(int index):获取指定索引处的字符

 int indexOf(String str):获取str在字符串对象中第一次出现的索引
  String substring(int start):从start开始截取字符串
   String substring(int start,int end):从start开始,到end结束截取字符串。包括start,不包括end 
  char[] toCharArray():把字符串转换为字符数组

3、实现Comparable接口,重写compareTo方法。

 

 
 
 
posted @ 2023-06-28 20:54  Yukia360  阅读(8)  评论(0)    收藏  举报