shift

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、前言

  • 跟之前相比,这几次题目集的难度很明显上升很多,尤其是菜单迭代的题目,简直是令人绝望,也让我再一次感受到了不下功夫学是难以取得好结果的,很多东西都需要慢慢摸索
  1. 第四次题目集题量大,但总体难度中上,2-7题主要考察了字符串相关的方法以及对象数组的使用,第1题就是我们第一次接触大名鼎鼎的菜单题,十分难做
  2. 第五次题目集前四题都考察了正则表达式的使用,不算太难,但是弄清楚正则表达式的条件也废了一点功夫,后面两题就是日期的聚合,难度大
  3. 第六次题目集只有一道题,菜单题的第四次迭代,但难度极大

二、设计与分析

挑选个别题目进行分析

  • 第四次题目集

7-1 菜单计价程序-3

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。

Dish {

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }

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

Menu {

Dish\[\] dishs ;//菜品数组,保存所有菜品信息

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

Dish addDish(String dishName,int unit_price)//添加一道菜品信息

}

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

Record {

int orderNum;//序号\\

Dish d;//菜品\\

int portion;//份额(1/2/3代表小/中/大份)\\

int getPrice()//计价,计算本条记录的价格\\

}

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

Order {

Record\[\] records;//保存订单上每一道的记录

int getTotalPrice()//计算订单的总价

Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。

delARecordByOrderNum(int orderNum)//根据序号删除一条记录

findRecordByNum(int orderNum)//根据序号查找一条记录

}

### 输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

### 输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+”:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+“:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

  • 思路:首先我们可以看到这个题目真的很长,当时我看了一下之后觉得短时间内很难写出来,就去做后面的题目了,这道题直到作业截止的时候也没能做出来,我忏悔。因此菜单四也是理所当然的做不出来,所以又返回来看了看这道题,尝试着做了一下。事实上这道题的难度也是相当的大,不仅要考虑订单时间的判断,还要输入菜品的信息,订单信息的增删改等等等等,难以下手。最后是使用了循环了进行输入,并且逐条处理输入的信息,下面放出正确代码

源码如下:

  1 import java.util.*;
  2 public class Main {
  3     public static void main(String[] args) {
  4         Scanner input = new Scanner(System.in);
  5         Menu menu = new Menu();
  6         Table[] tables = new Table[10];
  7         int dishAmount;
  8         int orderAmount;
  9         Dish dish;
 10         int tableAmount = 0;
 11         int count;
 12         String[] temp;
 13         int a1,a2,a3,a4,a5;
 14         while (true) {
 15             String string = input.nextLine();
 16             temp = string.split(" ");
 17             if(string.equals("end"))
 18                 break;
 19             count = temp.length;
 20             if (count == 2) {
 21                 if (temp[1].equals("delete")) {
 22                         a1 = Integer.parseInt(temp[0]);
 23                         if (tablemes[tableAmount].order.delARecordByOrderNum(a1) == 0) {
 24                             System.out.println("delete error;");
 25                         } else {
 26                                 int c = tablemes[tableAmount].order.delARecordByOrderNum(a1);
 27                                 tablemes[tableAmount].order.sum -= c;
 28                         }
 29                 } else{
 30                     a2 = Integer.parseInt(temp[1]);
 31                     menu.dishs[dishAmount] = menu.addDish(temp[0], a2);
 32                     dishAmount++;
 33                 }
 34             }
 35             else if (count == 4) {
 36                 if (temp[0].equals("table")){
 37                     tableAmount++;
 38                     orderAmount = 0;
 39                     tablemes[tableAmount] = new Table(temp[1], temp[2], temp[3]);
 40                     tablemes[tableAmount].processTime();
 41                     tablemes[tableAmount].setDiscount();
 42                     System.out.println("table " + temp[1] + ": ");
 43                 } else {
 44                         a3 = Integer.parseInt(temp[0]);
 45                         a4 = Integer.parseInt(temp[2]);
 46                         a5 = Integer.parseInt(temp[3]);
 47                         tablemes[tableAmount].order.addARecord(a3, temp[1],a4 , a5);
 48                         dish = menu.searthDish(temp[1]);
 49                         if(dish==null){
 50                             System.out.println(temp[1]+" does not exist");
 51                         }
 52                         if (dish != null) {
 53                             tablemes[tableAmount].order.records[orderAmount].d = dish;
 54                             int a = tablemes[tableAmount].order.records[orderAmount].getPrice();
 55                             System.out.println(tablemes[tableAmount].order.records[orderAmount].orderNum + " " + dish.name + " " + a);
 56                             tablemes[tableAmount].order.sum += a;
 57                         }
 58                         orderAmount++;
 59                 }
 60             }
 61             else if (count == 5){
 62                 a1 = Integer.parseInt(temp[1]);
 63                 a2 = Integer.parseInt(temp[3]);
 64                 a3 = Integer.parseInt(temp[4]);
 65                 tablemes[tableAmount].order.addARecord(a1, temp[2], a2, a3);
 66                 dish = menu.searthDish(temp[2]);
 67                 if(dish==null){
 68                     System.out.println(temp[2]+" does not exist");
 69                 }
 70                 if (dish != null){
 71                     tablemes[tableAmount].order.records[orderAmount].d = dish;
 72                     int b = tablemes[tableAmount].order.records[orderAmount].getPrice();
 73                     System.out.println(temp[1] + " table " + tablemes[tableAmount].tableNum + " pay for table " + temp[0] + " " + b);
 74                     tablemes[tableAmount].order.sum += b;
 75                 }
 76                 orderAmount++;
 77             }
 78         }
 79         for(int i = 1; i < tableAmount + 1; i++){
 80             if(tablemes[i].getDiscount()>0){
 81                 System.out.println("table " + tablemes[i].tableNum + ": "+Math.round(tablemes[i].order.getTotalPrice()*tablemes[i].getDiscount()));
 82             }
 83             else System.out.println("table " + tablemes[i].tableNum + " out of opening hours");
 84         }
 85     }
 86 }
 87 class Dish {
 88     String name;
 89     int unit_price;
 90     int getPrice(int portion) {
 91         if (portion == 1) return unit_price;
 92         else if (portion == 2) return Math.round((float) (unit_price * 1.5));
 93         else return 2*unit_price;
 94     }
 95 }
 96 class Menu {
 97     Dish[] dishs = new Dish[10];
 98     int dishCount = 0;
 99     Dish searthDish(String dishName){
100         for(int i=dishCount-1;i>=0;i--){
101             if(dishName.equals(dishs[i].name)){
102                 return dishs[i];
103             }
104         }
105         return null;
106     }
107     Dish addDish(String dishName,int unit_price){
108         Dish dish = new Dish();
109         dish.name = dishName;
110         dish.unit_price = unit_price;
111         dishCount++;
112         return dish;
113     }
114 }
115 class Record {
116     int orderNum;
117     Dish d = new Dish();
118     int num = 0;
119     int portion;
120     int getPrice(){
121         return d.getPrice(portion)*num;
122     }
123 }
124 class Order {
125     Record[] records = new Record[10];
126     int count = 0;
127 
128     int sum;
129     void addARecord(int orderNum,String dishName,int portion,int num){
130         records[count] = new Record();
131         records[count].d.name = dishName;
132         records[count].orderNum = orderNum;
133         records[count].portion = portion;
134         records[count].num = num;
135         count++;
136     }
137     int getTotalPrice(){
138         return sum;
139     }
140     int delARecordByOrderNum(int orderNum){
141         if(orderNum>count||orderNum<=0){
142             return 0;
143         }else {
144             return records[orderNum - 1].getPrice();
145         }
146     }
147     Record findRecordByNum(int orderNum) {
148         for (int i = count - 1; i >= 0; i--) {
149             if (orderNum == records[i].orderNum) {
150                 return records[i];
151             }
152         }
153         return null;
154     }
155 }
156 class Table {
157     int tableNum;
158     String Date;
159     String tableTime;
160     public Table() {
161     }
162 
163     public Table(String tableNum, String date, String tableTime) {
164         this.tableNum = Integer.parseInt(tableNum);
165         Date = date;
166         this.tableTime = tableTime;
167     }
168     int year,month,day,week,hh,mm,ss;
169     Order order = new Order();
170     float discount = -1;
171     void processTime(){
172         String[] temp1 = Date.split("/");
173         String[] temp2 = tableTime.split("/");
174 
175         year = Integer.parseInt(temp1[0]);
176         month = Integer.parseInt(temp1[1]);
177         day = Integer.parseInt(temp1[2]);
178 
179         Calendar date = Calendar.getInstance();
180         date.set(year, (month-1), day);
181         week = date.get(Calendar.DAY_OF_WEEK);
182         if(week==1)
183             week = 7;
184         else
185             week--;
186         hh = Integer.parseInt(temp2[0]);
187         mm = Integer.parseInt(temp2[1]);
188         ss = Integer.parseInt(temp2[2]);
189 
190     }
191     void setDiscount(){
192         if(week>=1&&week<=5)
193         {
194             if(hh>=17&&hh<20)
195                 discount =0.8F;
196             else if(hh==20&&mm<30)
197                 discount =0.8F;
198             else if(hh==20&&mm==30&&ss==0)
199                 discount =0.8F;
200             else if(hh>=11&&hh<=13||hh==10&&mm>=30)
201                 discount =0.6F;
202             else if(hh==14&&mm<30)
203                 discount =0.6F;
204             else if(hh==14&&mm==30&&ss==0)
205                 discount =0.6F;
206         }
207         else
208         {
209             if(hh>=10&&hh<=20)
210                 discount = 1.0F;
211             else if(hh==9&&mm>=30)
212                 discount = 1.0F;
213             else if(hh==21&&mm<30||hh==21&&mm==30&&ss==0)
214                 discount = 1.0F;
215         }
216     }
217     float getDiscount(){
218         return discount;
219     }
220 }
View Code

 

 

