前言:
JAVA_BLOG_PTA题目集4-6_总结分析
题目集四:
知识点:大体如预备知识,即:通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。另加上题目一难度较大的类间设计与方法使用。
题量:适中,时间开得相对较短但是勉强写得下来。
难度:菜单计价程序难度较大,其余题目难度偏低。但是在看见最后一题的预备知识提要之间写得崎岖艰辛,希望下次可以把它放到整个题目集的前言或者第一题的须知。
题目集五:
知识点:正则表达式、字符串、类间聚合设计。
题量:适中,写下来比题目集四轻松。
难度:正则表达式训练难度不大,但是这属于记忆量较大的新知识,上手比较慢,但是找到对应的公式后写起来很快。末两题在一开始对于这种高聚合调用有点无从下手,试了两次上手了就还好,算法和之前的差不多,之前没做出来的日期差这次写出来了,总体上过得去。
题目集六:
知识点:技术上,类的设计,类间关系的处理。方法上,把题目变成填空题。一些微妙的算法。
题量:只有一题。
难度:老师原话,难度较大,预计代码行数1000+,需用时20h+。后更新准确数据为1700+行往上,个人用时,只作粗略估计,远不止20h……
设计与分析:
04-7-1
(源码稀巴烂所以只作分析……)
分析:(事后再来看。当时居然连Main以外的类都没写出来,蠢得没下限啊这是。)
增删查都是ArrayList,返回类型是ArrayList的new一开始就少了个<>,识别就在数组里遍历一遍查找对照,多桌菜循环加对首字符串的判断。写了0671再来看这个真的蠢得……
05-7-5
源码数据:
类图:
源码:
//package _05_5__; import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int year1, month1, day1; int year2, month2, day2; int number = in.nextInt(); if(number < 1 || number > 3) { System.out.println("Wrong Format"); System.exit(0); } else if (number == 1) { //下n天 year1 = in.nextInt(); month1 = in.nextInt(); day1 = in.nextInt(); DateUtil date = new DateUtil(year1, month1, day1); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } else{ int m = in.nextInt(); System.out.println(date.getNextNDays(m).showDate()); } } else if (number == 2) { //前n天 year1 = in.nextInt(); month1 = in.nextInt(); day1 = in.nextInt(); DateUtil date = new DateUtil(year1, month1, day1); if (!date.checkInputValidity()) { //检查日期是否合法 System.out.println("Wrong Format"); System.exit(0); } else { int n = in.nextInt(); if(n < 0) { //日期越界情况 System.out.println("Wrong Format"); System.exit(0); } System.out.println(date.getPreviousNDays(n).showDate()); } } else { //两天之间相差的天数 year1 = in.nextInt(); month1 = in.nextInt(); day1 = in.nextInt(); year2 = in.nextInt(); month2 = in.nextInt(); day2 = in.nextInt(); DateUtil fromDate = new DateUtil(year1, month1, day1); DateUtil toDate = new DateUtil(year2, month2, day2); if (!fromDate.checkInputValidity() || !toDate.checkInputValidity()) { //检查日期的合法性 System.out.println("Wrong Format"); System.exit(0); } else { System.out.println(fromDate.getDaysofDates(toDate)); } } } } //package _05_5__; class Year { private 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(){ if((value % 4 == 0 && value % 100 != 0) || value % 400 == 0) { return true; } else return false; } //校验数据合法性 public boolean validate(){ if(value < 1900 || value > 2050){ return false; } else return true; } //年份加一 public void yearIncrease(){ value++; } //年份减一 public void yearReduction(){ value--; } } //package _05_5__; class Month { private int value; private Year year; public Month(){ } public Month(int yearValue, int monthValue){ this.value = monthValue; this.year = new Year(yearValue); } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Year getYear() { return year; } public void setYear(Year year) { this.year = year; } //月份复位(1) public void resetMin(){ value = 1; } //月份设置为12 public void resetMax(){ value = 12; } //检验数据合法性 public boolean validate(){ if(value < 1 || value > 12){ return false; } else return true; } //月份加一 public void monthIncrement(){ value ++; } //月份减一 public void monthReduction(){ value --; } } //package _05_5__; class Day { private int value; private Month month; private int[] mon_maxnum ={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public Day(){ } public Day(int yearValue, int monthValue, int dayValue){ this.month = new Month(yearValue,monthValue); this.value = dayValue; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Month getMonth() { return month; } public void setMonth(Month month) { this.month = month; } //日期复位1 public void resetMin(){ value = 1; } //日期设为本月最大值 public void resetMax(){ if(this.getMonth().getYear().isLeapYear()){ mon_maxnum[1] = 29; } value = mon_maxnum[month.getValue() - 1]; } //校验数据合法性 public boolean validate(){ if(this.getMonth().getYear().isLeapYear()) mon_maxnum[1] = 29; if (value < 1 || value > mon_maxnum[month.getValue() - 1]){ return false; } else return true; } //日期加一 public void dayIncrement(){ value ++; } //日期减一 public void dayReduction(){ value --; } } //package _05_5__; class DateUtil { private Day day; public DateUtil() { } public DateUtil(int d, int m, int y) { this.day = new Day(d, m, y); } public Day getDay() { return day; } public void setDay(Day d) { this.day = d; } //检验数据是否合法 public boolean checkInputValidity() { if (this.getDay().getMonth().getYear().validate() && this.getDay().getMonth().validate() && day.validate()) return true; else return false; } //比较两个日期的大小 public boolean compareDates(DateUtil date) { if (date.getDay().getMonth().getYear().getValue() < this.getDay().getMonth().getYear().getValue()) return false; else if (date.getDay().getMonth().getYear().getValue() == this.getDay().getMonth().getYear().getValue() && date.getDay().getMonth().getValue() < this.getDay().getMonth().getValue()) return false; else if (date.getDay().getMonth().getYear().getValue() == this.getDay().getMonth().getYear().getValue() && date.getDay().getMonth().getValue() == this.getDay().getMonth().getValue() && date.getDay().getValue() < this.getDay().getValue()) return false; else return true; } //判定两个日期是否相等 public boolean equalDates(DateUtil date) { if (this.getDay().getValue() == date.getDay().getValue() && this.getDay().getMonth().getValue() == date.getDay().getMonth().getValue() && this.getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()) return true; else return false; } //日期值格式化 public String showDate() { return this.getDay().getMonth().getYear().getValue() + "-" + this.getDay().getMonth().getValue() + "-" + this.getDay().getValue(); } //求下n天 public DateUtil getNextNDays(int n) { int[] mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; for (; n > 0; n--) { if (day.getMonth().getYear().isLeapYear()) { mon_maxnum[2] = 29; } else { mon_maxnum[2] = 28; } if (day.getValue() > mon_maxnum[day.getMonth().getValue()] - 1) { if (day.getMonth().getValue() < 12) { day.getMonth().monthIncrement(); day.resetMin(); } else { day.getMonth().getYear().yearIncrease(); day.getMonth().resetMin(); day.resetMin(); } } else { day.dayIncrement(); } } return new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), day.getValue()); } //求前n天 public DateUtil getPreviousNDays(int n) { for (; n > 0; n--) { if (day.getValue() > 1) { day.dayReduction(); } else { if (day.getMonth().getValue() == 1) { day.getMonth().getYear().yearReduction(); day.getMonth().resetMax(); day.resetMax(); } else { day.getMonth().monthReduction(); day.resetMax(); } } } return new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), day.getValue()); } private static int[] mon = {//几个月之间的天数和 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; //求两个日期之间的天数 public int getDaysofDates(DateUtil date) { DateUtil date1 = this; DateUtil date2 = date; if (this.equalDates(date)) {//如果两天的日期相等 return 0; } else if (!this.compareDates(date)) {//如果日期大小不对 date1 = date; date2 = this; } int[] mon_nummax = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int i = 0, j = 0, days = 0; if(date1.getDay().getMonth().getYear().getValue() < date2.getDay().getMonth().getYear().getValue() - 1) { for (i = date1.getDay().getMonth().getYear().getValue() + 1; i < date2.getDay().getMonth().getYear().getValue(); i++) {//两个日期之间有完整的间隔年,其日期数 days = days + 365; if (new Year(i).isLeapYear()) days++; } } if (date1.getDay().getMonth().getYear().getValue() == date2.getDay().getMonth().getYear().getValue() && date1.getDay().getMonth().getValue() == date2.getDay().getMonth().getValue()) {//年份相同,月份相同,日不同 days = days + (date2.getDay().getValue() - date1.getDay().getValue()); } else if (date1.getDay().getMonth().getYear().getValue() == date2.getDay().getMonth().getYear().getValue() && date1.getDay().getMonth().getValue() < date2.getDay().getMonth().getValue()) {//年份相同,月份不同 if (date1.getDay().getMonth().getYear().isLeapYear())//是闰年 mon_nummax[1] = 29; days = days + mon_nummax[date1.getDay().getMonth().getValue() - 1] - date1.getDay().getValue();//小日期该月剩余的天数 days = days + date2.getDay().getValue();//大日期的天数 for (j = date1.getDay().getMonth().getValue() + 1; j <= date2.getDay().getMonth().getValue() - 1; j++)//月份天数和 days += mon_nummax[j - 1]; }//date1<date2 else if (date1.getDay().getMonth().getYear().getValue() == date2.getDay().getMonth().getYear().getValue() && date1.getDay().getMonth().getValue() > date2.getDay().getMonth().getValue()) {//年份相同,月份不同 if (date1.getDay().getMonth().getYear().isLeapYear())//是闰年 mon_nummax[1] = 29; days = days + mon_nummax[date2.getDay().getMonth().getValue() - 1] - date2.getDay().getValue();//小日期该月剩余的天数 days = days + date1.getDay().getValue();//大日期的天数 for (j = date2.getDay().getMonth().getValue() + 1; j <= date1.getDay().getMonth().getValue() - 1; j++)//月份天数和 days += mon_nummax[j - 1]; }//date1>date2 else if (date1.getDay().getMonth().getYear().getValue() != date2.getDay().getMonth().getYear().getValue()) {//年份不同 days = days + mon_nummax[date1.getDay().getMonth().getValue() - 1] - date1.getDay().getValue();//小日期在该月剩余的天数 days = days + date2.getDay().getValue();//大日期在该月已经过的天数 for (j = date1.getDay().getMonth().getValue() + 1; j <= 12; j++)//小日期在该年剩余的天数 days = days + mon_nummax[j - 1]; for (j = date2.getDay().getMonth().getValue() - 1; j > 0; j--)//大日期在该年已经过的天数 days = days + mon_nummax[j - 1]; if (date1.getDay().getMonth().getYear().isLeapYear() && date1.getDay().getMonth().getValue() <= 2)//如果小日期该年为闰年且该天在1月或2月 days++; if (date2.getDay().getMonth().getYear().isLeapYear() && date2.getDay().getMonth().getValue() > 2)//如果大日期该年为闰年且该天在1月或2月后 days++; } return days; } }
分析:按照题给类图搭起框架,发现相对难写的不是算法,是各种调用。算法按之前的改了改,新写出来的日期差的逻辑是:先判断日期是否同样,同样返回零即零天,不同则进算法,分多层判断年、月、日的大小,按有无整年差整月差和碎天数来加日期。做这题体验了一把模块化的清晰也感受到了高耦合的离谱和诡异。这题耦合度真的太高,类图生成出来直接是链式,好夸张。
05-7-6
源码数据:
类图:
源码:
//package _05_6__; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int year1, month1, day1; int year2, month2, day2; int number = in.nextInt(); if(number < 1 || number > 3) { System.out.println("Wrong Format"); System.exit(0); } else if (number == 1) { //下n天 year1 = in.nextInt(); month1 = in.nextInt(); day1 = in.nextInt(); DateUtil date = new DateUtil(year1, month1, day1); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } else{ int m = in.nextInt(); System.out.println(year1 + "-" + month1 + "-" + day1 + " next " + m + " days is:" +date.getNextNDays(m).showDate()); } } else if (number == 2) { //前n天 year1 = in.nextInt(); month1 = in.nextInt(); day1 = in.nextInt(); DateUtil date = new DateUtil(year1, month1, day1); if (!date.checkInputValidity()) { //检查日期是否合法 System.out.println("Wrong Format"); System.exit(0); } else { int n = in.nextInt(); if(n < 0) { //日期越界情况 System.out.println("Wrong Format"); System.exit(0); } System.out.println(year1 + "-" + month1 + "-" + day1 + " previous " + n + " days is:" +date.getPreviousNDays(n).showDate()); } } else { //两天之间相差的天数 year1 = in.nextInt(); month1 = in.nextInt(); day1 = in.nextInt(); year2 = in.nextInt(); month2 = in.nextInt(); day2 = in.nextInt(); DateUtil fromDate = new DateUtil(year1, month1, day1); DateUtil toDate = new DateUtil(year2, month2, day2); if (!fromDate.checkInputValidity() || !toDate.checkInputValidity()) { //检查日期的合法性 System.out.println("Wrong Format"); System.exit(0); } else { System.out.println("The days between " + year1 + "-" + month1 + "-" + day1 + " and " + year2 + "-" + month2 + "-" + day2 + " are:" + fromDate.getDaysofDates(toDate)); } } } } //package _05_6__; class Year { private 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(){ if((value % 4 == 0 && value % 100 != 0) || value % 400 == 0) { return true; } else return false; } //校验数据合法性 public boolean validate(){ if(value < 1820 || value > 2020){ return false; } else return true; } //年份加一 public void yearIncrease(){ value++; } //年份减一 public void yearReduction(){ value--; } } //package _05_6__; class Month { private int value; public Month(){ } public Month(int Value){ this.value = Value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } //月份复位(1) public void resetMin(){ value = 1; } //月份设置为12 public void resetMax(){ value = 12; } //检验数据合法性 public boolean validate(){ if(value < 1 || value > 12){ return false; } else return true; } //月份加一 public void monthIncrement(){ value ++; } //月份减一 public void monthReduction(){ value --; } } //package _05_6__; class Day { private int value; //private int[] mon_maxnum ={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public Day(){ } public Day(int value){ this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } //日期复位1 public void resetMin(){ value = 1; } //日期加一 public void dayIncrement(){ value ++; } //日期减一 public void dayReduction(){ value --; } } //package _05_6__; class DateUtil { private Year year; public Month month; private Day day; private 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.year = new Year(y); this.month = new Month(m); this.day = new Day(d); } 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 d) { this.day = d; } public void setDayMin(){ day.setValue(1); } //日期设为本月最大值 public void setDayMax(){ if(this.getYear().isLeapYear()){ mon_maxnum[1] = 29; } day.setValue(mon_maxnum[month.getValue() - 1]); } //检验数据是否合法 public boolean checkInputValidity() { if (this.getYear().validate() && this.getMonth().validate()) return true; else return false; } //比较两个日期的大小 public boolean compareDates(DateUtil date) { if (date.getYear().getValue() < this.getYear().getValue())//不同年 return false; else if (date.getYear().getValue() == this.getYear().getValue() && date.getMonth().getValue() < this.getMonth().getValue()) return false;//同年不同月 else if (date.getYear().getValue() == this.getYear().getValue() && date.getMonth().getValue() == this.getMonth().getValue() && date.getDay().getValue() < this.getDay().getValue())//同年同月日期一小于二 return false; else return true; } //判定两个日期是否相等 public boolean equalDates(DateUtil date) { if (this.getDay().getValue() == date.getDay().getValue() && this.getMonth().getValue() == date.getMonth().getValue() && this.getYear().getValue() == date.getYear().getValue()) return true; else return false; } //日期值格式化 public String showDate() { return this.getYear().getValue() + "-" + this.getMonth().getValue() + "-" + this.getDay().getValue(); } //求下n天 public DateUtil getNextNDays(int n) { int[] mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; for (; n > 0; n--) { if (year.isLeapYear()) { mon_maxnum[2] = 29; } else { mon_maxnum[2] = 28; } if (day.getValue() > mon_maxnum[month.getValue()] - 1) { if (month.getValue() < 12) { month.monthIncrement(); day.resetMin(); } else { year.yearIncrease(); month.resetMin(); day.resetMin(); } } else { day.dayIncrement(); } } return new DateUtil(year.getValue(), month.getValue(), day.getValue()); } //求前n天 public DateUtil getPreviousNDays(int n) { for (; n > 0; n--) { if (day.getValue() > 1) { day.dayReduction(); } else { if (month.getValue() == 1) { year.yearReduction(); month.resetMax(); setDayMax(); } else { month.monthReduction(); setDayMax(); } } } return new DateUtil(year.getValue(), month.getValue(), day.getValue()); } int[] mon = {//几个月之间的天数和 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; //求两个日期之间的天数 //求两个日期之间的天数 public int getDaysofDates(DateUtil date) { DateUtil date1 = this; DateUtil date2 = date; if (this.equalDates(date)) {//如果两天的日期相等 return 0; } else if (!this.compareDates(date)) {//如果日期大小不对 date1 = date; date2 = this; } int[] mon_nummax = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int i = 0, j = 0, days = 0; if(date1.year.getValue() < date2.year.getValue() - 1) { for (i = date1.year.getValue() + 1; i < date2.year.getValue(); i++) {//两个日期之间有完整的间隔年,其日期数 days = days + 365; if (new Year(i).isLeapYear()) days++; } } if (date1.year.getValue() == date2.year.getValue() && date1.month.getValue() == date2.month.getValue()) {//年份相同,月份相同,日不同 days = days + (date2.getDay().getValue() - date1.getDay().getValue()); } else if (date1.year.getValue() == date2.year.getValue() && date1.month.getValue() < date2.month.getValue()) {//年份相同,月份不同 if (date1.year.isLeapYear())//是闰年 mon_nummax[1] = 29; days = days + mon_nummax[date1.month.getValue() - 1] - date1.getDay().getValue();//小日期该月剩余的天数 days = days + date2.getDay().getValue();//大日期的天数 for (j = date1.month.getValue() + 1; j <= date2.month.getValue() - 1; j++)//月份天数和 days += mon_nummax[j - 1]; }//date1<date2 else if (date1.year.getValue() == date2.year.getValue() && date1.month.getValue() > date2.month.getValue()) {//年份相同,月份不同 if (date1.year.isLeapYear())//是闰年 mon_nummax[1] = 29; days = days + mon_nummax[date2.month.getValue() - 1] - date2.getDay().getValue();//小日期该月剩余的天数 days = days + date1.getDay().getValue();//大日期的天数 for (j = date2.month.getValue() + 1; j <= date1.month.getValue() - 1; j++)//月份天数和 days += mon_nummax[j - 1]; }//date1>date2 else if (date1.year.getValue() != date2.year.getValue()) {//年份不同 days = days + mon_nummax[date1.month.getValue() - 1] - date1.getDay().getValue();//小日期在该月剩余的天数 days = days + date2.getDay().getValue();//大日期在该月已经过的天数 for (j = date1.month.getValue() + 1; j <= 12; j++)//小日期在该年剩余的天数 days = days + mon_nummax[j - 1]; for (j = date2.month.getValue() - 1; j > 0; j--)//大日期在该年已经过的天数 days = days + mon_nummax[j - 1]; if (date1.year.isLeapYear() && date1.month.getValue() <= 2)//如果小日期该年为闰年且该天在1月或2月 days++; if (date2.year.isLeapYear() && date2.month.getValue() > 2)//如果大日期该年为闰年且该天在1月或2月后 days++; } return days; } }
分析:0575的迭代,改了类间关系,一开始看两版类图笔者才疏学浅没太大感觉,写起来,0575你这样设计在公司会被开了的吧。算法一模一样所以不提,类间设计图给得很清晰很舒服,照着填空真的轻松设计类是真累……一个这版没过上版过了的测试点,debug了,没de出来……错,在改。
06-7-1
源码数据:
类图:
源码:
package _06_000; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class Main { public static void main(String[] args) throws ParseException { Scanner in = new Scanner(System.in); Dish dish = new Dish(); LocalDate localDate = new LocalDate(); Menu menu = new Menu(); Order order = new Order(); Record record = new Record(); Table table = new Table(); Time time = new Time(); //只输出WrongFormat的单独拎出来判断,终止进程System.exit(0) String[] ordermenu = new String[100];//序号最多五十五,但是还有别的信息 int i = 0; boolean flag1 = true; while (true){ String information = in.nextLine();//暂时存放每行信息 if (information.equals("end")) {//end一单结尾 break; } ordermenu[i] = information;//每一行一个信息存进数组 i ++; } int pause = 0; boolean flag0 = false; //每一道菜品记录于菜谱 for(int j = 0; j < ordermenu.length; j ++) { if(ordermenu[j].split(" ")[0].equals("table")) { flag0 = true; } if (flag0){ pause = j;//结束菜谱输入,暂停,下个循环以此为起始点 break; } else { dish.setName(ordermenu[j].split(" ")[0]);//分割后第零个小字符串是名字 //判断是否为浮点数:转化为字符数组,看有没有小数点 char[] CheckChar; boolean flag2 = true; for (int p = 0; p < ordermenu[j].split(" ")[1].length(); p ++) { CheckChar = ordermenu[j].split(" ")[1].toCharArray(); if(CheckChar[0] == '0'){ System.out.println("wrong format"); System.exit(0); } else if(CheckChar[p] == '.'){ flag2 = false; break; } } if(!flag2) { System.out.println("wrong format"); break; } else { dish.setUnit_price(Integer.parseInt(ordermenu[j].split(" ")[1]));//价格 } //有些没有T,那里是空,就会数组越界 if(ordermenu[j].split(" ").length == 2){ dish.setKind("N"); } else if(ordermenu[j].split(" ").length == 3){ dish.setKind("T");//特色菜 } if(!dish.priceValidity(dish.getUnit_price())) { System.out.println(dish.getName() + " price out of range " + dish.getUnit_price()); } menu.addDish(dish.getName(), dish.getUnit_price(), dish.getKind());//添加进菜谱里 } } //每次以table为开始的一桌点菜, for (int j = pause; j < ordermenu.length; j ++) {//j-table // 时间日期格式不对输出错误后直接终止,先判断 for (int k = 0; k < 3; k++) { if(ordermenu[j] == null) { break; } else { if(ordermenu[j].split(" ")[3].split("/")[k].length() > 2 || ordermenu[j].split(" ")[3].split("/")[k].length() < 1){ System.out.println("wrong format"); System.exit(0); }//时间格式错误直接结束 } } if(ordermenu[j] == null) { break; } else{ time.setTime(ordermenu[j].split(" ")[3]);//输入时间 } if(!time.TimeValidity(time.getTime())) { System.out.println("table" + table.getTable() + "out of opening hours"); }//不在营业时间 //字符串转日期 SimpleDateFormat datestring = new SimpleDateFormat("yyyy/MM/dd"); for(int k = 1; k < 3; k ++){ if((ordermenu[j].split(" ")[2].split("/")[k].length() > 2 || ordermenu[j].split(" ")[2].split("/")[k].length() < 1) || ordermenu[j].split(" ")[2].split("/")[0].length() != 4){ System.out.println("wrong format"); System.exit(0); }//日期格式错误直接结束 } localDate.setDate(datestring.parse(ordermenu[j].split(" ")[2])); ///时间区域????? if(localDate.dateValidity(localDate.getDate())) { System.out.println("not a valid time period"); }//日期非法 if(ordermenu[pause].split(" ")[0].equals("table")){//第一个词是table if(Character.isDigit(ordermenu[j].split(" ")[1].charAt(0))){//桌号输入第一个数是数字 table.setTable(Integer.parseInt(ordermenu[j].split(" ")[1]));//桌号 if(table.tableValidity(table.getTable()) == 0){// System.out.println(table + "table num out of range"); } else if(ordermenu[j].split(" ")[1].startsWith("0")){ System.out.println("wrong format"); System.exit(0); } else { System.out.println("table " + table.getTable() + ": "); } } else { System.out.println("wrong format"); System.exit(0); } } else { System.out.println("wrong format");//不是table } //table行输入结束,开始点菜 for (int k = pause + 1; k < ordermenu.length; k ++, j ++) { if (ordermenu[k] == null) { break; } else { record.setOrderNum(Integer.parseInt(ordermenu[k].split(" ")[0]));//序号 } //序号必须从小到大"record serial number sequence error"————待 if (ordermenu[k].split(" ")[1].equals("delete")) { if (order.findRecordByNum(Integer.parseInt(ordermenu[k].split(" ")[0]))) {//序号不存在 System.out.println("delete error");//删除记录序号不存在 } else { order.delARecordByOrderNum(record.getOrderNum()); } if (ordermenu[k].equals(ordermenu[k + 1])) { System.out.println("deduplication " + ordermenu[k].split(" ")[0]); }//重复删除 }//输入删除 else if (menu.searchDish(ordermenu[k].split(" ")[1]). getName().equals(ordermenu[k].split(" ")[1])) { record.setD(menu.searchDish(ordermenu[k].split(" ")[1]));//点菜 if(record.portionValidity(record.getPortion()) == -1) {//份额为两位 System.out.println("wrong format"); System.exit(0); } record.setPortion(Integer.parseInt(ordermenu[k].split(" ")[2]));//份额 if(ordermenu[k].split(" ")[3].startsWith("0")) {//份数以0开头 System.out.println("wrong format"); System.exit(0); } record.setNum(Integer.parseInt(ordermenu[k].split(" ")[3]));//份数 // order.addARecord(record.getOrderNum(), record.getD().getName(), // record.getPortion(), record.getNum()); if (record.numValidity(record.getNum()) == 0) { System.out.println(record.getOrderNum() + " num out of range " + record.getNum()); }//份数合法性 if (record.portionValidity(record.getPortion()) == 0) { System.out.println(record.getOrderNum() + " portion out of range " + record.getPortion()); }//份额数据合法性????? if (record.numValidity(record.getNum()) == 1 && record.portionValidity(record.getPortion()) == 1) { System.out.println(record.getOrderNum() + " " + record.getD().getName() + " " + record.getD().getUnit_price() * record.getNum()); } }//输入的是菜谱里有的菜 else { System.out.println("wrong format"); System.exit(0); }//————应该只输出wrongformat if (ordermenu[k].split(" ")[0].equals("end")) { break; } } } System.out.printf("table %d: %d %.0f", table.getTable(), order.getTotalPrice(time), order.getTotalPrice(time) * time.TimeCount(time.getTime(), dish)); } } static class LocalDate { private Date date = new Date();//eg.2023/15/16 //private String date; Date date1 = new Date(2022, 1,1); Date date2 = new Date(2023,12,31); public LocalDate() { // TODO Auto-generated constructor stub } public void LocalDate(Date date) { this.date = date; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public boolean dateValidity(Date date) { if (date.after(date1) && date.before(date2)){ return true; } else { return false; } } public int transformWeekday(Date date) {//日期转换为周几 int[] weekDays = {1, 2, 3, 4, 5, 6, 7}; Calendar cal = Calendar.getInstance(); cal.setTime(date); int weekday = cal.get(Calendar.DAY_OF_WEEK) - 1; if (weekday < 0){ weekday = 0; } return weekDays[weekday]; } } //菜品类:对应菜谱上一道菜的信息。 static class Dish { private String name;//菜品名称 private int unit_price; //单价 private String kind;//是否是特色菜 //Time time = new Time(); public Dish() { } public void Dish(String name, int unit_price) { this.name = name; this.unit_price = unit_price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getUnit_price() { return unit_price; } public void setUnit_price(int unit_price) { this.unit_price = unit_price; } public void setKind(String kind) { this.kind = kind; } public String getKind() { return kind; } public int getPrice(int portion) {//一个菜确定大小和时间后的单价 if(portion == 2) { unit_price = (int) (Math.ceil(unit_price * 1.5)); } else if(portion == 3) { unit_price = (int) (Math.ceil(unit_price * 2.0)); } return unit_price; }//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) public boolean priceValidity(int unit_price) { if (unit_price <= 0 || unit_price >= 300) { return false; } else return true; } } //菜谱类:对应菜谱,包含饭店提供的所有菜的信息。 static class Menu { //Dish[] dish; private ArrayList<Dish> dishs = new ArrayList<Dish>();//菜品数组,保存所有菜品信息 public Menu() { } public void Menu(ArrayList dishs) { this.dishs = dishs; } public ArrayList getDishs() { return dishs; } public void setDishs(ArrayList dishs) { this.dishs = dishs; } public Dish addDish(String dishName, int unit_price, String kind) { Dish dishsNew = new Dish(); dishsNew.setName(dishName); dishsNew.setUnit_price(unit_price); dishsNew.setKind(kind); dishs.add(dishsNew); return dishsNew; }//添加一道菜品信息 public Dish searchDish(String dishName) {//比较字符串 Dish dishSearched = new Dish(); for (int i = 0; i < dishs.size(); i ++){ if (dishName.equals(dishs.get(i).getName())) { dishSearched.setName(dishName); dishSearched.setKind(dishs.get(i).getKind()); dishSearched.setUnit_price(dishs.get(i).getUnit_price()); break; } } return dishSearched; }//根据菜名在菜谱中查找菜品信息,返回Dish对象。 } //点菜记录类:保存订单上的一道菜品记录 static class Record { private int orderNum;//序号 public int num;//份数 private Dish d = new Dish();//菜品 private int portion;//份额(1/2/3代表小/中/大份) public Record(){ } public void Record(int orderNum, int num, Dish d, int portion) { this.d = d; this.num = num; this.portion = portion; this.orderNum = orderNum; } public Dish getD() { return d; } public void setD(Dish d) { this.d = d; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public int getOrderNum() { return orderNum; } public void setOrderNum(int orderNum) { this.orderNum = orderNum; } public int getPortion() { return portion; } public void setPortion(int portion) { this.portion = portion; } public int getPrice() { return d.getPrice(portion); }//计价,计算本条记录的价格//份额后价格 public int numValidity(int num) {//份数合法 if(num > 15 || num < 0){ return 0; } return 1; } public int portionValidity(int portion, Dish d) { if (d.getKind().equals("T") && (portion == 1 || portion == 3)) { return 1; } else if((portion < 1 || portion > 3) && portion <= 9) { return 0; } else if(portion > 9) { return -1; } return 1; } } // 订单类:保存用户点的所有菜的信息。 static class Order { //Record[] records; private ArrayList<Record> records = new ArrayList<Record>();//保存订单上每一道的记录 //HashMap<Integer, Integer, Dish, Integer> records = new HashMap<>(); Menu menu = new Menu(); Dish dish = new Dish(); public Order() { } public void Order(ArrayList records) { this.records = records; } public ArrayList getRecords() { return records; } public void setRecords(ArrayList records) { this.records = records; } public int getTotalPrice(Time time) { double totalprice = 0; int total; int size = records.size(); for (int i = 0; i < size; i++) { totalprice = totalprice + records.get(i).getPrice() * time.TimeDishCount(time.getTime(), records.get(i).getD()); } total = (int) totalprice; return total; }//计算订单的总价 public Record addARecord(int orderNum, String dishName, int portion, int num) { Record recordNew = new Record(); recordNew.setOrderNum(orderNum); recordNew.setD(menu.searchDish(dishName)); recordNew.setPortion(portion); recordNew.setNum(num); records.add(recordNew); return null; }//添加一条菜品信息到订单中。 public void delARecordByOrderNum(int orderNum) { Record recordNew = new Record(); for(int i = 0; i < records.size(); i ++) { if (orderNum == records.get(i).getOrderNum()) { recordNew = records.get(i); } } records.remove(recordNew); }//根据序号删除一条记录 public boolean findRecordByNum(int orderNum) { //或者遍历数组找有没有orderNum boolean flag = false; for(int i = 0; i < records.size(); i ++) { if (orderNum == records.get(i).getOrderNum()) { flag = true; } } return flag; }//根据序号查找一条记录; } static class Table { int table; public Table() { } public void Table() { this.table = table; } public int getTable() { return table; } public void setTable(int table) { this.table = table; } public int tableValidity(int table) { if(table < 1 || table > 55){ return 0; } return 1; } } static class Time { private String time; Dish dish = new Dish(); public Time() { } public Dish getDish() { return dish; } public void setDish(Dish dish) { this.dish = dish; } public void Time() { this.time = time; } public void setTime(String time) { this.time = time; } public String getTime() { return time; } public boolean TimeValidity(String time) { String[] times = time.split("/"); LocalDate localDate = new LocalDate(); if ((localDate.transformWeekday(localDate.getDate()) >= 1 && localDate.transformWeekday(localDate.getDate()) <= 5) && ((Integer.parseInt(times[0]) == 10 && Integer.parseInt(times[1]) >= 30) || (Integer.parseInt(times[0]) > 10 && Integer.parseInt(times[0]) < 14) || (Integer.parseInt(times[1]) <= 30) && Integer.parseInt(times[0]) == 14)) { return true; }//周一至周五中午,六折 else if ((localDate.transformWeekday(localDate.getDate()) >= 1 && localDate.transformWeekday(localDate.getDate()) <= 5) && ((Integer.parseInt(times[0]) >= 17 && Integer.parseInt(times[0]) < 20) || (Integer.parseInt(times[0]) == 20 && Integer.parseInt(times[1]) <= 30))) { return true; }//周一至周五晚上,八折 else if ((localDate.transformWeekday(localDate.getDate()) >= 6) && ((Integer.parseInt(times[0]) == 9 && Integer.parseInt(times[1]) >= 30) || (Integer.parseInt(times[0]) > 9 && Integer.parseInt(times[0]) < 21) || (Integer.parseInt(times[0]) == 21 && Integer.parseInt(times[1]) <= 30))) { return true; }//周末营业时间,全价 else return false; } public double TimeDishCount(String time, Dish dish) { String[] times = time.split("/"); LocalDate localDate = new LocalDate(); if ((localDate.transformWeekday(localDate.getDate()) >= 1 && localDate.transformWeekday(localDate.getDate()) <= 5) && ((Integer.parseInt(times[0]) == 10 && Integer.parseInt(times[1]) >= 30) || (Integer.parseInt(times[0]) > 10 && Integer.parseInt(times[0]) < 14) || (Integer.parseInt(times[1]) <= 30) && Integer.parseInt(times[0]) == 14)) { if (dish.getKind().equals("T")) { return 0.7; } else return 1; }//周一至周五 else if (((localDate.transformWeekday(localDate.getDate()) >= 1) && (localDate.transformWeekday(localDate.getDate()) <= 5)) && (((Integer.parseInt(times[0]) >= 17) && (Integer.parseInt(times[0]) < 20)) || ((Integer.parseInt(times[0]) == 20) && (Integer.parseInt(times[1]) <= 30)))) { if (dish.getKind().equals("T")) { return 0.7; } else return 1; }//周一至周五晚上,八折 else if ((localDate.transformWeekday(localDate.getDate()) >= 6) && ((Integer.parseInt(times[0]) == 9 && Integer.parseInt(times[1]) >= 30) || (Integer.parseInt(times[0]) > 9 && Integer.parseInt(times[0]) < 21) || (Integer.parseInt(times[0]) == 21 && Integer.parseInt(times[1]) <= 30))) { return 1.0; }//周末营业时间,全价 else return 0; } } }
分析:
首先结果是,这个题笔者没写出来,不是态度问题是能力问题的,写不出来。
按标准流程走,拿到题目先分析出有哪些类以及各类属性和方法,再明确类间关系,依照类图搭起框架后,开始填空。
基于题给类,笔者另外加了Date日期类、Time时间类、Table桌号类,Date方法有判断日期有效性等,Time属性为二十四时制时间,用于计算菜品折后价格,Table属性即为桌号。以及其他类属性方法的调整,如Record类增加num份数属性、判断桌号是否存在等。
Date类中日期有效性方法,一开始的思路是字符串切割转整型数据比大小,写了两行想起来Java有Date类可以直接用啊,遂改了date的数据类型用之。Time类没有工具包可以直接用,遂传统写之,切割字符串等。方法中,由于数据判断的输出不同,把如份额合法性由boolean改为int属性,按照返回值的不同处理输出数据越界但继续程序,还是数据有误直接终止程序。
输入,个人认为是这个题最难写的地方。存入数组再一句一句取出判断,输出有及时输出和末尾集中输出两种模式,笔者用得来的是前者。同学有提醒说不集中输出的话会有几个测试点过不了……感谢但是根本写不到那些测试点……同样被这位提醒的分割字符串要用正则而不是split,七个题目给出的输入样例都过不完……写得挺绝望的就是说。这题报错给的多是数组越界、返回为空、字符串数组某一位为空。数组越界笔者盘出来是循环没写好的问题,但是根据每次测试结果又debug去改循环,新改新错……返回为空,debug没de出来,调整了方法中的属性也一样,最后是输出试试发现啊循环没写好根本没存进去返回当然空……数组为空加个判断就好。
输出,就那位同学的建议,应该是集中输出更合理。方法大概是循环判断叠叠乐,在每句的判断int或Boolean赋值。没写出来,点烟。
小结,这题没写出来暴露的问题,笔者体无完肤。笔者的错,笔者会改,笔者会努力。
踩坑心得:
首先值得乐观的是BLOG1里提及的毛病在这三次作业里都有效规避了。
题目集四:
7-2和7-3两个涉及重复数据的问题一开始都暴力塞俩循环,编译器运行正常PTA测试超时,查查别的处理字符串数组的方法好HashSet和LinkedHashSet,要用才学所以这两个工具目前我只会用它们来处理字符串重复数据。7-4Iterator和MyComparator也一样,普通String[]不行所以要用才学且学得不多。7-5和7-6看着吓人写起来简单,没大问题。
题目集五:
很蠢的读题错误,7-3看着好写一顿写提交才发现啊要求正则表达式好吧这题零分。7-1、7-3、7-4都是正则表达式训练,属于不难但是很烦的范畴,几乎全是记忆性的知识,写的时候对着表格盘了两下再写其实还好,但是把这个表格拿走就完个大蛋……得背。56前文已述。
字符串做法
题目集六:
0671前文已书,不加赘述。
改进建议:
尽量早尽量快地开始题目集……永远不会知道下一个bug会出现在哪里也永远发现不了自己脑子的坑有多少,笨鸟先飞,有道理的。
对于代码的迭代,比起自己分析更多地是迭代系列的题目中学习(技术过于有限是这样……)日期题是结构迭代的典中典,笔者自己按类分析的话考虑出的结果是6而非5,算法迭代目前题目集中未有涉及,菜单题做过的34更多是功能的增加,笔者做不来的功能增加……
笨鸟先飞,笔者应该且将要做的。
总结:
对题目集:
先分两块讲,一是日期题二是菜单题。对于日期题踩坑主要是日期差的算法盘了几遍才盘清,没测出来的测试点反映的是笔者测试能力的缺陷。菜单题,结构自认为想得比较清楚,但是算法稀巴烂写不来其实也就是白搭,尤其老师说这玩意不难的时候笔者心如死灰……能力问题,在改。再来私以为写代码真的是很磨人的事情,给的测试用例过不去心态垮了一半就想和这两个死磕完全没心思去磨别的测试点,技术不行心态也不行,笔者的问题,会改在改。最后是老师课上提到题目集的难度会增加,秉持着努力争取坚忍不拔的精神,不太盲目地展望一下未来,会花更多时间会动更多脑子……能力不行真的难受……
学到的东西对于要学的来说,少的嘞。到底学到了点类间设计以及一些工具包的应用,正则表达式没能熟练使用,甚至只是粗浅地了解了一下,以后会多多使用。
还要学的部分,熟练使用正则表达式,菜单的处理,以及不要过度依赖编译器期末考只能用PTA,过度依赖编译器期末考不得完蛋……
对课程:
比较难的题目希望可以给一下提示或给一点参考,完全摸瞎自己写出来的可能性就笔者而言特别小,又如本次0671做出来的人……讨论空间也不大……
另:
辛苦阅读,耗子吃狗祝您生活愉快。
标签:06,04,int,PTA,getValue,getDay,value,return,public From: https://www.cnblogs.com/psychewind/p/17360603.html