BOOG-1作业

前言:第一次比较简单,知识点较少,第二次不会很难,需要对字符串进行分隔处理。第三次比较难,多了一个桌子,还有时间与折扣等,需要用到的东西也比较多,字符串的使用啊,时间类的使用等

读入

其实对于前三次作业,读入的基本处理套路都是类似的:

  • 读入字符串;
  • 根据字符串先判断是否为菜单或终止(对字符串进行辨析)
  • 读入点菜信息(包括增删改查等)
  • 终止点菜信息并计算最终的总价格

我们看待读入可以以这种视角:

  1. 判断首字符串是否为数字
  2. 判断字符串是否与指定字符相等
  3. 判断是否终止
  4. 判断菜品在菜单是否存在

这样我们就可以根据字符串的类别把菜单的菜品,单价,记录下来,然后在把菜品的订单序号,菜品名称,份额,以及删除信息等一一记录下来,在末尾输入结束字符使的得程序结束并计算最终的总价格,由于每次输入的字符串类型不同可以把这些内容很好的分隔开,达到点菜目的。

第三次是比较复杂的,他加入了桌子信息及时间,需要考虑桌子与菜单间关系且还可以给其他桌子点菜这需要把 两个桌子的加在一起,还需要根据时间确定点菜的优惠,然后点菜,计算 并且有多个桌子 ,需要进行多个循环,需要创建一个列表把桌子装入进去,最后分别输出每个桌子应付价格

第三次pta类图

 

 

为了简便运算和代码有以下方法及代码

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH/mm/ss");

Date date;

 

date= sdf.parse(time);

这个是用来解析输入的时间字符串的,可以把年月日 时分秒分隔出来因此获得优惠程度运用时间类简化时间解析

int getPrice(){
    if(portion==2)return (int) Math.round(1.5*d.unit_price)*quota;
    else if(portion==3)return 2*d.unit_price*quota;
    else return d.unit_price*quota;
}

点菜记录中的方法,用来计算一道菜的总价

int searchDish(String dishName,int count){
    for(int i=0;i<count;i++){
        if(dishName.equals(dishs[i].name)){
            return i;
        }
    }

return -1;
    }

菜谱中方法 可以判断是否存在此菜品,为价格计算菜品判断等提供便利

Dish addDish(String dishName,int unit_price){
    Dish newDish = new Dish();
    newDish.name = dishName;
    newDish.unit_price = unit_price;
    return newDish;
}

菜谱中方法 可以加入一道菜每次添加一个菜品都需要用到此方法

Record addARecord(int orderNum,String dishName,int portion,int quota,int count,Menu menu){
    Record newRecord = new Record();
    newRecord.orderNum = orderNum;
    newRecord.d=menu.dishs[menu.searchDish(dishName,count)];
    newRecord.portion = portion;
    newRecord.quota = quota;
    System.out.println(newRecord.orderNum + " "+newRecord.d.name +" "+newRecord.getPrice());
    return newRecord;
}

订单中方法可以添加一个点菜记录每点一道菜添加一次

boolean delARecordByOrderNum(int orderNum,int count){
    int i,j,flag2=0;
    for(i=0;i<count;i++){
        if(records[i].orderNum==orderNum){
            for(j=i;j<count-1;j++){
                records[j]=records[j+1];
            }
            flag2++;
        }
    }
    if(flag2==0){System.out.println("delete error;");return false;}
    return true;
}

订单中方法用来判断订单中是否有该序号的菜品,用来删除菜品

void od(Menu menu,int menu_count,String Str1,String Str2,int portion,int quota){
    if(Str2.equals("delete")){
        if(order.delARecordByOrderNum(Integer.parseInt(Str1),order_pd))
            order_pd--;
    }
    else {
        if(menu.searchDish(Str2,menu_count)!=-1){
            order.records[order_pd] = new Record();
            order.records[order_pd] = order.addARecord(Integer.parseInt(Str1),Str2,portion,quota,menu_count,menu);
            order_pd++;
        }
        else System.out.println(Str2+" does not exist");
    }
}