7-2 有重复的数据

在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。

你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES”这三个字母;如果没有,则输出“NO”。

  • 思路:一开始觉得这个题目似曾相识,本来是用双重循环来做这个题目,在eclipse里面完全没问题,但是在pta上就说运行超时,行吧,那我们换个方法。查阅资料之后发现用hashset方法可以直接简单轻松地做出来,也为后面的题目打下了基础

源码如下:

import java.util.*;
public class Main { 
    public static void main(String[] args) { 
        Scanner input = new Scanner(System.in); 
        int n = input.nextInt(); 
        Set<Integer> set = new HashSet<>(); 
        for (int i = 0; i < n; i++) 
        { 
            int num = input.nextInt();
            if (set.contains(num)) 
            { 
                System.out.println("YES"); 
                return; 
            } 
            set.add(num); 
        } 
        System.out.println("NO"); 
    } 
}

 

7-4 单词统计与排序

从键盘录入一段英文文本(句子之间的标点符号只包括“,”或“.”,单词之间、单词与标点之间都以" "分割。

要求:按照每个单词的长度由高到低输出各个单词(重复单词只输出一次),如果单词长度相同,则按照单词的首字母顺序(不区分大小写,首字母相同的比较第二个字母,以此类推)升序输出。

输入格式:

一段英文文本。

输出格式:

按照题目要求输出的各个单词(每个单词一行)。

  • 思路:这道题一开始卡了我很久,别的还好,主要是按照长度从高到低排序,同时还要判断长度相同时字母的先后顺序有点麻烦。后面用replace方法把输入语句中的 "," 和 "." 去掉之后,将得到的字符串按不同的单词分开存储为一个数组,再使用hashset和arraylist的方法做了出来

源码如下:

import java.util.*;

public class Main{
  public static void main(String[] args) {
      Scanner input = new Scanner(System.in);
      String a = input.nextLine();
      String b = a.replace(",", "");
      String f = b.replace(".", "");
      String c[] = f.split(" ");

        Set<String> d = new HashSet<>(Arrays.asList(c));  
        List<String> e = new ArrayList<>(d);
        Collections.sort(e, new Comparator<String>() {  
            public int compare(String s1, String s2) {
                if (s1.length() != s2.length()) {
                    return s2.length() - s1.length();  
                } else {
                    return s1.compareToIgnoreCase(s2);  
                }
            }
        });

        for (String word : e) {
            System.out.println(word);
        }
    }
}

 

7-5 面向对象编程(封装性) 

Student类具体要求如下:
私有成员变量:学号(sid,String类型),姓名(name,String类型),年龄(age,int类型),专业(major,String类型) 。
提供无参构造和有参构造方法。(注意:有参构造方法中需要对年龄大小进行判定)
普通成员方法:print(),输出格式为“学号:6020203100,姓名:王宝强,年龄:21,专业:计算机科学与技术”。
普通成员方法:提供setXxx和getXxx方法。(注意:setAge()方法中需要对年龄进行判定)
注意:
年龄age不大于0,则不进行赋值。
print()中的“:”和“,”为均为中文冒号和逗号。

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //调用无参构造方法,并通过setter方法进行设值
        String sid1 = sc.next();
        String name1 = sc.next();
        int age1 = sc.nextInt();
        String major1 = sc.next();
        Student student1 = new Student();
        student1.setSid(sid1);
        student1.setName(name1);
        student1.setAge(age1);
        student1.setMajor(major1);
        //调用有参构造方法
        String sid2 = sc.next();
        String name2 = sc.next();
        int age2 = sc.nextInt();
        String major2 = sc.next();
        Student student2 = new Student(sid2, name2, age2, major2);
        //对学生student1和学生student2进行输出
        student1.print();
        student2.print();
    }
}

/* 请在这里填写答案 */

输入格式:

输出格式:

学号:6020203110,姓名:王宝强,年龄:21,专业:计算机科学与技术
学号:6020203119,姓名:张三丰,年龄:23,专业:软件工程

输入样例:

在这里给出一组输入。例如:

6020203110 王宝强 21 计算机科学与技术
6020203119 张三丰 23 软件工程

输出样例:

在这里给出相应的输出。例如:

学号:6020203110,姓名:王宝强,年龄:21,专业:计算机科学与技术
学号:6020203119,姓名:张三丰,年龄:23,专业:软件工程
  • 思路:就是创建对象数组,根据给出的代码可以较快做出

源码如下:

import java.util.*;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //调用无参构造方法,并通过setter方法进行设值
        String sid1 = sc.next();
        String name1 = sc.next();
        int age1 = sc.nextInt();
        String major1 = sc.next();
        Student student1 = new Student();
        student1.setSid(sid1);
        student1.setName(name1);
        student1.setAge(age1);
        student1.setMajor(major1);
        //调用有参构造方法
        String sid2 = sc.next();
        String name2 = sc.next();
        int age2 = sc.nextInt();
        String major2 = sc.next();
        Student student2 = new Student(sid2, name2, age2, major2);
        //对学生student1和学生student2进行输出
        student1.print();
        student2.print();
    }
}

class Student{
    private String sid;
    private String name;
    private int age;
    private String major;
    Student(){
        
    }
    Student(String sid,String name,int age,String major){
        
        this.sid = sid;
        this.name = name;
            if(age < 0)
        {
            System.exit(0);
        }
        this.age = age;
        this.major = major;
    
    }
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        if(age < 0)
        {
            System.exit(0);
        }
        this.age = age;
    }
    public String getMajor() {
        return major;
    }
    public void setMajor(String major) {
        this.major = major;
    }
    public void print() {
        System.out.println("学号:"+getSid()+","+"姓名:"+this.name+","+"年龄:"+this.age+","+"专业:"+this.major);
    }
}

 

7-7 判断两个日期的先后,计算间隔天数、周数

从键盘输入两个日期,格式如:2022-06-18。判断两个日期的先后,并输出它们之间间隔的天数、周数(不足一周按0计算)。

预备知识:通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。

输入格式:

输入两行,每行输入一个日期,日期格式如:2022-06-18

输出格式:

第一行输出:第一个日期比第二个日期更早(晚)
第二行输出:两个日期间隔XX天
第三行输出:两个日期间隔XX周

  • 思路:还是熟悉的日期,但是这次是为了让我们熟悉java中自带的日期和时间类及他们的方法的使用,难度不大。就是要用split方法把输入的日期分开然后一个个进行判断就好了

源码如下:

import java.util.Scanner;
import java.time.LocalDate;
import java.time.*; 
import java.time.temporal.ChronoUnit;
import java.time.temporal.*;
import java.time.format.DateTimeFormatter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;
public class Main
{
    public static void main(String[] args)
    {
        int flag=0;
       Scanner scan =new Scanner(System.in);
       String a= scan.nextLine();
       String b= scan.nextLine();
       String []s1=a.split("-");
       String []s2=b.split("-");
       int year1=Integer.parseInt(s1[0], 10);
       int month1=Integer.parseInt(s1[1], 10);
       int day1=Integer.parseInt(s1[2], 10);
       int year2=Integer.parseInt(s2[0], 10);
       int month2=Integer.parseInt(s2[1], 10);
       int day2=Integer.parseInt(s2[2], 10);
       LocalDate l1=LocalDate.of(year1,month1,day1);
       LocalDate l2=LocalDate.of(year2,month2,day2);
       boolean status = l1.isAfter(l2);
       if(status)
       {
           
           System.out.println("第一个日期比第二个日期更晚");
       }
       else
       {
           flag=1;
           System.out.println("第一个日期比第二个日期更早");
       }
      
       long days = l1.until(l2, ChronoUnit.DAYS);
       long weeks=days/7;
        if(flag==1)
        {
            System.out.println("两个日期间隔"+days+"天");
            System.out.println("两个日期间隔"+weeks+"周");
        }
       else
       {
           days=days*-1;
           weeks=weeks*-1;
           System.out.println("两个日期间隔"+days+"天");
            System.out.println("两个日期间隔"+weeks+"周");
       }
       
    }
  • 第五次题目集

7-1 正则表达式训练-QQ号校验

校验键盘输入的 QQ 号是否合格,判定合格的条件如下:

    • 要求必须是 5-15 位;
    • 0 不能开头;
    • 必须都是数字;

输入格式:

在一行中输入一个字符串。

输出格式:

    • 如果合格,输出:“你输入的QQ号验证成功”;
    • 否则,输出:“你输入的QQ号验证失败”。
  • 思路:就是让我们学会如何使用正则表达式,难度不大

源码如下:

import java.util.Scanner;
public class Main{ 
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String a = input.nextLine();
        if(a.matches("^[1-9][0-9]{4,14}$"))
        {
            System.out.print("你输入的QQ号验证成功");
        }
        else
        {
            System.out.print("你输入的QQ号验证失败");
        }
 
    }
}

 

