面向程序对象设计
前言:
1.相比于之前的题目,题目集4主要是在一些基本的题目类型,除去第一道题目,其他题目难度均比之前要小,包括字符串的排序,重复数据问题,以及java中Date类的使用,当然重中之重的是第一题的菜单题,不过由于个人的轻视以及懒导致并没有去做这一道题,直接导致了零分,也就导致了之后对于第六次作业下手无措的开端埋下了伏笔,确实,自己在这方面是给自己偷懒找理由了.
相比于最开始学习java时不会出现过多的语法错误以及逻辑错误了.
2.题目集5更主要的是体现在学会利用正则表达式这一方便的工具,减少if-else等语句的冗杂,非常方便用于判断字符串的合法性以及适用性,可在一定程度上大大减少原来的代码量,不过正则表达式相比于之前的更加晦涩难懂些,需要在稍微熟悉后才能使用.本次题目集除去前面的4道题以外就是关于聚合关系的实现,这也和之前日期问题相挂钩,虽然代码量增加了,但是类于类之间蕴含了关系,相比于之前更像是面向对象而非面向过程,不过考虑到没有使用面向对象7大基本原则,所以顶多谈得上是挂钩,还不到相关,题目难度稍有提高,最后两题的算法是一样的,只是结构不同.
3.题目集6是之前题目集4的菜单问题的延伸版本,考虑了更多方面的问题,包括多桌问题,添加了更多样的菜品形式以及时间问题,难度相比于之前大大提高,这也导致第一道就没做的我更是无力,而且在这种情况下我更是写出了非常糟糕的代码使得整体结构非常的紊乱,没有将各个问题分别处理,最后也就导致了整个代码改到最后难以改进,也就只能草草地得到十几分的低分,除此之外对于练习时间来说,相比于其他人,确实在这方面的投入要少的多,这也是我今后要更加多的弥补的.,最重要的一点就是没有严格的进行过设计.
4.总结:这三次题目集主要体现了我的设计确实存在问题以及包括偷懒.
设计与分析
训练题集(4)7-2
题目要求:输入一个在1-10000的数n之后再输入n个数,
求:如果存在相同的输出Yes,否则输出NO
源码:
import java.util.*; public class Main{ public static void main(String[] args){ Scanner input=new Scanner(System.in); int num1=input.nextInt(); int arr[]=new int[num1]; int count=0; for(int i=0;i<num1;i++){ arr[i]=input.nextInt(); } Arrays.sort(arr); for(int i=0;i<num1-1;i++){ if(num1==1){ break; } if(arr[i]==arr[i+1]){ count++; break; } } if(count==0){ System.out.print("NO"); }else{ System.out.print("YES"); } } }
输出结果:
题目分析:
本题主要考察数组的遍历以检查相同的,但是如果不使用array的快拍的话,这道题目会显示超时,即遍历时间过长.,在如今的学习中可以使用到treeset或是hashset可以将通过键直接检测是否存在相同数,以及他们的时间效率是远高于数组的.
训练题集(4)7-3
题目要求:输入一个在1-10000的数n之后再输入n个数
求:在一行中按照输入顺序输出去除重复之后的数据。每两个数据之间有一个空格,行首尾不得有多余空格
源码;
import java.util.*; public class Main{ public static void main(String[] args){ Scanner input=new Scanner(System.in); int Number=input.nextInt(); int[] array=new int[100001]; for(int i=0;i<Number;i++){ int index=input.nextInt(); if(array[index]==1){ continue; }else{ array[index]=1; // System.out.print(" "+index); if(i!=0){ System.out.print(" "+index); }else{ System.out.print(index); } } } } }
输出结果:
题目分析:
因为这道题的数据跟上一道一样,但不同的是上一道大部分情况下不会分析到最后一个数字就可以直接break跳出并输出结果,而这道题目不能这样做也就导致如果使用相同格式的算法上一道题目的时间复杂度这一条件就过不去,所以就要求另外使用办法,之后想到的便是通过建立一个数组,相当于每个数字的房间号,每当一个数字被输入时,与数字相同大小的房间便不为0(默认条件下,新创建的数组中每一个元素都为0),每次遍历一个数字便相当于“此房间有人”,并且在之后每一次遍历时都检测该房间是否为空,如果为空就输入并输出,不为空就直接进入下一个数字,一定程度上这种方法大大减少了时间花费,这也使得我这个测试点能够全部通过.和上一题相同点在于均可以使用hashmap和hashset通过对键的查找快速的遍历,可以更加的方便的一种方法.
训练题集(4)7-4
题目要求:输入一段一段英文文本
要求:按照题目要求输出的各个单词(每个单词一行)。
源码:
import java.util.*; public class Main{ public static void main(String []args){ Scanner input = new Scanner(System.in); String Newinput=input.nextLine(); String[] Input=Newinput.split("\\,|\\ |\\."); ArrayList array=new ArrayList(); int flag=0; for(int i=0;i<Input.length;i++){ if(Input[i].equals("")){ String container; flag++; for(int j=i;j<Input.length-1;j++){ container=Input[j+1]; Input[j]=container; } } }String count; for(int i=0;i<Input.length-flag;i++){ for(int j = 0;j<Input.length-flag;j++){ if(Input[j].length()<Input[j+1].length()){ count=Input[j]; Input[j]=Input[j+1]; Input[j+1]=count; }if(Input[j].length()==Input[j+1].length()){ if(Input[j].compareToIgnoreCase(Input[j+1])>0){ count=Input[j]; Input[j]=Input[j+1]; Input[j+1]=count; } } } }System.out.println(Input[0]); for(int i=1;i<Input.length-flag+1;i++){ for(int j=0;j<i;j++){ if(Input[j].equals(Input[i])) break; if(j==i-1) System.out.println(Input[i]); } } } }
输出结果:
题目分析:
嗯,这道题就是先通过spilt分开为一个个字符串数组之后再一一进行排序,不过写的时候可谓之艰辛,就是因为没有考虑到字母大小的问题,后来和同学的交流才知道要进行考虑.
训练题集(4)7-6
题目要求;三个数值,数之间用空格分开
要求:
源码:
import java.util.*; public class Main{ public static void main(String[] args){ Scanner input=new Scanner(System.in); int Degree=input.nextInt(); int Minute=input.nextInt(); double second=input.nextDouble(); double sum=0; sum=Degree+Minute/60.0+second/3600; System.out.print(Degree+"°"+Minute+"′"+second+"″ = "); System.out.printf("%.6f",sum); } }
输出结果:
题目分析:
这道题主要就是一个问题,就是前面的数据没告诉你几位就直接输出就行,否则还容易出错.
训练题集(4)7-7
题目输入:入两行,每行输入一个日期,日期格式如:2022-06-18
题目输出:
第一行输出:第一个日期比第二个日期更早(晚)
第二行输出:两个日期间隔XX天
第三行输出:两个日期间隔XX周
源码;
import java.util.*; import java.time.LocalDate; import java.time.temporal.ChronoUnit; public class Main{ public static void main(String []args){ Scanner input = new Scanner(System.in); String Date1 = input.nextLine(); String Date2 = input.nextLine(); String[] date1 = Date1.split("-"); String[] date2 = Date2.split("-"); int year1 = Integer.parseInt(date1[0]); int year2 = Integer.parseInt(date2[0]); int month1 = Integer.parseInt(date1[1]); int month2 = Integer.parseInt(date2[1]); int day1 = Integer.parseInt(date1[2]); int day2 = Integer.parseInt(date2[2]); LocalDate DATE1 = LocalDate.of(year1,month1,day1); LocalDate DATE2 = LocalDate.of(year2,month2,day2); if(!DATE1.isAfter(DATE2)){ System.out.println("第一个日期比第二个日期更早"); }else{ System.out.println("第一个日期比第二个日期更晚"); } long days = DATE1.until(DATE2, ChronoUnit.DAYS); long weeks = DATE1.until(DATE2, ChronoUnit.WEEKS); System.out.println("两个日期间隔"+Math.abs(days)+"天"); System.out.print("两个日期间隔"+Math.abs(weeks)+"周"); } }
输出结果:
题目分析:
此题主要要求能够掌握并使用java中LocalDate类中的方法(不得不吐槽的一句,难怪前面的题目不让用localdate,当时还不知道啥东西,没成想这么方便).
训练题集(5)7-1
题目要求:
在一行中输入一个字符串。
求:
如果合格,输出:“你输入的QQ号验证成功”;
否则,输出:“你输入的QQ号验证失败”。
源码:
import java.util.*; public class Main{ public static void main(String[] args){ Scanner input = new Scanner(System.in); String QQNumber = input.nextLine(); String regex = "[1-9][0-9]{4,14}"; boolean flag = QQNumber.matches(regex); if(flag){ System.out.print("你输入的QQ号验证成功"); }else{ System.out.print("你输入的QQ号验证失败"); } } }
输出结果:
题目分析:
该题目集前4题均考察正则表达式的使用,考察点相同,所以就第一题分析,首先需设置一个regex,再用flag来代表筛选输入字符串是否true,之后再根据flag来判断输出内容.
训练题集(5)7-5
题目要求:
要求符合设计类图
输出显示:
源码:
import java.util.*; public class Main{ public static void main(String[] args) { 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 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.println(date.getNextNDays(n).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.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(fromDate.getDaysofDates(toDate)); } else { System.out.println("Wrong Format"); System.exit(0); } } else{ System.out.println("Wrong Format"); System.exit(0); } } } class Year{ private int value; Year (){ } Year (int value){ this.value = value; } public int getValue(){ return value; } public void setValue(int value){ this.value = value; } public boolean isLeapYear (){ return (value % 400 == 0) || (value % 4 == 0 && value % 100 != 0); } public boolean validate (){ return value >= 1900 && value <= 2050; } public void yearIncrement(){ this.value++; } public void yearReduction(){ this.value--; } } class Month{ private int value; private Year year = new Year(); Month() { } Month (int yearValue, int monthValue){ year.setValue(yearValue); value = monthValue; } public int getValue(){ return value; } public void setValue(int value){ this.value = value; } Year getYear(){ return year; } public void setYear(Year year){ this.year = year; } public void resetMin(){ this.value = 1; } public void resetMax(){ this.value = 12; } public boolean validate(){ if(value >= 1 &&value <= 12){ return true; }else{ return false; } } public void monthIncrement (){ this.value++; } public void monthReduction (){ this.value--; } } class Day{ private int value; private Month month = new Month(); int []mon_maxnum = new int[]{31,28,31,30,31,30,31,31,30,31,30,31}; Day(){ } Day(int yearValue,int monthValue, int dayValue){ value = dayValue; month.setValue(monthValue); month.getYear().setValue(yearValue); } public int getValue (){ return value; } public void setValue(int value){ this.value = value; } Month getMonth (){ return month; } public void setMonth(Month value){ this.month = value; } public void resetMin(){ if(month.getYear().isLeapYear()){ mon_maxnum[1] = 29; } value = 1; } public void resetMax(){ if(month.getYear().isLeapYear()){ mon_maxnum[1] = 29; } value = mon_maxnum[month.getValue()-1]; } public boolean validate(){ if(month.getYear().isLeapYear()){ mon_maxnum[1] = 29; } if(value <= mon_maxnum[month.getValue()-1] && value >= 1){ return true; }else{ return false; } } public void dayIncrement(){ this.value++; } public void dayReduction(){ this.value--; } } class DateUtil { private Day day = new Day(); DateUtil() { } DateUtil(int d, int m, int y) { day.setValue(y); day.getMonth().setValue(m); day.getMonth().getYear().setValue(d); } Day getDay() { return day; } public void setDay(Day d) { this.day = d; } public boolean checkInputValidity() { return day.getMonth().getYear().validate() && day.getMonth().validate() && day.validate(); } public boolean compareDates(DateUtil date) { if (day.getMonth().getYear().getValue() > date.getDay().getMonth().getYear().getValue() || (day.getMonth().getYear().getValue() > date.getDay().getMonth().getYear().getValue() && day.getMonth().getValue() > date.day.getMonth().getValue()) || (day.getMonth().getYear().getValue() > date.getDay().getMonth().getYear().getValue() && day.getMonth().getValue() > date.day.getMonth().getValue() && day.getValue() > date.getDay().getValue())) { return true; } else { return false; } } public boolean equalTwoDates(DateUtil date) { if (day.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue() && day.getMonth().getValue() == date.getDay().getMonth().getValue() && day.getValue() == date.getDay().getValue()) { return true; } else { return false; } } public String showDate() { return day.getMonth().getYear().getValue() + "-" + day.getMonth().getValue() + "-" + day.getValue(); } public DateUtil getNextNDays(int n) { while (n > 0) { if (day.getMonth().getYear().isLeapYear()) { day.mon_maxnum[1] = 29; } else { day.mon_maxnum[1] = 28; } if (day.getValue() < day.mon_maxnum[day.getMonth().getValue() - 1]) { day.dayIncrement(); n--; } else { n--; if (day.getMonth().getValue() == 12) { day.getMonth().resetMin(); day.resetMin(); day.getMonth().getYear().yearIncrement(); } else { day.getMonth().monthIncrement(); day.resetMin(); } } } DateUtil Days = new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), day.getValue()); return Days; } public DateUtil getPreviousNDays(int n) { while (n > 0) { if (day.getMonth().getYear().isLeapYear()) { day.mon_maxnum[1] = 29; } else { day.mon_maxnum[1] = 28; } if (day.getValue() > 0) { day.dayReduction(); n--; } else { if (day.getMonth().getValue() == 1) { day.getMonth().resetMax(); day.resetMax(); day.getMonth().getYear().yearReduction(); } else { day.getMonth().monthReduction(); day.resetMax(); } } } DateUtil Days = new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), day.getValue()); return Days; } public int getDaysofDates(DateUtil date) { int gap = 0; if (equalTwoDates(date)) { return 0; } else { if (compareDates(date)) { if (date.getDay().getMonth().getYear().getValue() == day.getMonth().getYear().getValue()) { if (date.getDay().getMonth().getValue() != day.getMonth().getValue()) { gap = date.getDay().mon_maxnum[date.getDay().getMonth().getValue() - 1] - date.getDay().getValue(); for (int i = date.getDay().getMonth().getValue() + 1; i < day.getMonth().getValue(); i++) { gap += date.getDay().mon_maxnum[i - 1]; } gap += day.getValue(); return gap; }else{ return day.getValue()-date.getDay().getValue(); } }else{ //gap =date.getDay().mon_maxnum[date.getDay().getMonth().getValue()-1]-date.getDay().getValue(); while(date.getDay().getMonth().getYear().getValue()!=day.getMonth().getYear().getValue()){ gap +=date.getDay().mon_maxnum[date.getDay().getMonth().getValue()-1]-date.getDay().getValue(); if(date.getDay().getMonth().getYear().isLeapYear()){ date.getDay().mon_maxnum[1] = 29; }else{ date.getDay().mon_maxnum[1] = 28; } for(int i = date.getDay().getMonth().getValue();i<12;i++){ gap += date.getDay().mon_maxnum[i]; } date.getDay().getMonth().getYear().yearIncrement(); date.getDay().getMonth().resetMin(); date.getDay().resetMin(); gap += 1; } if(day.getMonth().getYear().isLeapYear()){ day.mon_maxnum[1] = 29; }else{ day.mon_maxnum[1] = 28; } for(int i =0 ;i<day.getMonth().getValue()-1;i++){ gap += day.mon_maxnum[i]; } gap += day.getValue(); gap--; return gap; } }else{ if (date.getDay().getMonth().getYear().getValue() == day.getMonth().getYear().getValue()) { if (date.getDay().getMonth().getValue() != day.getMonth().getValue()) { gap += day.mon_maxnum[day.getMonth().getValue() - 1] - day.getValue(); for (int i = day.getMonth().getValue() + 1; i < date.getDay().getMonth().getValue(); i++) { gap += day.mon_maxnum[i - 1]; } gap += date.getDay().getValue(); return gap; }else{ return date.getDay().getValue()-day.getValue(); } }else{ //gap =day.mon_maxnum[day.getMonth().getValue()-1]-day.getValue(); while(date.getDay().getMonth().getYear().getValue()!=day.getMonth().getYear().getValue()){ gap +=day.mon_maxnum[day.getMonth().getValue()-1]-day.getValue(); if(day.getMonth().getYear().isLeapYear()){ day.mon_maxnum[1] = 29; }else{ day.mon_maxnum[1] = 28; } for(int i = day.getMonth().getValue();i<12;i++){ gap += day.mon_maxnum[i]; } day.getMonth().getYear().yearIncrement();; day.getMonth().resetMin(); day.resetMin(); gap += 1; } if(date.getDay().getMonth().getYear().isLeapYear()){ date.getDay().mon_maxnum[1] = 29; }else{ date.getDay().mon_maxnum[1] = 28; } for(int i =0 ;i<date.getDay().getMonth().getValue()-1;i++){ gap += date.getDay().mon_maxnum[i]; } gap += date.getDay().getValue(); gap--; return gap; } } } } }
类图:
复杂度:
输出结果:
题目分析:
该题目与之前的题目集3的日期类设计题目内容相似,其算法大致相似.主要要求改变的是类与类之间的关系,即聚合关系,使得各个类之间互相具有了联系,即主方法调用DateUtil类,而DateUtil类调用Day类,Day类调用Month类,Month类调用Year类,层层递进,却是在开始的时候这种关系的实现需要一些时间去思考,甚至在后来的过程发现原来的算法并不适用因为要保留一些数据进行下一步的处理,但是根据类图中的变量并不允许我去这样设置,使得我在这方面不得不去重新构造新的算法,以及一些新的思路,这也给我的整个日期问题提供了一种新的思路.
训练题集(5)7-6
题目要求:
题目求解:
与上题一样.
源码:
import java.util.*; public class Main { public static void main(String[] args) { 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 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.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " next " + n + " days is:"); System.out.println(date.getNextNDays(n).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.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " 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 Year{ private int value; Year (){ } Year (int value){ this.value = value; } public int getValue(){ return value; } public void setValue(int value){ this.value = value; } public boolean isLeapYear (){ return (value % 400 == 0) || (value % 4 == 0 && value % 100 != 0); } public boolean validate (){ return value >= 1820 && value <= 2020; } public void yearIncrement(){ this.value++; } public void yearReduction(){ this.value--; } } class Month{ private int value; Month (){ } Month (int Value){ this.value = Value; } public int getValue(){ return value; } public void setValue(int value){ this.value = value; } public void resetMin(){ this.value = 1; } public void resetMax(){ this.value = 12; } public boolean validate(){ if(value >= 1 &&value <= 12){ return true; }else{ return false; } } public void monthIncrement (){ this.value++; } public void monthReduction (){ this.value--; } } class Day { private int value; Day() { } Day(int value) { this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public void dayIncrement() { this.value++; } public void dayReduction() { this.value--; } } class DateUtil { private Day day = new Day(); private Month month = new Month(); private Year year = new Year(); int[] mon_maxnum = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31}; DateUtil() { } DateUtil(int y, int m, int d) { day.setValue(d); month.setValue(m); year.setValue(y); } Month getMonth() { return month; } void setMonth(Month month) { this.month = month; } Year getYear() { return year; } void setYear(Year year) { this.year = year; } Day getDay() { return day; } void setDay(Day day) { this.day = day; } void setDayMin() { day.setValue(1); } void setDayMax() { if(year.isLeapYear()){ mon_maxnum[1] = 29; }else{ mon_maxnum[1] = 28; } day.setValue(mon_maxnum[month.getValue()-1]); } public boolean checkInputValidity() { if (year.validate() && month.validate()) { if (year.isLeapYear()) { mon_maxnum[1] = 29; } else { mon_maxnum[1] = 28; } if (day.getValue() <= mon_maxnum[month.getValue()]) { return true; } else { return false; } } else { return false; } } public boolean compareDates(DateUtil date) { if (year.getValue() > date.getYear().getValue() || (month.getValue() > date.getMonth().getValue()&&year.getValue() == date.getYear().getValue()) || (day.getValue() > date.getDay().getValue()&& month.getValue() == date.getMonth().getValue()&& year.getValue() == date.getYear().getValue())) { return true; } else { return false; } } public boolean equalTwoDates(DateUtil date) { if (day.getValue() == date.getDay().getValue() && year.getValue() == date.getYear().getValue() && month.getValue() == date.getMonth().getValue()) { return true; } else { return false; } } public String showDate() { return year.getValue() + "-" + month.getValue() + "-" + day.getValue(); } public DateUtil getNextNDays(int n){ while (n > 0) { if (year.isLeapYear()) { mon_maxnum[1] = 29; } else { mon_maxnum[1] = 28; } if (day.getValue() < mon_maxnum[month.getValue() - 1]) { day.dayIncrement(); n--; } else { n--; if (month.getValue() == 12) { month.resetMin(); setDayMin(); year.yearIncrement(); } else { month.monthIncrement(); setDayMin(); } } } DateUtil Days = new DateUtil(year.getValue(),month.getValue(), day.getValue()); return Days; } public DateUtil getPreviousNDays(int n) { while (n > 0) { if (year.isLeapYear()) { mon_maxnum[1] = 29; } else { mon_maxnum[1] = 28; } if (day.getValue() > 0) { day.dayReduction(); n--; } else { if (month.getValue() == 1) { month.resetMax(); setDayMax(); year.yearReduction(); } else { month.monthReduction(); setDayMax(); } } } DateUtil Days = new DateUtil(year.getValue(), month.getValue(), day.getValue()); return Days; } public int getDaysofDates(DateUtil date) { int gap = 0; if(equalTwoDates(date)){ return 0 ; } else{ if(compareDates(date)) { if (date.getYear().getValue() != year.getValue()) { if (year.isLeapYear()) { mon_maxnum[1] = 29; } for (int i = month.getValue() - 2; i >= 0; i--) { gap += mon_maxnum[i]; } mon_maxnum[1] = 28; gap += day.getValue(); } else { if (year.isLeapYear()) { mon_maxnum[1] = 29; } for (int i = month.getValue() - 2; i >= 0; i--) { gap += mon_maxnum[i]; } mon_maxnum[1] = 28; gap += day.getValue(); if (date.year.isLeapYear()) { mon_maxnum[1] = 29; } for (int i = date.month.getValue() - 2; i >= 0; i--) { gap -= mon_maxnum[i]; } mon_maxnum[1] = 28; gap -= date.day.getValue(); return gap; } year.yearReduction(); while (true) { if (year.getValue() != date.year.getValue()) { if (year.isLeapYear()) { gap += 366; } else { gap += 365; } year.yearReduction(); } else { break; } } if (date.year.isLeapYear()) { mon_maxnum[1] = 29; for (int i = date.month.getValue() - 2; i >= 0; i--) { gap -= mon_maxnum[i]; } mon_maxnum[1] = 28; gap -= date.day.getValue(); gap += 366; mon_maxnum[1] = 29; } else { for (int i = date.month.getValue() - 2; i >= 0; i--) { gap -= mon_maxnum[i]; } mon_maxnum[1] = 28; gap -= date.day.getValue(); gap += 365; //return gap; } return gap; }else{ if (date.getYear().getValue() != year.getValue()) { if (date.year.isLeapYear()) { mon_maxnum[1] = 29; } for (int i = date.month.getValue() - 2; i >= 0; i--) { gap += mon_maxnum[i]; } mon_maxnum[1] = 28; gap += date.day.getValue(); } else { if (year.isLeapYear()) { mon_maxnum[1] = 29; } for (int i = month.getValue() - 2; i >= 0; i--) { gap -= mon_maxnum[i]; } mon_maxnum[1] = 28; gap -= day.getValue(); if (date.year.isLeapYear()) { mon_maxnum[1] = 29; } for (int i = date.month.getValue() - 2; i >= 0; i--) { gap += mon_maxnum[i]; } mon_maxnum[1] = 28; gap += date.day.getValue(); return gap; } date.year.yearReduction(); while (true) { if (year.getValue() != date.year.getValue()) { if (date.year.isLeapYear()) { gap += 366; } else { gap += 365; } date.year.yearReduction(); } else { break; } } if (year.isLeapYear()) { mon_maxnum[1] = 29; for (int i = month.getValue() - 2; i >= 0; i--) { gap -= mon_maxnum[i]; } mon_maxnum[1] = 28; gap -= day.getValue(); gap += 366; mon_maxnum[1] = 29; } else { mon_maxnum[1] = 28; for (int i = month.getValue() - 2; i >= 0; i--) { gap -= mon_maxnum[i]; } mon_maxnum[1] = 28; gap -= day.getValue(); gap += 365; } return gap; } } } }
类图:
复杂度:
题目结果:
题目分析:
与上一道题目不同的是这道题目主要考察聚合关系发生的变化,从原本的多层调用变为DateUtil调用Month,Year,Day类,依赖关系也发生变化,想到这个题目就有点像外观模式,即生成一个客户类去和各个类之间打交道,可以解耦提高代码的可复用性.
训练题集(6)7-1
题目输出与要求:
源码:
import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); String information = null; boolean containsDish = true; int tableOfNumber[] = new int[60]; int[] mon_maxnum = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int PricesOfMeals = 0;//记录每条菜的价格 int PricesOfspecialMeals = 0;//特别餐的价格 boolean DateErrorOfMeal = false; boolean DateError = false; boolean formatNumberOfTable = true; boolean DateOfTable = true;//默认输入数据合法,判断合法后再进行下一步 boolean FomatOfDateOfTable = true; Menu menu = new Menu(); Dish dish = new Dish(); Record record = new Record(); Order order = new Order(menu); int [] SpecialMenu = new int[30]; String[] specialDish = new String[30];//用于标注特殊菜品 int[] DateOfDay = new int[]{1, 2, 3, 4, 5, 6, 7};//用于判断星期几 int SumOfDay = 0;//计算总共多少天 int flag = 0;//用于判断点菜到哪个阶段 int numberOfTable = 0; int deleteFlag[] = new int[50]; int NuM = 0; boolean Stopflag = false; //int count = 0;//用于计算特殊采数目 information = input.nextLine(); boolean saletime = true;//判断是否在营业时间 double normalPrice = 1; double specialPrice = 1; while (containsDish) { if (information.equals("end")) { break; } while (!information.equals("end")) { int count = 0;//用于计数特殊菜数目 //information = input.nextLine(); //int flag = 0;//用于判断点菜到哪个阶段 if (Stopflag ) { flag = 1; } String Input[] = information.split(" "); while (true) { if (!formatNumberOfTable || !DateOfTable) { if (!Input[0].equals("table")) { break; } } FomatOfDateOfTable = true; formatNumberOfTable = true; if (Input[0].equals("table")) { Stopflag = false; // NuM = Integer.parseInt(Input[1]);//存在桌子 DateError = false; //flag = 1;//进入到点菜阶段 //numberOfTable = Integer.parseInt(Input[1]); if (Input[1].length() > 1) { String regex = "[1-5][0-9]"; formatNumberOfTable = Input[1].matches(regex); } else { String regex = "[1-9]"; formatNumberOfTable = Input[1].matches(regex); } if (formatNumberOfTable) { NuM = Integer.parseInt(Input[1]);//存在桌子 tableOfNumber[NuM] = 1; numberOfTable = Integer.parseInt(Input[1]); } String Maindate = Input[2]; // if(formatNumberOfTable) { // int NuM = Integer.parseInt(Input[1]);//存在桌子 // tableOfNumber[NuM] = 1; // } // if(Input.length == 2){ // System.out.println("invalid dish"); // } String[] Date = Maindate.split("/"); int year = Integer.parseInt(Date[0]); int month = Integer.parseInt(Date[1]); int day = Integer.parseInt(Date[2]); // if (year == 2023) { SumOfDay += 365; for (int i = 0; i < month - 2; i++) { SumOfDay += mon_maxnum[i]; } SumOfDay += day; } else { for (int i = 0; i < month - 2; i++) { SumOfDay += mon_maxnum[i]; } SumOfDay += day; } int remainder = SumOfDay % 7;//判断余数日期 //用于计算日期 String MainTime = Input[3]; String date[] = MainTime.split("/"); int hour = Integer.parseInt(date[0]); int minute = Integer.parseInt(date[1]); int second = Integer.parseInt(date[2]); //System.out.println(date[1].length()); //集中进行桌子信息的判断 //String NumberOFTable = String.valueOf(NumberOfTable); //if (NumberOFTable.equals(Input[1])) { //System.out.println(date[1].matches("[0-9][0-9]")); // while(true){ // if((FomatOfDateOfTable != Date[0].matches("[0-9][0-9][0-9][0-9]"))){ // FomatOfDateOfTable = true; // break; // } // } // if((FomatOfDateOfTable != Date[0].matches("[0-9][0-9][0-9][0-9]")) || (FomatOfDateOfTable != Date[1].matches("[0-9][0-9]")) || (FomatOfDateOfTable != Date[2].matches("[0-9][0-9]"))){ // FomatOfDateOfTable = false; // if((FomatOfDateOfTable != date[0].matches("[0-9][0-9]")) || (FomatOfDateOfTable != date[1].matches("[0-9][0-9]")) || (FomatOfDateOfTable != date[2].matches("[0-9][0-9]"))){ // FomatOfDateOfTable = false; // } // } while (true) { if ((FomatOfDateOfTable != Date[0].matches("[0-9][0-9][0-9][0-9]"))) { FomatOfDateOfTable = false; break; } if (Date[1].length() == 1) { if (FomatOfDateOfTable != Date[1].matches("[0-9]")) { FomatOfDateOfTable = false; break; } }else { if ((FomatOfDateOfTable != Date[1].matches("[0-9][0-9]"))) { FomatOfDateOfTable = false; break; } } if (Date[2].length() == 1) { if (FomatOfDateOfTable != Date[2].matches("[0-9]")) { FomatOfDateOfTable = false; break; } }else { if ((FomatOfDateOfTable != Date[2].matches("[0-9][0-9]"))) { FomatOfDateOfTable = false; break; } } if (date[0].length() == 1) { if (FomatOfDateOfTable != date[0].matches("[0-9]")) { FomatOfDateOfTable = false; break; } } else { if ((FomatOfDateOfTable != date[0].matches("[0-9][0-9]"))) { FomatOfDateOfTable = false; break; } } if (date[1].length() == 1) { if (FomatOfDateOfTable != date[1].matches("[0-9]")) { FomatOfDateOfTable = false; break; } }else { if ((FomatOfDateOfTable != date[1].matches("[0-9][0-9]"))) { FomatOfDateOfTable = false; break; } } if (date[2].length() == 1) { if (FomatOfDateOfTable != date[2].matches("[0-9]")) { FomatOfDateOfTable = false; break; } }else { if ((FomatOfDateOfTable != date[2].matches("[0-9][0-9]"))) { FomatOfDateOfTable = false; break; } } break; }//判断时间合法 // if (Date[0].length() == 4 && (Date[1].length() == 2 || Date[1].length() == 1) && (Date[2].length() == 2 || Date[2].length() == 1)) { // if ((date[0].length() == 1 || date[0].length() == 2) && (date[1].length() == 2 || date[1].length() == 1) && (date[2].length() == 2 || date[2].length() == 1)) { // FomatOfDateOfTable = true; // } // } if ((year >= 2022 && year <= 2023) && ((month >= 1 && month <= 12)) && day <= mon_maxnum[month - 1]) { if (hour >= 0 && hour <= 24 && minute >= 0 && minute <= 60 && second >= 0 && second <= 60) { if (remainder <= 5) { if ((hour == 10 && minute >= 30)) { normalPrice = 0.6; specialPrice = 0.7; } else if (hour == 14 && minute <= 30) { normalPrice = 0.6; specialPrice = 0.7; } else if (hour >= 11 && hour <= 13) { normalPrice = 0.6; specialPrice = 0.7; } else if (hour >= 17 && hour <= 19) { normalPrice = 0.8; specialPrice = 0.7; } else if (hour == 20 && minute <= 30) { normalPrice = 0.8; specialPrice = 0.7; } else { saletime = false; } } else { if (hour == 9 && minute >= 30) {//normalPrice = 1; } else if (hour >= 10 && hour <= 20) { } else if (hour == 21 && minute <= 30) { } else { saletime = false;//周末均全价 } } //saletime = false; } else { FomatOfDateOfTable = false; } } else { FomatOfDateOfTable = false; } //break; } else if (Input[0].contains("t") || Input[0].contains("a") || Input[0].contains("b") || Input[0].contains("l") || Input[0].contains("e")) { flag = 1;//进入并归计算 DateError = true; } else { break; } if (!formatNumberOfTable || !FomatOfDateOfTable) { DateError = true; if (count != 1) { System.out.println("wrong format"); } count = 1; information = input.nextLine(); //flag = 1; //break; } else { Stopflag = true; count = 0; flag = 4; System.out.println("table " + Input[1] + ": "); break; } } // if (DateError) { // System.out.println("wrong format"); // } if (flag == 0) {//输菜阶段 if (Input.length < 3) { int price = Integer.parseInt(Input[1]); boolean PriceRange;//默认价格正确 if (price > 300 || price <= 0) { System.out.println(Input[0] + " price out of range" + price); } if (Input[1].charAt(0) == '0') { //String priceregex = "[1-9]"; //boolean PriceRange = false;//默认价格正确 PriceRange = true; } else { PriceRange = false; } if (PriceRange) { System.out.println("wrong format"); break; } //int price = Integer.parseInt(Input[1]); String NumberOfPrice = String.valueOf(price); if (NumberOfPrice.equals(Input[1])) { menu.addDish(Input[0], price); } else { System.out.println("wrong format"); } } else { int price = Integer.parseInt(Input[1]); boolean PriceRange = false;//默认价格正确 if(Input.length >3){ PriceRange = true; } // int price = Integer.parseInt(Input[1]); // boolean PriceRange;//默认价格正确 if (!Input[2].equals("T")){ PriceRange = true; } PriceRange = Input[1].matches("[123456789][0-9]{1,3}"); if (PriceRange) { System.out.println("wrong format"); break; } if (price > 300 || price <= 0) { System.out.println(Input[0] + " price out of range" + price); break; } String NumberOfPrice = String.valueOf(price); if (NumberOfPrice.equals(Input[1])) { specialDish[count] = Input[0]; menu.addDish(Input[0], price); count++; } else { System.out.println("wrong format"); } } } else if (flag == 1) {//进入点菜阶段 //int deleteFlag[] = new int[10]; boolean isSpecialDish = false; boolean isFormatSize = false; boolean isFormatPortion = false;//默认菜大小,份数均错误 boolean isFormatSizelength = false; boolean isFormatPortionlegal = false; if (Input.length > 2 && !information.contains("T")) {//点菜 int orderNum = Integer.parseInt(Input[0]); String dishName = Input[1]; for (int i = 0; i < specialDish.length; i++) { if (dishName.equals(specialDish[i])) { isSpecialDish = true; } } int Size = Integer.parseInt(Input[2]); if (isSpecialDish) { if (Size >= 1 && Size <= 3) { isFormatSize = true; } } else { if (Size >= 1 && Size <= 3) { isFormatSize = true; } } if (Size < 10) { isFormatSizelength = true; } int NumberOfDish = Integer.parseInt(Input[3]); if (NumberOfDish <= 15) { isFormatPortion = true; } String regex = "[1-9]"; if (Input[3].length() == 1) { isFormatPortionlegal = Input[3].matches(regex); } else { isFormatPortionlegal = true; } if (!isFormatSizelength) { System.out.println("wrong format"); information = input.nextLine();//重新输入下一串语句 break; } if (!isFormatSize) { System.out.println(orderNum + " portion out of range " + Size); information = input.nextLine();//重新输入下一串语句 break; } if (!isFormatPortionlegal) { System.out.println("wrong format"); information = input.nextLine();//重新输入下一串语句 break; } if (!isFormatPortion) { System.out.println(orderNum + " num out of range " + NumberOfDish); information = input.nextLine();//重新输入下一串语句 break; } // deleteFlag[orderNum] = orderNum; //order.addARecord(orderNum,dishName,Size,NumberOfDish); if (order.addARecord(orderNum, dishName, Size, NumberOfDish) == null) { break; } else { boolean specialFlag = false; for (int i = 0; i < specialDish.length; i++) { if (dishName.equals(specialDish[i])) { deleteFlag[orderNum] = orderNum; SpecialMenu[orderNum] = orderNum; specialFlag = true; PricesOfspecialMeals += order.findRecordByNum(orderNum); information = input.nextLine(); break; } } if(!specialFlag) { deleteFlag[orderNum] = orderNum; PricesOfMeals += order.findRecordByNum(orderNum); information = input.nextLine(); break; }else{ break; } //order.findRecordByNum(orderNum);//多桌启用 //System.out.println(orderNum+" "+dishName+" "+); } //System.out.println(orderNum+" "+dishName+" "+) //System.out.println(orderNum+" "+dishName+" "+); } else if (Input[1].equals("delete")) {//取消菜 int deleteNum = Integer.parseInt(Input[0]); if (deleteFlag[deleteNum] != deleteNum) { System.out.println("deduplication " + deleteNum); information = input.nextLine();//重新输入下一串语句 break; } if(SpecialMenu[deleteNum] != deleteNum){ PricesOfMeals = PricesOfMeals - order.findRecordByNum(deleteNum); //System.out.println(deleteNum); order.delARecordByOrderNum(deleteNum); //System.out.println(order.getTotalPrice()); deleteFlag[deleteNum] = 0; information = input.nextLine();//重新输入下一串语句 break; } PricesOfspecialMeals = PricesOfspecialMeals - order.findRecordByNum(deleteNum); //System.out.println(deleteNum); order.delARecordByOrderNum(deleteNum); //System.out.println(order.getTotalPrice()); deleteFlag[deleteNum] = 0; information = input.nextLine();//重新输入下一串语句 break; } else if (Input.length == 2 || information.contains("T")) { //System.out.println(information.contains("T")); if(information.contains("T")){ System.out.println("invalid dish"); containsDish = false; //information = input.nextLine(); break; } System.out.println("invalid dish"); information = input.nextLine();//重新输入下一串语句 break; } } information = input.nextLine();//重新输入下一串语句 } } if (information.equals("end") || !containsDish) { // if (formatNumberOfTable) { // tableOfNumber[NuM] = 1; // System.out.println("Table " + NuM + ": "); // } int afterdiscountPrice = (int) (Math.round(PricesOfMeals * normalPrice) + Math.round(PricesOfspecialMeals * specialPrice)); System.out.println("table " + numberOfTable + ": " + order.getTotalPrice() + " " + afterdiscountPrice); } } } class Dish { String name;//菜品名称 int unit_price; //单价 public Dish(){ } public String getName(){ return name; } public int getUnit_pricenit(){ return unit_price; } public void setName(String name) { this.name = name; } public void setUnit_price(int unit_price) { this.unit_price = unit_price; } public Dish(String name, int unit_price){ this.name = name; this.unit_price = unit_price; } public int getPrice(int portion){ float sign[] = {1, 1.5f , 2}; return Math.round((unit_price * sign[portion - 1])); }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) } class Record { private int NumberOfDish;//菜的数目 private int orderNum;//序号 private Dish d;//菜品\\ private int portion;//份额(1/2/3代表小/中/大份) private boolean Delte = false;//删除显示 private boolean Status = false;//菜的状态 public Record() { } public Dish getD() { return d; } public int getOrderNum() { return orderNum; } public Record(int orderNum, Dish d, int portion, int NumberOfDish) { this.portion = portion; this.d = d; this.NumberOfDish = NumberOfDish; this.orderNum = orderNum; } public int getNumberOfDish() { return NumberOfDish; } public int getPortion() { return portion; } public void setOrderNum(int orderNum) { this.orderNum = orderNum; } public void setNumberOfDish(int numberOfDish) { NumberOfDish = numberOfDish; } public void setD(Dish d) { this.d = d; } public void setPortion(int portion) { this.portion = portion; } int getPrice(){ return d.getPrice(portion) * NumberOfDish; }//计价,计算本条记录的价格 public boolean showStatus(){ return Status; } public void setStatus(boolean Status){ this.Status = Status; } public boolean showDelte() { return Delte; } public void setDelte(boolean Delte){ this.Delte = Delte; } } class Order { private Menu menu; private int SumPrice = 0; private int price = 0; ArrayList<Record> records = new ArrayList<>();//保存订单上每一道的记录 public Order(Menu menu) { this.menu = menu; } public int getTotalPrice() { for (Record record : records) { int Price = record.getPrice(); if (!record.showDelte()) { SumPrice += Price; } } return SumPrice; }//计算订单的总价 Record addARecord(int orderNum, String dishName, int portion, int num) { Dish dish = menu.searthDish(dishName); if (dish == null) { System.out.println(dishName + "does not exist"); return null; } Record record = new Record(orderNum, dish, portion, num); records.add(record); price = record.getPrice(); System.out.println(record.getNumberOfDish() + " " + record.getD().getName() + " " + price); return record; }//添加一条菜品信息到订单中。 public boolean delARecordByOrderNum(int orderNum) { for (Record record : records) { if (!record.showDelte() && !record.showStatus() && record.getOrderNum() == orderNum) { record.setDelte(true); return true; } } //System.out.println("delete error;"); return false; }//根据序号删除一条记录 public int findRecordByNum(int orderNum) { for (Record record : records) { if (record.getOrderNum() == orderNum) { return record.getPrice(); } } //根据序号查找一条记录 return 0; } } class Menu { ArrayList<Dish> dishs = new ArrayList<>();//菜品数组,保存所有菜品信息 Dish searthDish(String dishName){ for(Dish dish : dishs){ if(dish.getName().equals(dishName)){ return dish; } } return null; }//根据菜名在菜谱中查找菜品信息,返回Dish对象。 Dish addDish(String dishName,int unit_price){ for(Dish dish : dishs){ if(dish.getName().equals(dishName)){ dish.setUnit_price(unit_price); return dish; } } Dish dish = new Dish(dishName,unit_price); dishs.add(dish); return dish; }//添加一道菜品信息 }
输出结果:
复杂度:
题目分析:
确实呢结论相比于之前这道题目真的难度是前所未有的,考虑到实际上与之前的题目集的4的7-1的是有一些关系的,出于没有任何经验的结果下,当然还缺少不了是因为自己懒的原因下,导致后面四天才开进行(本来时间期限是7天的),主要考察的就是关于输入形式的考虑,这也与之前的正则表达式不谋而合,但是在最开始的码的过程中我并没有考虑到这一点,这又就导致我后面甚至是写成了屎山代码,即太多的if-else语句导致整个代码体系结构紊乱,甚至到我后面想改的时候牵一发而动全身,到达了一个无可救药的地步.总结来说就是需要在写之前分别想好对应的模块去处理相应的算法,否则就写的耦合度太高,基本没有拓展可言.
踩坑心得
1.对于越是要求量大的题目更需要提前进行好构思,模块化的对应处理非常重要.
2.在题目只给出一些形式的情况下应提前考虑到一些情况,即不知道测试点的情况下也能根据其提示推测出大概的要求其写出对应的算法,不同算法不同结果.
3.不能照搬一些算法,因为不同的情况下限制条件也会有所区别,包括对于一些已经给出的类图中未出现的变量不能因为自己的需求就进行设置,全局变量在非必要情况少进行设置.
4.能用正则表达式对输入进行限制判断就尽量使用,可以大量减少重复代码量以及减少if-else语句的使用,方便整体进行判断,以及对于新要求的提出可以只需要进行一些删改,总的来说就是可以非常的便捷.
改进建议
代码的规范性,相比于以前,代码中要更加具有空格符合现在基本上大部分的代码风格.还是构思问题,一定要三思而后行,不要一开始就直接上手不经过大脑思考,虽然这样可能会使一些简单的要求被很快完成,但是对于复杂的问题就难以求解,耦合度越来越高,使得整个代码就只是那样,并不具有过河很好的过渡性.提高代码的可读性,方便自己也能看懂(不仅仅只是写注释这种,写也会写累死).充分考虑到不仅仅只是面向过程,还包括面向对象.
总结
相比于之前的练习来说,我并没有意识到题目是越来越难的,我只认为投入少部分就能收获很多,这是一种相对来说消极的思想,应该拨正我的思想,尽可能将更多的时间投入到这方面的学习中去,相比于先用再学,我往往是经常看完一个相关的点之后再投入使用,但实际上这样的实际上效率并不高,先用再学,这是一条非常实用的经验,废话不多说,实践为真.
标签:心得体会,int,System,getValue,OOP4,date,习题,day,getMonth From: https://www.cnblogs.com/gaybear/p/17357043.html