桌子中方法用来删除桌子中该道菜品

void getSum() {
    int sjday = time.getDayOfWeek().getValue();
    for(int i=0;i<order_pd;i++) {
        sum+=order. records[i].getPrice();
    }
    if(sjday>0&&sjday<6) {
        if(time.getHour()>=17&&time.getHour()<20)sum=Math.round(sum*0.8);
        if(time.getHour()==20) {
            if(time.getMinute()<=30)sum=Math.round(sum*0.8);
        }
        if(time.getHour()>=10&&time.getHour()<14)sum=Math.round(sum*0.6);
        if(time.getHour()==14) {
            if(time.getMinute()<=30)sum=Math.round(sum*0.6);
        }
    }
}

 

桌子中方法,可以用来计算该桌子价格优惠

boolean isOpen() {
    int sjday = time.getDayOfWeek().getValue();
    if(sjday>0&&sjday<6) {
        if(time.getHour()>=17&&time.getHour()<20)return true;
        if(time.getHour()==20) {
            if(time.getMinute()<=30)return true;
        }
        if(time.getHour()>10&&time.getHour()<14)return true;
        if(time.getHour()==10){
            if(time.getMinute()>=30)return true;
        }
        if(time.getHour()==14) {
            if(time.getMinute()<=30)return true;
        }
    }
    else {
        if(time.getHour()>9&&time.getHour()<21)return true;
        if(time.getHour()==9) {
            if(time.getMinute()>=30)return true;
        }
        if(time.getHour()==21) {
            if(time.getMinute()<=30)return true;
        }
    }
    return false;

}

桌子中方法用来判断桌子订单是否在营业范围内

类的使用及用途

1.菜品类:对应菜谱上一道菜的信息。Dish

static class Dish{
    String name;
    int unit_price;
}

可以存储菜品名字及单价

2.菜谱类:对应菜谱,包含饭店提供的所有菜的信息。Menu

static class Menu{
    Dish[] dishs = new Dish[30];
    int searchDish(String dishName,int count){
        for(int i=0;i<count;i++){
            if(dishName.equals(dishs[i].name)){
                return i;
            }
        }
        return -1;
    }
    Dish addDish(String dishName,int unit_price){
        Dish newDish = new Dish();
        newDish.name = dishName;
        newDish.unit_price = unit_price;
        return newDish;
    }
}

可以添加菜品及判断菜品是否存在

  1. 点菜记录类:保存订单上的一道菜品记录Record

static class Record{
    int orderNum;
    Dish d;
    int portion;
    int quota;
    int getPrice(){
        if(portion==2)return (int) Math.round(1.5*d.unit_price)*quota;
        else if(portion==3)return 2*d.unit_price*quota;
        else return d.unit_price*quota;
    }
}

有序号,份额,份数,及根据份额计算菜的总价

  1. 订单类:保存用户点的所有菜的信息。Order

static class Order{
    Record[] records = new Record[20];
    Record addARecord(int orderNum,String dishName11,int portion,int quota,int count1,Menu menu){
        Record newRecord = new Record();
        newRecord.orderNum = orderNum;
        newRecord.d=menu.dishs[menu.searchDish(dishName11,count1)];
        newRecord.portion = portion;
        newRecord.quota = quota;
        System.out.println(newRecord.orderNum + " "+newRecord.d.names +" "+newRecord.getPrice());
        return newRecord;
    }
    boolean delARecordByOrderNum(int orderNum,int count1){
        int i,j,flag2=0;
        for(i=0;i<count1;i++){
            if(records[i].orderNum==orderNum){
                for(j=i;j<count1-1;j++){
                    records[j]=records[j+1];
                }
                flag2++;
            }
        }
        if(flag2==0){System.out.println("delete error;");return false;}
        return true;
    }
}

保存点菜记录添加及查找点菜记录

  1. 桌子Table