7-5 日期问题面向对象设计(聚合一)

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

类图.jpg

应用程序共测试三个功能:

 

  • 思路:做这道题需要先看清楚题目要求,而且需要搞清类与类之间的关系,根据题目里给出的类图来写代码。其实核心逻辑和第四次题目集的7-7相差不大,只是不能用日期类的方法,需要自己写,但是需要使用聚合,事实上这里的代码我没有使用聚合,只有关联关系,在7-6里才做出了改进

源码如下(太长了折叠一下):

  1 import java.util.Scanner;
  2 
  3 public class Main {
  4     public static void main(String[] args) {
  5         Scanner input = new Scanner(System.in);
  6         int year = 0;
  7         int month = 0;
  8         int day = 0;
  9 
 10         int choice = input.nextInt();
 11 
 12         if (choice == 1) { // test getNextNDays method
 13             int m = 0;
 14             year = Integer.parseInt(input.next());
 15             month = Integer.parseInt(input.next());
 16             day = Integer.parseInt(input.next());
 17 
 18             DateUtil date = new DateUtil(day, month, year);
 19 
 20             if (!date.checkInputValidity()) {
 21                 System.out.println("Wrong Format");
 22                 System.exit(0);
 23             }
 24 
 25             m = input.nextInt();
 26 
 27             if (m < 0) {
 28                 System.out.println("Wrong Format");
 29                 System.exit(0);
 30             }
 31 
 32             System.out.println(date.getNextNDays(m).showDate());
 33         } else if (choice == 2) { // test getPreviousNDays method
 34             int n = 0;
 35             year = Integer.parseInt(input.next());
 36             month = Integer.parseInt(input.next());
 37             day = Integer.parseInt(input.next());
 38 
 39             DateUtil date = new DateUtil(day, month, year);
 40 
 41             if (!date.checkInputValidity()) {
 42                 System.out.println("Wrong Format");
 43                 System.exit(0);
 44             }
 45 
 46             n = input.nextInt();
 47 
 48             if (n < 0) {
 49                 System.out.println("Wrong Format");
 50                 System.exit(0);
 51             }
 52 
 53             System.out.println(date.getPreviousNDays(n).showDate());
 54         } else if (choice == 3) {    //test getDaysofDates method
 55             year = Integer.parseInt(input.next());
 56             month = Integer.parseInt(input.next());
 57             day = Integer.parseInt(input.next());
 58 
 59             int anotherYear = Integer.parseInt(input.next());
 60             int anotherMonth = Integer.parseInt(input.next());
 61             int anotherDay = Integer.parseInt(input.next());
 62 
 63             DateUtil fromDate = new DateUtil(day, month, year);
 64             DateUtil toDate = new DateUtil(anotherDay, anotherMonth, anotherYear);
 65 
 66             if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
 67                 System.out.println(fromDate.getDaysofDates(toDate));
 68             } else {
 69                 System.out.println("Wrong Format");
 70                 System.exit(0);
 71             }
 72         }
 73         else{
 74             System.out.println("Wrong Format");
 75             System.exit(0);
 76         }
 77     }
 78 }
 79 class DateUtil {
 80     private Day day = new Day();
 81 
 82     DateUtil() {
 83 
 84     }
 85 
 86     DateUtil(int d, int m, int y) {
 87         day.setValue(d);
 88         day.getMonth().setValue(m);
 89         day.getMonth().getYear().setValue(y);
 90     }
 91 
 92     Day getDay() {
 93         return day;
 94     }
 95 
 96     void setDay(Day d) {
 97         day = d;
 98     }
 99 
100     public boolean checkInputValidity() {
101         if (day.getMonth().getYear().validate()) {
102             if (day.getMonth().validate()) {
103                 if (day.validate()) {
104                     return true;
105                 } else return false;
106             } else return false;
107         } else return false;
108     }
109 
110     public DateUtil getNextNDays(int m) {
111         int i;
112         long sum = 0;
113         long sum1 = 0;
114         long sum2 = 0;
115         long sum3 = 0;
116         long sum4 = 0;
117         long n = (long) m;
118         DateUtil date1 = new DateUtil();
119         if (day.getMonth().getYear().isLeapYear()) {
120             day.mon_maxnum[1] = 29;
121             for (i = 0; i < day.getMonth().getValue() - 1; i++) {
122                 sum1 += day.mon_maxnum[i];
123             }
124             sum = sum1 + day.getValue();
125             i = 0;
126             if (sum + n <= 366) {
127                 while (sum2 + day.mon_maxnum[i] < sum + n) {
128                     sum2 += day.mon_maxnum[i];
129                     i++;
130                 }
131                 date1.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
132                 date1.day.getMonth().setValue(i + 1);
133                 date1.day.setValue((int) (sum + n - sum2));
134             } else {
135                 while (sum4 < sum + n) {
136                     if (day.getMonth().getYear().isLeapYear()) {
137                         sum3 += 366;
138                         day.getMonth().getYear().yearIncrement();
139                         if (day.getMonth().getYear().isLeapYear()) {
140                             sum4 = sum3 + 366;
141                         } else sum4 = sum3 + 365;
142                         day.getMonth().getYear().yearReduction();
143                     } else {
144                         sum3 += 365;
145                         day.getMonth().getYear().yearIncrement();
146                         if (day.getMonth().getYear().isLeapYear()) {
147                             sum4 = sum3 + 366;
148                         } else sum4 = sum3 + 365;
149                         day.getMonth().getYear().yearReduction();
150                     }
151                     day.getMonth().getYear().yearIncrement();
152                 }
153                 i = 0;
154                 sum2 = 0;
155                 if (day.getMonth().getYear().isLeapYear()) day.mon_maxnum[2] = 29;
156                 else day.mon_maxnum[2] = 28;
157                 while ((sum2 + day.mon_maxnum[i]) < (sum + n - sum3)) {
158                     sum2 += day.mon_maxnum[i];
159                     i++;
160                 }
161                 date1.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
162                 date1.day.getMonth().setValue(i + 1);
163                 date1.day.setValue((int) (sum + n - sum3 - sum2));
164             }
165         } else {
166             for (i = 0; i < day.getMonth().getValue() - 1; i++) {
167                 sum1 += day.mon_maxnum[i];
168             }
169             sum = sum1 + day.getValue();
170             i = 0;
171             if (sum + n <= 365) {
172                 while (sum2 + day.mon_maxnum[i] < sum + n) {
173                     sum2 += day.mon_maxnum[i];
174                     i++;
175                 }
176                 date1.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
177                 date1.day.getMonth().setValue(i + 1);
178                 date1.day.setValue((int) (sum + n - sum2));
179             } else {
180                 while (sum4 < sum + n) {
181                     if (day.getMonth().getYear().isLeapYear()) {
182                         sum3 += 366;
183                         day.getMonth().getYear().yearIncrement();
184                         if (day.getMonth().getYear().isLeapYear()) {
185                             sum4 = sum3 + 366;
186                         } else sum4 = sum3 + 365;
187                         day.getMonth().getYear().yearReduction();
188                     } else {
189                         sum3 += 365;
190                         day.getMonth().getYear().yearIncrement();
191                         if (day.getMonth().getYear().isLeapYear()) {
192                             sum4 = sum3 + 366;
193                         } else sum4 = sum3 + 365;
194                         day.getMonth().getYear().yearReduction();
195                     }
196                     day.getMonth().getYear().yearIncrement();
197                 }
198                 i = 0;
199                 sum2 = 0;
200                 if (day.getMonth().getYear().isLeapYear()) day.mon_maxnum[1] = 29;
201                 else day.mon_maxnum[1] = 28;
202                 while ((sum2 + day.mon_maxnum[i]) < (sum + n - sum3)) {
203                     sum2 += day.mon_maxnum[i];
204                     i++;
205                 }
206                 date1.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
207                 date1.day.getMonth().setValue(i + 1);
208                 date1.day.setValue((int) (sum + n - sum3 - sum2));
209             }
210         }
211         return date1;
212     }
213 
214     public DateUtil getPreviousNDays(int m) {
215         int i;
216         long sum = 0;
217         long sum1 = 0;
218         long sum2 = 0;
219         long sum3 = 0;
220         long n = (long) m;
221         DateUtil date2 = new DateUtil();
222         if (day.getMonth().getYear().isLeapYear())
223             day.mon_maxnum[1] = 29;
224         else day.mon_maxnum[1] = 28;
225             for (i = 0; i < day.getMonth().getValue() - 1; i++) {
226                 sum1 += day.mon_maxnum[i];
227             }
228             sum = sum1 + day.getValue();
229             i = 0;
230             if (n < sum) {
231                 while ((sum2 + day.mon_maxnum[i]) < (sum - n)) {
232                     sum2 += day.mon_maxnum[i];
233                     i++;
234                 }
235                 date2.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
236                 date2.day.getMonth().setValue(i + 1);
237                 date2.day.setValue((int) (sum - n - sum2));
238             }
239             else {
240                 while (sum3 <= (n - sum)) {
241                     day.getMonth().getYear().yearReduction();
242                     if (day.getMonth().getYear().isLeapYear()) sum3 += 366;
243                     else sum3 += 365;
244                 }
245                 i = 0;
246                 sum2 = 0;
247                 if (day.getMonth().getYear().isLeapYear()) day.mon_maxnum[1] = 29;
248                 else day.mon_maxnum[1] = 28;
249                 while ((sum2 + day.mon_maxnum[i]) < (sum3 - n + sum)) {
250                     sum2 += day.mon_maxnum[i];
251                     i++;
252                 }
253                 date2.day.getMonth().getYear().setValue(day.getMonth().getYear().getValue());
254                 date2.day.getMonth().setValue(i + 1);
255                 date2.day.setValue((int) (sum3 - n + sum - sum2));
256             }
257             return date2;
258         }
259 
260     public int getDaysofDates(DateUtil date) {
261         int i, j, k;
262         int sum0 = 0;
263         int sum = 0;
264         int sum1 = 0;
265         int sum2 = 0;
266         int sum3 = 0;
267         int sum4 = 0;
268         if (day.getMonth().getYear().isLeapYear())
269             day.mon_maxnum[1] = 29;
270         else day.mon_maxnum[1]=28;
271             for (i = 0; i < day.getMonth().getValue() - 1; i++) {
272                 sum1 += day.mon_maxnum[i];
273             }
274             sum0 = sum1 + day.getValue();
275             if (date.getDay().getMonth().getYear().isLeapYear()) date.getDay().mon_maxnum[1] = 29;
276             else date.getDay().mon_maxnum[1] = 28;
277             for (j = 0; j < date.getDay().getMonth().getValue() - 1; j++) {
278                 sum2 += date.getDay().mon_maxnum[j];
279             }
280             sum = sum2 + date.getDay().getValue();
281             if (equalTwoDates(date)) return 0;
282             else {
283                 Day day1 = new Day();
284                 if (compareDates(date)) {
285                     if (day.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()) return (sum - sum0);
286                     else {
287                         for (k = (day.getMonth().getYear().getValue() + 1); k < date.getDay().getMonth().getYear().getValue(); k++) {
288                             day1.getMonth().getYear().setValue(k);
289                             if (day1.getMonth().getYear().isLeapYear()) sum3 += 366;
290                             else sum3 += 365;
291                         }
292                         if (day.getMonth().getYear().isLeapYear()) return (sum3 + 366 - sum0 + sum);
293                         else return (sum3 + 365 - sum0 + sum);
294                     }
295                 } else {
296                     if (day.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()) return (sum0 - sum);
297                     else {
298                         for (k = (date.getDay().getMonth().getYear().getValue() + 1); k < day.getMonth().getYear().getValue(); k++) {
299                             day1.getMonth().getYear().setValue(k);
300                             if (day1.getMonth().getYear().isLeapYear()) sum4 += 366;
301                             else sum4 += 365;
302                         }
303                         if (date.getDay().getMonth().getYear().isLeapYear()) return (sum4 + 366 - sum + sum0);
304                         else return (sum4 + 365 - sum + sum0);
305                     }
306                 }
307             }
308         }
309 
310      public boolean compareDates(DateUtil date){
311             if(day.getMonth().getYear().getValue()<date.getDay().getMonth().getYear().getValue()) return true;
312             else if(day.getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue()){
313                 if(day.getMonth().getValue()<date.getDay().getMonth().getValue()) return true;
314                 else if(day.getMonth().getValue()==date.getDay().getMonth().getValue()){
315                     if(day.getValue()<date.getDay().getValue()) return true;
316                     return false;
317                 }
318                 return false;
319             }
320             return false;
321         }
322         public boolean equalTwoDates(DateUtil date){
323             if(day.getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue()&&day.getMonth().getValue()==date.getDay().getMonth().getValue()&&day.getValue()==date.getDay().getValue()) return true;
324             else return false;
325         }
326 
327             public String showDate () {
328                 String s = day.getMonth().getYear().getValue() + "-" + day.getMonth().getValue() + "-" + day.getValue();
329                 return s;
330             }
331 }
332 class Day{
333     private int value;
334     private Month month = new Month();
335     int[] mon_maxnum={31,28,31,30,31,30,31,31,30,31,30,31};
336     Day(){
337 
338     }
339 
340     Day(int yearValue,int monthValue,int dayValue){
341         month.setValue(monthValue);
342         month.getYear().setValue(yearValue);
343     }
344 
345     int getValue(){
346         return value;
347     }
348 
349     void setValue(int value){
350         this.value=value;
351     }
352 
353     Month getMonth(){
354         return month;
355     }
356 
357     void setMonth(Month value){
358         month=value;
359     }
360 
361     void resetMin(){
362         value=1;
363     }
364 
365     void resetMax(){
366         if(month.getYear().isLeapYear()){
367             mon_maxnum[1]=29;
368         }
369         value=mon_maxnum[value-1];
370     }
371 
372     boolean validate(){
373         if(month.getYear().isLeapYear()){
374             mon_maxnum[1]=29;
375         }
376         if(value>=1&&value<=mon_maxnum[month.getValue()-1]){
377             return true;
378         }
379         else return false;
380     }
381 
382     void dayIncrement(){
383         value+=1;
384     }
385 
386     void dayReduction(){
387         value-=1;
388     }
389 }
390 
391 class Month{
392     private int value;
393     private Year year = new Year();
394 
395     Month(){
396 
397     }
398 
399     Month(int yearValue,int monthValue){
400         value = monthValue;
401         year.setValue(yearValue);
402     }
403 
404     int getValue(){
405         return value;
406     }
407 
408     void setValue(int value){
409         this.value=value;
410     }
411 
412     Year getYear(){
413         return year;
414     }
415 
416     void setYear(Year year){
417         this.year=year;
418     }
419 
420     void resetMin(){
421         value=1;
422     }
423 
424     void resetMax(){
425         value=12;
426     }
427 
428     boolean validate(){
429         if(value>=1&&value<=12){
430             return true;
431         }
432         else return false;
433     }
434 
435     void monthIncrement(){
436         value+=1;
437     }
438 
439     void monthReduction(){
440         value-=1;
441     }
442 }
443 
444 class Year{
445     private int value;
446 
447     Year(){
448 
449     }
450 
451     Year(int value){
452         this.value=value;
453     }
454 
455     int getValue(){
456         return value;
457     }
458 
459     void setValue(int value){
460         this.value=value;
461     }
462 
463     boolean isLeapYear(){
464         if((value%4==0&&value%100!=0)||(value%400==0)){
465             return true;
466         }
467         else return false;
468     }
469 
470     boolean validate(){
471         if(value>=1900&&value<=2050){
472             return true;
473         }
474         else return false;
475     }
476 
477     void yearIncrement(){
478         value+=1;
479     }
480 
481     void yearReduction(){
482         value-=1;
483     }
484 }
7-5 日期问题面向对象设计(聚合一)
View Code

 

7-6 日期问题面向对象设计(聚合二)

参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

类图.jpg

应用程序共测试三个功能:

  • 思路:和第五题大差不差,首先更改了时间的范围,然后改进了输出的格式,类图看起来也更加清晰简洁,需要我们在第五题的基础上进行不小的改进,但是有了第五题的基础,相对来说想要做出来并不算太难。

源码如下:

import java.util.*;
public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;
        int choice = input.nextInt();
        if (choice == 1) { // test getNextNDays method
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            m = input.nextInt();

            if (m < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.print(date.showDate() + " next " + m + " days is:");
            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { // test getPreviousNDays method
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
            DateUtil date = new DateUtil(year, month, day);
            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            n = input.nextInt();
            if (n < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            System.out.print(date.showDate() + " previous " + n + " days is:");
            System.out.println(date.getPreviousNDays(n).showDate());
        } else if (choice == 3) { // test getDaysofDates method
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());
            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
                System.out.println("The days between " + fromDate.showDate() + " and " + toDate.showDate() + " are:"
                        + fromDate.getDaysofDates(toDate));
            } else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        } else {
            System.out.println("Wrong Format");
            System.exit(0);
        }

    }
}
class DateUtil {
    Year year;
    Month month;
    Day day;
    int mon_maxnum[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    public DateUtil(){
        
    }
    public DateUtil(int y, int m, int d){
        this.day = new Day(d);
        this.month = new Month(m);
        this.year = new Year(y);
    }
    public Year getYear() {
        return year;
    }
    public void setYear(Year year) {
        this.year = year;
    }
    public Month getMonth() {
        return month;
    }
    public void setMonth(Month month) {
        this.month = month;
    }
    public Day getDay() {
        return day;
    }
    public void setDay(Day day) {
        this.day = day;
    }
    public void setDayMin() {
        this.day.value=1;
    }
    public void setDatMax() {
        if(this.year.isLeapYear())
            mon_maxnum[1]++;
        this.day.value=mon_maxnum[this.month.value-1];
    }
    
    public boolean checkInputValidity(){//检测输入的年、月、日是否合法
        if(this.year.isLeapYear())
            mon_maxnum[1]++;
        if(this.year.validate()&&this.month.validate()&&this.day.value>=1&&this.day.value<=mon_maxnum[this.month.value-1]) 
            return true;
        return false;
    }
    
    public boolean compareDates(DateUtil date){//比较当前日期与date的大小(先后)
        if (date.year.value<this.year.value)
            return false;
        
        else if (date.year.value==this.year.value
                &&date.month.value<this.month.value) 
            return false;
        
        if (date.year.value==this.year.value
                &&date.month.value==this.month.value
                &&date.day.value<this.day.value) 
            return false;
        
        return true;
    }
    
    public boolean equalTwoDates(DateUtil date){//判断两个日期是否相等
        if (this.getDay().getValue()==date.getDay().getValue() 
                && this.getYear().getValue()==date.getYear().getValue() 
                && this.getMonth().getValue()==date.getMonth().getValue()) 
            return true;
        
        return false;
    }
    
    public String showDate(){//以“year-month-day”格式返回日期值
        return this.getYear().getValue()+"-"+this.getMonth().getValue()+"-"+this.getDay().getValue();
    
    }
    
    public DateUtil getNextNDays(int n){//取得year-month-day的下n天日期
        int arr[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
        int year=0, month=0, day=0;
        int rest = restday(this);
        if (rest>n) {//本年
            year=this.getYear().getValue();
            int mday = arr[this.getMonth().getValue()];
            if (this.getYear().isLeapYear()&&this.getMonth().getValue()==2) {
                mday++;
            }
            mday-=this.getDay().getValue();//本月剩余的日期
            if (mday>=n) {    //本月
                month = this.getMonth().getValue();
                day = n+this.getDay().getValue();
            }
            else{    //其他月
                n-=mday;
                month = this.getMonth().getValue()+1;
                int k = month;
                while(n-arr[k]>0&&k<=12){
                    n -= arr[k];
                    month++;
                    k++;
                }
                day = n;
            }
        }
        else {
            n-=rest;
            year = this.getYear().getValue()+1;
            int y = 365;
            if (new Year(year).isLeapYear()) {
                y++;
            }
            while(n-y>0){
                n-=y;
                year++;
                y=365;
                if (new Year(year).isLeapYear())
                    y++;
            }
            int k = 1;
            while(n-arr[k]>0&&k<=12){
                n -= arr[k];
                k++;
            }
            month = k;
            day = n;
        }
        
//        System.out.println(this.showDate()+" next "+n+" days is:"+year+"-"+month+"-"+day);
        
        return new DateUtil(year, month, day);
    }
    
    public int restday(DateUtil d) {
        int n = 0;
        int arr[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
        for (int i = d.getMonth().getValue()+1; i <=12; i++) {
            n+=arr[i];
        }
        n+=arr[d.getMonth().getValue()]-d.getDay().getValue();
        if(d.getYear().isLeapYear()&&d.getMonth().getValue()<=2)
            n++;
        return n;
    }
    
    public DateUtil getPreviousNDays(int n){//取得year-month-day的前n天日期
        int arr[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
        int year=0, month=0, day=0;
        int rest = 365-restday(this);
        if (this.getYear().isLeapYear()) {
            rest++;
        }
        if (rest>n) {//本年
            year=this.getYear().getValue();
            int mday=this.getDay().getValue();//本月剩余的日期
            if (mday>n) {    //本月
                month = this.getMonth().getValue();
                day = mday-n;
            }
            else{    //其他月
                n-=mday;
                month = this.getMonth().getValue()-1;
                if (month==0) {
                    month = 12;
                    year=this.getYear().getValue()-1;
                }
                int k = month;
                while(n-arr[k]>0&&k>=0){
                    n -= arr[k];
                    month--;
                    k--;
                }
                day = arr[k]-n;
                if (new Year(year).isLeapYear()&&month==2) {
                    day++;
                }
            }
        }
        else {
            n-=rest;
            year = this.getYear().getValue()-1;
            int y = 365;
            if (new Year(year).isLeapYear()) {
                y++;
            }
            while(n-y>0){
                n-=y;
                year--;
                y=365;
                if (new Year(year).isLeapYear())
                    y++;
            }
            int k = 12;
            while(n-arr[k]>0&&k>=0){
                n -= arr[k];
                k--;
            }
            month = k;
            day = arr[k]-n;
            if (new Year(year).isLeapYear()&&month==2) {
                day++;
            }
        }
//        System.out.println(this.showDate()+" previous "+n+" days is:"+year+"-"+month+"-"+day);
        return new DateUtil(year, month, day);
    }
    
    
    public int getDaysofDates(DateUtil date){//求当前日期与date之间相差的天数
        DateUtil pred = this;
        DateUtil nextd = date;
        if (this.equalTwoDates(date)) {
            return 0;
        }
        else if (!this.compareDates(date)) {
            pred = date;
            nextd = this;
        }
        int arr[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
        int i,j,d = 0;
        for(i=pred.getYear().getValue()+1;i<nextd.getYear().getValue();i++) {
            d=d+365;
            if(new Year(i).isLeapYear()) 
                d++;
        }
        if (pred.getYear().getValue()!=nextd.getYear().getValue()) {
            for(j=pred.getMonth().getValue()+1;j<=12;j++) 
                d=d+arr[j];
            d+=arr[pred.getMonth().getValue()]-pred.getDay().getValue();
            for(j=1;j<nextd.getMonth().getValue();j++)
                d+=arr[j];
            d+=nextd.getDay().getValue();
            if(pred.getYear().isLeapYear()&&pred.getMonth().getValue()<=2)
                d++;
            if (nextd.getYear().isLeapYear()&&nextd.getMonth().getValue()>2) {
                d++;
            }
        }
        else if(pred.getYear().getValue()==nextd.getYear().getValue()&&pred.getMonth().getValue()!=nextd.getMonth().getValue()){
            for(j=pred.getMonth().getValue()+1;j<=nextd.getMonth().getValue()-1;j++)
                d+=arr[j];
            d+=arr[pred.getMonth().getValue()]-pred.getDay().getValue();
            d+=nextd.getDay().getValue();
            if(pred.getYear().isLeapYear()&&pred.getMonth().getValue()<=2)
                d++;
        }
        else if(pred.getYear().getValue()==nextd.getYear().getValue()&&pred.getMonth().getValue()==nextd.getMonth().getValue()){
            d=nextd.getDay().getValue()-pred.getDay().getValue();
        }
        return d;
    }
    

}
class Day{
    int value;
    public Day() {
        
    }
    public Day(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
    public void dayIncrement() {
        value++;
    }
    public void dayReduction() {
        value--;
    }
}
class Month{
    int value;
    public Month() {
        
    }
    public Month(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
    public void resetMin() {
        value=1;
    }
    public void resetMax() {
        value=12;
    }
    public boolean validate() {
        if(1<=this.value&&12>=this.value)
            return true;
        return false;
    }
    public void monthIncrement() {
        value++;
    }
    public void monthReduction() {
        value--;
    }
}
class Year{
    int value;
    public Year() {
        
    }
    public Year(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
    public boolean isLeapYear(){//判断year是否为闰年
        boolean y1 = value%4 == 0;
        boolean y2 = value%100 != 0;
        boolean y3 = value%400 == 0;
        
        if((y1&&y2)||y3)
            return true;
        else 
            return false;
    }
    public boolean validate() {
        if(this.value<=2020&&this.value>=1820)
            return true;
        return false;
    }
    public void yearIncrement() {
        value++;
    }
    public void yearReduction() {
        value--;
    }
}

 

 

  • 第六次题目集

7-1 菜单计价程序-4

本体大部分内容与菜单计价程序-3相同,增加的部分用加粗文字进行了标注。

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的桌号从小到大的顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

参考以下类的模板进行设计(本内容与计价程序之前相同,其他类根据需要自行定义):

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

Dish {

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }

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

Menu {

Dish[] dishs ;//菜品数组,保存所有菜品信息

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

Dish addDish(String dishName,int unit_price)//添加一道菜品信息

}

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

Record {

int orderNum;//序号

Dish d;//菜品\\

int portion;//份额(1/2/3代表小/中/大份)

int getPrice()//计价,计算本条记录的价格

}

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

Order {

Record[] records;//保存订单上每一道的记录

int getTotalPrice()//计算订单的总价

Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。

delARecordByOrderNum(int orderNum)//根据序号删除一条记录

findRecordByNum(int orderNum)//根据序号查找一条记录

}

本次课题比菜单计价系列-3增加的异常情况:

1、菜谱信息与订单信息混合,应忽略夹在订单信息中的菜谱信息。输出:"invalid dish"

2、桌号所带时间格式合法(格式见输入格式部分说明,其中年必须是4位数字,月、日、时、分、秒可以是1位或2位数),数据非法,比如:2023/15/16 ,输出桌号+" date error"

3、同一桌菜名、份额相同的点菜记录要合并成一条进行计算,否则可能会出现四舍五入的误差。

4、重复删除,重复的删除记录输出"deduplication :"+序号。

5、代点菜时,桌号不存在,输出"Table number :"+被点菜桌号+" does not exist";本次作业不考虑两桌记录时间不匹配的情况。

6、菜谱信息中出现重复的菜品名,以最后一条记录为准。

7、如果有重复的桌号信息,如果两条信息的时间不在同一时间段,(时段的认定:周一到周五的中午或晚上是同一时段,或者周末时间间隔1小时(不含一小时整,精确到秒)以内算统一时段),此时输出结果按不同的记录分别计价。

8、重复的桌号信息如果两条信息的时间在同一时间段,此时输出结果时合并点菜记录统一计价。前提:两个的桌号信息的时间都在有效时间段以内。计算每一桌总价要先合并符合本条件的饭桌的点菜记录,统一计价输出。

9、份额超出范围(1、2、3)输出:序号+" portion out of range "+份额,份额不能超过1位,否则为非法格式,参照第13条输出。

10、份数超出范围,每桌不超过15份,超出范围输出:序号+" num out of range "+份数。份数必须为数值,最高位不能为0,否则按非法格式参照第16条输出。

11、桌号超出范围[1,55]。输出:桌号 +" table num out of range",桌号必须为1位或多位数值,最高位不能为0,否则按非法格式参照第16条输出。

12、菜谱信息中菜价超出范围(区间(0,300)),输出:菜品名+" price out of range "+价格,菜价必须为数值,最高位不能为0,否则按非法格式参照第16条输出。

13、时间输入有效但超出范围[2022.1.1-2023.12.31],输出:"not a valid time period"

14、一条点菜记录中若格式正确,但数据出现问题,如:菜名不存在、份额超出范围、份数超出范围,按记录中从左到右的次序优先级由高到低,输出时只提示优先级最高的那个错误。

15、每桌的点菜记录的序号必须按从小到大的顺序排列(可以不连续,也可以不从1开始),未按序排列序号的输出:"record serial number sequence error"。当前记录忽略。(代点菜信息的序号除外)

16、所有记录其它非法格式输入,统一输出"wrong format"

17、如果记录以“table”开头,对应记录的格式或者数据不符合桌号的要求,那一桌下面定义的所有信息无论正确或错误均忽略,不做处理。如果记录不是以“table”开头,比如“tab le 55 2023/3/2 12/00/00”,该条记录认为是错误记录,后面所有的信息并入上一桌一起计算。

本次作业比菜单计价系列-3增加的功能:

菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+基础价格+"T"

例如:麻婆豆腐 9 T

菜价的计算方法:

周一至周五 7折, 周末全价。

注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价:

计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。

最后将所有记录的菜价累加得到整桌菜的价格。

输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+”:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“** does not exist”,**是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价

  • 思路:该来的总是要来的,菜单四终于还是来了。在经历过整整一个星期的折磨之后,我还是没能做出来这道题,作业截止之后,我寻求了做出来的同学的帮助,好像懂了些什么,又好像什么都没懂。这道题彻底摧毁了我的侥幸心理,让我发现前面的所谓难题只不过是开胃小菜,这还是老师降低难度后的题,就已经让我抓耳挠腮,难以想象后面的题目难度会有多大,但是我能知道的就是始终要认真学习不同的方法,锻炼逻辑思维,理清类与类之间的关系。这里我会放出修改过后的代码

源码如下:

import java.util.Scanner;
import java.util.regex.Pattern;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.regex.Matcher;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Menu menu = new Menu();
        Order order = new Order();
        Table table = new Table();
        for (int i = 0; i < table.order.length; i++) {
            table.order[i] = new Order();
            for (int i1 = 0; i1 < order.records.length; i1++) {
                table.order[i].records[i1] = new Record();
                table.order[i].s[i1] = new SpecialDish();
            }
        }
        for (int i = 0; i < menu.dishes.length; i++) {
            menu.dishes[i] = new Dish();
            menu.dishes[i].name = " ";
        }
        int invalidFlag = 0, tablei = 0;
        int tableFlag = 0;
        int orderFlag1 = 0, orderFlag2 = 0;
        int j = 0; //j用来看订单的序号
        int stringFlag = 0;
        int combineFlag = 0; //判断是否要合并桌
        while (true) {
            String signal = sc.nextLine();
            if (signal.equals("end")) {
                break;
            }
            String str[] = signal.split(" ");
            //菜单的输入和删除序号
            if (str.length == 2 || str.length == 3) {


                //菜单的输入
                if (str.length == 3) {
                    if (!str[2].equals("T")) {
                        System.out.println("wrong format");
                        continue;
                    }
                    if (invalidFlag != 0) {
                        System.out.println("invalid dish");
                        continue;
                    }
                    if (!isInteger(str[1])) {
                        System.out.println("wrong format");
                        continue;
                    }
                    if (Integer.parseInt(str[1]) > 300) {
                        System.out.println(str[0] + " price out of range 400");
                        continue;
                    }
                    menu.addSpecial(true);
                }
                if (str[0].length() != 1) {

                    if (!isInteger(str[1])) {
                        Pattern pattern = Pattern.compile("^table.*");
                        Matcher matcher = pattern.matcher(signal);
                        System.out.println("wrong format");
                        stringFlag = 1;
                        continue;
                    }
                    if (invalidFlag != 0) {
                        System.out.println("invalid dish");
                        continue;
                    }
                    if (Integer.parseInt(str[1]) >= 300) {
                        System.out.println(str[0] + " price out of range 400");
                        continue;
                    }
                    if (str[1].charAt(0) == '0') {
                        System.out.println("wrong format");
                        continue;
                    }
                    menu.addDish(str[0], Integer.parseInt(str[1]));
                }

                //删除
                else {
                    if (tablei - 1 < 0) {
                        continue;
                    }
                    if (menu.findSpecial(str[0], table.order[tablei - 1])) {
                        SpecialDish s1 = table.order[tablei - 1].findSpecialDish(Integer.parseInt(str[0]));
                        table.order[tablei - 1].pretendDelRecordByOrderNum(Integer.parseInt(str[0]), s1);
                    } else {
                        table.order[tablei - 1].delARecordByOrderNum(Integer.parseInt(str[0]));
                    }

                }
            }

            //订单的输入或者桌号的输入
            else if (str.length == 4 || str.length == 5) {

                //订单的输入
                if (isInteger(str[0])) {
                    if (stringFlag == 1) {
                        continue;
                    }
                    //代点菜
                    if (str.length == 5) {
                        if (!isInteger(str[0])) {
                            System.out.println("wrong format");
                        }
                        //代点菜存在
                        if (menu.searchDish(str[2]) != null) {
                            if (tableFlag == 1) {
                                j = 0;
                                tableFlag = 0;
                            }
                            if (table.num[tablei - 1] != Integer.parseInt(str[0]) && table.ifExistTableNum(Integer.parseInt(str[0]))) {
                                if (Integer.parseInt(str[3]) > 3) {
                                    if (Integer.parseInt(str[3]) > 9) {
                                        System.out.println("wrong format");
                                    } else {
                                        System.out.println(str[0] + " portion out of range " + str[3]);
                                    }
                                    continue;
                                }
                                if (Integer.parseInt(str[4]) > 15) {
                                    System.out.println(str[0] + " num out of range " + str[3]);
                                    continue;
                                }
                                if (menu.searchSpecial(str[2])) {
                                    if (tablei - 1 > -1) {
                                        table.order[tablei - 1].s[j].addDish(menu, str[2], str[3], str[4]);
                                        table.order[tablei - 1].s[j].num = Integer.parseInt(str[1]);
                                        System.out.println(str[1] + " table " + table.num[tablei - 1] + " pay for table " + str[0] + " " + Math.round(Integer.parseInt(str[4]) * menu.searchDish(str[2]).getPrice(Integer.parseInt(str[3]))));
                                        j++;
                                        table.order[tablei - 1].records[j].d = menu.searchDish(str[2]);
                                        table.order[tablei - 1].addARecord(Integer.parseInt(str[1]), str[2], Integer.parseInt(str[3]), Integer.parseInt(str[4]));
                                        table.order[tablei - 1].pretendToDelete(Integer.parseInt(str[1]));
                                    }
                                } else {
                                    System.out.println(str[1] + " table " + table.num[tablei - 1] + " pay for table " + str[0] + " " + Math.round(Integer.parseInt(str[4]) * menu.searchDish(str[2]).getPrice(Integer.parseInt(str[3]))));
                                    table.order[tablei - 1].records[j].d = menu.searchDish(str[2]);
                                    j++;
                                    table.order[tablei - 1].addARecord(Integer.parseInt(str[1]), str[2], Integer.parseInt(str[3]), Integer.parseInt(str[4]));
                                }
                            } else {
                                System.out.println("Table number :" + str[0] + " does not exist");
                            }
                        }

                        //代点菜不存在
                        else {
                            System.out.println(str[2] + " does not exist");
                            continue;
                        }
                    }

                    //给自己点菜
                    else if (str.length == 4) {
                        if (stringFlag == 1) {
                            continue;
                        }
                        //点的菜在菜单上存在
                        if (menu.searchDish(str[1]) != null) {
                            char ch1 = str[2].charAt(0);
                            char ch2 = str[3].charAt(0);
                            char ch3 = str[0].charAt(0);
                            if (ch1 == '0' || ch2 == '0' || ch3 == '0') {
                                System.out.println("wrong format");
                                continue;
                            }
                            if (Integer.parseInt(str[2]) > 3) {
                                if (Integer.parseInt(str[2]) > 9) {
                                    System.out.println("wrong format");
                                } else {
                                    System.out.println(str[0] + " portion out of range " + str[2]);
                                }
                                continue;
                            }
                            if (Integer.parseInt(str[3]) > 15) {
                                System.out.println(str[0] + " num out of range " + str[3]);
                                continue;
                            }
                            orderFlag2 = Integer.parseInt(str[0]);
                            if (orderFlag2 - orderFlag1 <= 0) {
                                System.out.println("record serial number sequence error");
                                continue;
                            }
                            orderFlag1 = Integer.parseInt(str[0]);


                            //当前是特殊菜
                            if (menu.searchSpecial(str[1])) {
                                if (tableFlag == 1) {
                                    j = 0;
                                    tableFlag = 0;
                                }
                                if (tablei - 1 > -1) {
                                    table.order[tablei - 1].s[j].addDish(menu, str[1], str[2], str[3]);
                                    table.order[tablei - 1].s[j].num = Integer.parseInt(str[0]);
                                    System.out.println(str[0] + " " + str[1] + " " + table.order[tablei - 1].s[j].searchPrice(str[1]));
                                    j++;
                                    table.order[tablei - 1].records[j].d = menu.searchDish(str[1]);
                                    table.order[tablei - 1].addARecord(Integer.parseInt(str[0]), str[1], Integer.parseInt(str[2]), Integer.parseInt(str[3]));
                                    table.order[tablei - 1].pretendToDelete(Integer.parseInt(str[0]));
                                }
                            } else {
                                if (tableFlag == 1) {
                                    j = 0;
                                    tableFlag = 0;
                                }
                                if (tablei - 1 > -1) {
                                    table.order[tablei - 1].records[j].d = menu.searchDish(str[1]);
                                    table.order[tablei - 1].addARecord(Integer.parseInt(str[0]), str[1], Integer.parseInt(str[2]), Integer.parseInt(str[3]));
                                    System.out.println(str[0] + " " + str[1] + " " + table.order[tablei - 1].records[j].getPrice());
                                }
                                j++;
                            }
                        }

                        //点的菜在菜单上不存在
                        else {
                            System.out.println(str[1] + " does not exist");      //记录错误菜品名
                            continue;
                        }
                    }
                }

                //输入桌号
                else {

                    if (str[0].equals("table")) {
                        if (str.length != 4) {
                            System.out.println("wrong format");
                            stringFlag = 1;
                            continue;
                        }
                        if (!isInteger(str[1])) {
                            System.out.println("wrong format");
                            stringFlag = 1;
                            continue;
                        }
                        if (!table.ifLegal(signal, str[1])) {
                            if (str[1].equals("")) {
                                System.out.println("wrong format");
                                stringFlag = 1;
                                continue;
                            }
                            if (Integer.parseInt(str[1]) > 55 || Integer.parseInt(str[1]) < 1) {
                                System.out.println(str[1] + " table num out of range");
                                stringFlag = 1;
                                continue;
                            }
                            System.out.println("wrong format");
                            stringFlag = 1;
                            continue;
                        }
                        table.num[tablei] = Integer.parseInt(str[1]);
                        table.date[tablei] = str[2];
                        table.time[tablei] = str[3];
                        table.order[tablei].workFlag = 0;
                        if (!table.isValidDate(tablei)) {
                            System.out.println(str[1] + " date error");
                            stringFlag = 1;
                            continue;
                        }
                        if (!table.judgeIfOutYear(tablei)) {
                            System.out.println("not a valid time period");
                            stringFlag = 1;
                            continue;
                        }
                        if (!table.judgeDiscount(tablei)) {
                            System.out.println("wrong format");
                            stringFlag = 1;
                            continue;
                        }
                        if (table.order[tablei].workFlag != 0) {
                            System.out.println("table " + table.num[tablei] + " out of opening hours");
                            stringFlag = 1;
                            continue;
                        }
                        stringFlag = 0;
                        table.specialDiscount(tablei);
                        invalidFlag = 1;
                        orderFlag1 = 0;
                        if (table.ifSameTime(tablei)) {
                            combineFlag = 1;
                        }
                        System.out.println("table " + table.num[tablei] + ": ");
                        tablei++;
                        tableFlag = 1;
                    } else {
                        System.out.println("wrong format");
                    }
                }
            } else {
                System.out.println("wrong format");
                stringFlag = 1;
                continue;
            }
        }
        for (int i = 0; i < tablei; i++) {
            System.out.print("table " + table.num[i] + ": ");
            int sum1 = table.order[i].getTotalPrice();
            int sum2 = table.order[i].getTotalSpecialPrice();
            int flag = 0;
            int s_1 = 0, s_2 = 0;
            for (int i1 = i + 1; combineFlag == 1 && i1 < tablei; i1++) {
                if (table.num[i] == table.num[i1]) {
                    flag = 1;
                    s_1 = table.order[i1].getTotalPrice();
                    s_2 = table.order[i1].getTotalSpecialPrice();
                }
            }
            if (flag == 1) {
                System.out.print(sum1 + sum2 + s_1 + s_2 + " ");
            } else {
                System.out.print(sum1 + sum2 + " ");
            }
            int sum3 = Math.round(sum1);
            int flag1 = 0;
            for (int i1 = i + 1; combineFlag == 1 && i1 < tablei; i1++) {
                if (table.num[i] == table.num[i1]) {
                    int s_3 = Math.round(s_1);
                    System.out.println(Math.round(sum3 * table.order[i].discount + s_3 * table.order[i1].discount) + Math.round(sum2 * table.order[i].specialDiscount + s_2 * table.order[i1].specialDiscount));
                    tablei--;
                    flag1 = 1;
                }
            }
            if (flag1 == 1) {
                continue;
            }
            System.out.println(Math.round(sum3 * table.order[i].discount) + Math.round(sum2 * table.order[i].specialDiscount));
        }
    }

    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }
}





class SpecialDish {
    Dish d[] = new Dish[100];
    int length = 0;
    int totalSpecialPrice = 0;
    int num = 0;

    public void addDish(Menu m, String dishName, String portion, String count) {
        d[length] = new Dish();
        d[length].name = dishName;
        d[length].unit_price = m.searchDish(dishName).getPrice(Integer.parseInt(portion)) * Integer.parseInt(count);
        length++;
    }

    public int searchPrice(String dishName) {
        for (int i = 0; i < d.length; i++) {
            if (d[i].name.equals(dishName)) {
                return d[i].unit_price;
            }
        }
        return 0;
    }

    public int getSpecialPrice() {
        for (int i = 0; d[i] != null; i++) {
            totalSpecialPrice += d[i].unit_price;
        }
        return totalSpecialPrice;
    }
}



class Order {  //保存用户点的所有菜的信息
    Record[] records = new Record[100];  //保存订单上每一道的记录
    SpecialDish []s = new SpecialDish[100];
    int length = 0;
    double discount;
    int workFlag = 0;
    int totalPrice = 0;
    int delete[] = new int[100];
    int deleteFlag = 0;
    double specialDiscount;
    int workOrRelaxFlag = 0; //周一到周五的中午为1,晚上为2,周日为3

    int getTotalPrice() {  //计算订单的总价
        for (Record record : records) {
            totalPrice += record.getPrice();
        }
        return totalPrice;
    }

    public int getTotalSpecialPrice(){
        int price = 0;
        for (SpecialDish specialDish : s) {
            price += specialDish.getSpecialPrice();
        }
        return price;
    }


    //添加一条菜品信息到订单中
    void addARecord(int orderNum, String dishName, int portion, int count) {
        records[length].d.name = dishName;
        records[length].portion = portion;
        records[length].count = count;
        records[length].orderNum = orderNum;
        length++;
    }

    void pretendToDelete(int orderNum){
        for (int i = 0; i < length; i++) {
            if (records[i].orderNum == orderNum) {
                totalPrice -= Math.toIntExact(Math.round(records[i].getPrice()));
            }
        }
    }

    SpecialDish findSpecialDish(int Num){
        for (int i = 0; s[i] != null; i++) {
            if(s[i].num == Num){
                return s[i];
            }
        }
        return null;
    }

    void pretendDelRecordByOrderNum(int orderNum, SpecialDish s){
        int flag = 0;
        for (int i = 0; i < deleteFlag; i++) {
            if (delete[i] == orderNum) {
                System.out.println("deduplication " + orderNum);
                return;
            }
        }
        for (int i = 0; i < length; i++) {
            if (records[i].orderNum == orderNum) {
                flag = 1;
                delete[deleteFlag++] = orderNum;
                s.totalSpecialPrice -= s.searchPrice(records[i].d.name);
            }
        }
        if (flag == 0) {
            System.out.println("delete error;");
        }
    }

    void delARecordByOrderNum(int orderNum) {
        int flag = 0;
        for (int i = 0; i < deleteFlag; i++) {
            if (delete[i] == orderNum) {
                System.out.println("deduplication " + orderNum);
                return;
            }
        }
        for (int i = 0; i < length; i++) {
            if (records[i].orderNum == orderNum) {
                flag = 1;
                delete[deleteFlag++] = orderNum;
                totalPrice -= Math.toIntExact(Math.round(records[i].getPrice()));
            }
        }
        if (flag == 0) {
            System.out.println("delete error;");
        }
    }
}


class Record {  //保存订单上的一道菜品记录
    Dish d = new Dish();  //菜品
    int orderNum;
    int count;//订单上的份数
    int portion;  //份额(1/2/3代表小/中/大份)

    int getPrice(){
        return count * d.getPrice(portion);
    }
}


class Dish { //对应菜谱上一道菜的信息。
    String name;  //菜品名称
    int unit_price; //单价

    boolean special;

    public int getPrice(int portion) {  //计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
        double price = 0;
        if (portion == 1) {
            price = unit_price;
        } else if (portion == 2) {
            price = unit_price * 1.5;
        } else if (portion == 3) {
            price = unit_price * 2;
        }
        int price1 = (int) (run(price));
        return price1;
    }

    double run(double num) {
        double a = Math.signum(num); //判断是正数负数还是0,负数返回-1.0,正数返回1.0
        if (a < 0.0)
            return 0.0 - Math.round(Math.abs(num));
        return Math.round(num);
    }
}


class Table {
    Order order[] = new Order[100];
    int num[] = new int[100];//桌子的序号
    String date[] = new String[100];
    String time[] = new String[100];


    public void specialDiscount(int i) {
        String d[] = date[i].split("/");
        LocalDate d1 = LocalDate.of(Integer.parseInt(d[0]), Integer.parseInt(d[1]), Integer.parseInt(d[2]));
        int day = d1.getDayOfWeek().getValue();
        if (day != 6 && day != 7) {
            order[i].specialDiscount = 0.7;
        } else {
            order[i].specialDiscount = 1;
        }
    }

    boolean judgeIfOutYear(int i) {
        String d[] = date[i].split("/");
        LocalDate d1 = LocalDate.of(Integer.parseInt(d[0]), Integer.parseInt(d[1]), Integer.parseInt(d[2]));
        LocalDate startYear = LocalDate.of(2022, 1, 1);
        LocalDate endYear = LocalDate.of(2023, 12, 31);
        if (d1.isAfter(endYear) || d1.isBefore(startYear)) {
            return false;
        }
        return true;
    }

    boolean judgeDiscount(int i) {
        String d[] = date[i].split("/");
        String t[] = time[i].split("/");
        LocalDate d1 = LocalDate.of(Integer.parseInt(d[0]), Integer.parseInt(d[1]), Integer.parseInt(d[2]));
        LocalTime d2 = LocalTime.of(Integer.parseInt(t[0]), Integer.parseInt(t[1]), Integer.parseInt(t[2]));
        LocalTime dRelaxStart = LocalTime.of(9, 30);
        LocalTime dRelaxEnd = LocalTime.of(21, 30);
        LocalTime dWorkStart1 = LocalTime.of(10, 30);
        LocalTime dWorkStart2 = LocalTime.of(17, 0);
        LocalTime dWorkEnd1 = LocalTime.of(14, 30);
        LocalTime dWorkEnd2 = LocalTime.of(20, 30);
        int day = d1.getDayOfWeek().getValue();
        if (day == 6 || day == 7) {
            if (d2.isAfter(dRelaxEnd) || d2.isBefore(dRelaxStart)) {
                order[i].workFlag = 1;
            } else {
                order[i].workOrRelaxFlag = 3;
                order[i].discount = 1;
            }
        } else {
            if ((d2.isAfter(dWorkStart1) && d2.isBefore(dWorkEnd1)) || (d2.until(dWorkStart1, ChronoUnit.SECONDS) == 0 || d2.until(dWorkEnd1, ChronoUnit.SECONDS) == 0)) {
                order[i].discount = 0.6;
                order[i].workOrRelaxFlag = 1;
            } else if ((d2.isAfter(dWorkStart2) && d2.isBefore(dWorkEnd2)) || (d2.until(dWorkStart2, ChronoUnit.SECONDS) == 0 || d2.until(dWorkEnd2, ChronoUnit.SECONDS) == 0)) {
                order[i].workOrRelaxFlag = 2;
                order[i].discount = 0.8;
            } else {
                order[i].workFlag = 1;
            }
        }
        String pattern = "([0-1]?[0-9]|2[0-3])/([0-5][0-9])/([0-5][0-9])";
        String timeString = "";
        char[] c = time[i].toCharArray();
        for (int i1 = 0; i1 < c.length; i1++) {
            timeString += c[i1];
        }
        if (timeString.matches(pattern)) {
            return true;
        } else {
            return false;
        }
    }

    boolean isValidDate(int i) {
        String str[] = date[i].split("/");


        // 接下来需要检查年月日是否都是数字,并且是否分别在合法的范围内
        try {
            int year = Integer.parseInt(str[0]);
            int month = Integer.parseInt(str[1]);
            int day = Integer.parseInt(str[2]);

            if (year < 1 || month < 1 || month > 12) {
                return false;
            }

            if (day < 1 || day > getDaysInMonth(year, month)) {
                return false;
            }
        } catch (NumberFormatException e) {
            return false;
        }

        // 如果以上条件都满足,则说明是一个合法的日期
        return true;
    }

    /**
     * 获取某个月份的天数
     *
     * @param year  年份
     * @param month 月份(1~12)
     * @return 指定月份的天数
     */
    public static int getDaysInMonth(int year, int month) {
        switch (month) {
            case 2:
                return isLeapYear(year) ? 29 : 28;
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
            default:
                return 31;
        }
    }

    /**
     * 判断某一年是否是闰年
     *
     * @param year 年份
     * @return 如果是闰年,则返回true,否则返回false
     */
    public static boolean isLeapYear(int year) {
        if (year % 4 == 0 && year % 100 != 0) {
            return true;
        } else if (year % 400 == 0) {
            return true;
        } else {
            return false;
        }
    }

    public boolean ifLegal(String str, String s) {
        if(Integer.parseInt(s) > 55 || Integer.parseInt(s) < 1){
            return false;
        }
        Pattern pattern = Pattern.compile("^(table)( )([1-9][0-9]*)( )([0-9]{4})(/)([0-9]|[0-9]{2})(/)([0-9]|[0-9]{2})( )([0-9]|[0-9]{2})(/)([0-9]|[0-9]{2})(/)([0-9]|[0-9]{2})$");
        Matcher matcher = pattern.matcher(str);
        if (matcher.matches()) {
            return true;
        }
        return false;
    }

    public boolean ifSameDay(int tablei) {
        String d1[] = date[tablei].split("/");
        LocalDate day = LocalDate.of(Integer.parseInt(d1[0]), Integer.parseInt(d1[1]), Integer.parseInt(d1[2]));
        for (int i1 = tablei - 1; i1 >= 0; i1--) {
            String d[] = date[i1].split("/");
            LocalDate d_ = LocalDate.of(Integer.parseInt(d[0]), Integer.parseInt(d[1]), Integer.parseInt(d[2]));
            if (d_.getDayOfWeek().getValue() == day.getDayOfWeek().getValue()) {
                return true;
            }
        }
        return false;
    }

    public boolean ifSameTime(int tablei) {
        if (!ifSameDay(tablei)) {
            return false;
        }
        for (int i1 = tablei - 1; i1 >= 0; i1--) {
            if(order[i1].workOrRelaxFlag == order[tablei].workOrRelaxFlag){
                return true;
            }
        }
        return false;
    }
    public boolean ifExistTableNum(int tableNum){
        for (int i = 0; i < num.length; i++) {
            if(num[i] == tableNum){
                return true;
            }
        }
        return false;
    }
}



class Menu {  //对应菜谱,包含饭店提供的所有菜的信息。
    Dish[] dishes = new Dish[100];//菜品数组,保存所有菜品信息
    int length = 0;


    Dish searchDish(String dishName) {
        for (int i = dishes.length - 1; i >= 0; i--) {
            if (dishes[i].name.equals(dishName)) {
                return dishes[i];
            }
        }
        return null; //未找到
    }

    boolean searchSpecial(String dishName) {
        if (searchDish(dishName).special) {
            return true;
        }
        return false;
    }

    boolean findSpecial(String orderNum, Order o) {
        for (int i = 0; i < o.records.length && o.records[i] != null; i++) {
            if (o.records[i].orderNum == Integer.parseInt(orderNum)) {
                if (searchSpecial(o.records[i].d.name)) {
                    return true;
                }
            }
        }
        return false;
    }

    void addDish(String dishName, int unit_price) {
        dishes[length].name = dishName;
        dishes[length].unit_price = unit_price;
        length++;
    }

    void addSpecial(boolean special) {
        dishes[length].special = special;
    }
}

三、踩坑心得

对于这几次题目集而言,我踩的坑确实不少。首先是有些题目中过于依赖循环导致代码运行时间过长,无法满足要求,其次是没有搞清楚正则表达式运用的条件,导致一开始做题目集五的时候一直错,后面才搞清楚。其实熟练运用正则表达式后能节省很多时间,提高我们的效率。再就是审题的问题。有的时候想当然地就去做题目,没有看清题目要求,然后犯一些低级错误,做了这么多题目之后还是没有改掉这个坏毛病,浪费了很多时间。

 

四、改进建议

  1. 应该多给代码标上备注。比如这几次题目集相隔时间有点远,又经过了菜单四的冲刷,导致我对之前的代码没什么记忆,又没有注释,让我读起来还需要仔细回忆一下这些东西都是干什么的,浪费了很多时间,也感到了注释的重要性
  2. 仔细看清题目给的类图,事实上这些类图是非常重要的,但是我一开始没有重视类图,都是自己乱打一气,其实很不符合题目要求,但是结果是对的

五、总结

通过这几次题目集,我的自学能力和读题能力有了较大的提升(主要归功于菜单类那长达1000多字的题目),学到了hashset方法的使用,确实十分方便,就是语句有点拗口。同时能够掌握正则表达式的运用,节省了很多时间,也提高了总体的效率。最后,虽然老师很不赞同这个想法,但我还是想说,pta能不能给个参考答案啊/(ㄒoㄒ)/~~代码确实不是唯一的,但是起码可以给个思路的参考啊,不然很多时候都不知道自己到底错哪了,就算不给参考答案,测试点也可以标清楚一点,像菜单四,完全就是盲打,截止之后也很难摸清楚方向。虽然但是,还是要多提升自己的思维逻辑,才能在接下来越来越难的题目集中尽可能地得分。

posted on 2023-04-30 23:33  染巷  阅读(216)  评论(0编辑  收藏  举报