static class Table {
    Order order = new Order();
    int order_pd=0;
    LocalDateTime times ;
    long sum=0;
    void od(Menu menu,int menu_count1,String Str2,String Str1,int portion,int quota){
        if(Str1.equals("delete")){
            if(order.delARecordByOrderNum(Integer.parseInt(Str2),order_pd))
                order_pd--;
        }
        else {
            if(menu.searchDish(Str1,menu_count1)!=-1){
                order.records[order_pd] = new Record();
                order.records[order_pd] = order.addARecord(Integer.parseInt(Str2),Str1,portion,quota,menu_count1,menu);
                order_pd++;
            }
            else System.out.println(Str1+" does not exist");
        }
    }
    void getSum() {
        int sjday = times.getDayOfWeek().getValue();
        for(int i=0;i<order_pd;i++) {
            sum+=order.records[i].getPrice();
        }
        if(sjday>0&&sjday<6) {
            if(times.getHour()>=17&&times.getHour()<20)sum=Math.round(sum*0.8);
            if(times.getHour()==20) {
                if(times.getMinute()<=30)sum=Math.round(sum*0.8);
            }
            if(times.getHour()>=10&&times.getHour()<14)sum=Math.round(sum*0.6);
            if(times.getHour()==14) {
                if(times.getMinute()<=30)sum=Math.round(sum*0.6);
            }
        }
    }
    boolean isOpen() {
        int sjday = times.getDayOfWeek().getValue();
        if(sjday>0&&sjday<6) {
            if(times.getHour()>=17&&times.getHour()<20)return true;
            if(times.getHour()==20) {
                if(times.getMinute()<=30)return true;
            }
            if(times.getHour()>10&&times.getHour()<14)return true;
            if(times.getHour()==10){
                if(times.getMinute()>=30)return true;
            }
            if(times.getHour()==14) {
                if(times.getMinute()<=30)return true;
            }
        }
        else {
            if(times.getHour()>9&&times.getHour()<21)return true;
            if(times.getHour()==9) {
                if(times.getMinute()>=30)return true;
            }
            if(times.getHour()==21) {
                if(times.getMinute()<=30)return true;
            }
        }
        return false;
    }
}

 

用来删除菜品,计算优惠,判断是否在营业范围内

优化与输出

第一次 :只需要记录菜品,判断是否存在菜品及计算总价格比较简单

第二次比第一次多了判断 菜品序号是否存在,比第一次添加了判断与删除功能;优化了计价规则的使用;对查找菜品的方法进行查找优化

第三次添加了一个桌子,桌子多了时间,并且可以帮别人点菜可以有多个订单,用判断 字符串类型方法记录点菜或删除等信息;对菜的优惠也利用时间类进行优化使其折扣计算更为突出明显,把优惠价格计算的更为清晰

测试

  1. 首先把 pta给出的代码运行测试
  2. 看到未得分点 找出一个与之相关的数据输入,然后根据得到的错误答案进行调试然后修改错误 代码

菜单1运行测试

麻婆豆腐 2

西红柿炒蛋 3

end

48

、、、、、、、、、、

麻婆豆腐 2

炒脆肚 2

西红柿炒蛋 3

end

炒脆肚 does not exist

48

、、、、、、、、、、

菜单2运行测试

麻婆豆腐 12

油淋生菜 9

1 麻婆豆腐 2 2

2 油淋生菜 1 3

end1 麻婆豆腐 36

2 油淋生菜 27

 

63

、、、、、、、、、、

麻婆豆腐 12

油淋生菜 9

1 麻婆豆腐 2 2

2 油淋生菜 1 3

3 麻辣鸡丝 1 2

1 delete

7 delete

end1 麻婆豆腐 36

2 油淋生菜 27

麻辣鸡丝 does not exist

delete error;

 

27

、、、、、、、、、、

1 麻婆豆腐 36

2 油淋生菜 27

麻辣鸡丝 does not exist

delete error;

delete error;

63

1 麻婆豆腐 36

2 油淋生菜 27 麻辣鸡丝 does not exist d

elete error;

delete error; 63

、、、、、、、、、、

菜单3运行测试

麻婆豆腐 12

油淋生菜 9

table 1 2023/3/22 17/0/0

1 麻婆豆腐 2 2

2 油淋生菜 1 3

1 delete

end

table 1:

1 麻婆豆腐 36

2 油淋生菜 27

table 1: 22

、、、、、、、、、、

麻婆豆腐 12

油淋生菜 9

table 1 2022/12/5 15/03/02

1 麻婆豆腐 2 2

2 油淋生菜 1 3

3 麻辣鸡丝 1 2

5 delete

7 delete

table 2 2022/12/3 15/03/02

1 麻婆豆腐 2 2

2 油淋生菜 1 3

3 麻辣鸡丝 1 2

7 delete

end

table 1:

1 麻婆豆腐 36

2 油淋生菜 27

麻辣鸡丝 does not exist

delete error;

delete error;

table 2:

1 麻婆豆腐 36

2 油淋生菜 27

麻辣鸡丝 does not exist

delete error;

table 1 out of opening hours

table 2: 63

、、、、、、、、、、

一些量化分析

结构中最复杂的代码在三个地方比较集中:优化、输入词法解析器和工厂中。这三个地方的复杂各有不同。
优化部分复杂的是因为,优化逻辑自己需要去抽象,这是一个面向过程的。我个人认为这个部分复杂不是什么坏事,最先开始考虑最模糊不清的地方,就需要拿出来单独优化,这样所有不好代码都被集中在一起维护,不会影响程序的其他部分。
词法解析这里复杂则完全是算法设计上的失误了。实际上前两次作业的时候,大量精力花在了去维护符号运算的方面,解析器这里写的却比较简单,这个类一开始就同时承担了模式匹配和将匹配到的子串转为表达式两个功能,直到第三次作业尝试扩展的时候才发现问题:这个设计并不能很好地拓展匹配带有嵌套的表达式。因此第三次作业在这里打了大量补丁,复杂程度骤增。索性没有导致太严重的问题
工厂这里写的很复杂是迫不得已,因为和优化一样,也是集所有混乱一身的一个类。除此之外,第三次作业因为写的有些放飞自我,很多本来应该写到优化器的优化直接写死在了工厂里面,也进一步使了这个类的复杂程度更严重。

总结

自己的Bug

有些数据得到的答案没有做到标准化,自己的答案与正确答案之间存在问题,无法解析一些错误的 输入,对错误输入的判断及解决还是有很多问题,有些代码过于冗长,没有合适的算法来使的自己的代码变得简便。对于字符串的分析及分隔还有待提高,而且不能熟练的使用字符串及时间的一些方法,对一些代码存在的问题无法解决,并且有一些代码的问题无法很快的找出,有时还会出现空指针异常,判断条件判断错误,循环计算错误单词拼写错误,遇到代码运行不一致,找了半天发现就是一个字母写错了。标点符号错误。英文符号写成中文,比如冒号(:和:)、引号(“”和"")、逗号(,和,)、分号(;和;),这些中文和英文它是不一样的等

别人的Bug

当运行该代码时,会抛出类型转换异常,因为字符串无法转换成整数,类型转换异常是当试图将一个对象强制转换成不兼容的类型时,会抛出类型转换异常,

数组越界异常是当试图访问一个数组中不存在的元素时,会抛出数组越界异常,字符串拼接异常是当试图访问一个字符串中不存在的字符时,会抛出字符串拼接异常,当运行该代码时,会出现死循环,因为循环计数器在每次循环中递减而不是递增。

展望

  首先,我个人认为java是一门比较复杂的语言,大量的专属名词让人目接不暇,又因为java是一门面向对象的语言,这就与c语言有着本质区别,在对java学习的过程中,一定要边写边学,不要只学但是不写代码,我们主要要培养我们自己的动手能力,而不是培养我们的刷课能力(dog),在java学习中我们一定要有动手,也可以背诵记忆,他有很多的类库,能大大减少我们的思维量和代码长度,还有近几年IT行业前途迷茫,我们只有更卷才能有更大希望,所以以后也要更加努力

posted @ 2023-05-20 22:02  beish  阅读(30)  评论(0)    收藏  举报