(1)训练集04 7-4 单词统计与排序
我的思路:
拿到这道题最主要的是想怎么将输入的文本分割,卡在这一步卡了很久,不知道怎么才能除去文本中的“,”“.”" "把单词提取出来,后来想到先用replaceAll方法将,.换成空格,再利用split方法把文本拆分成没有空格的字符串数组。
接着按照题意利用for循环和if语句进行比较和交换顺序,最后利用列表输出,为了使重复单词只输出一次,创建新列表,如果列表中有要输出的单词,那就不输出,如果没有,输出并加入列表。
我的代码:
import java.util.ArrayList; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); String sentence = input.nextLine().replaceAll("[,.]","");//把所有的,和.换成空字符 String[] word = sentence.split(" ");//拆分成没有空格的字符串数组 String w; for(int i = 0;i < word.length;i++){ for(int j = 0;j < word.length-i-1;j++){ if(word[j].length()<word[j+1].length()){//如果前一个单词长度小于后一个 w = word[j]; word[j] = word[j+1]; word[j+1] = w;//交换 } else if (word[j].length() == word[j+1].length()) {//如果单词长度相等,比较字母 for(int m = 0;m < word[j].length();m++){ if(word[j].substring(m,m+1).compareToIgnoreCase(word[j+1].substring(m,m+1))>0){//如果字母前一个大于后一个 w = word[j]; word[j] = word[j+1]; word[j+1] = w;//交换 break; } else if (word[j].substring(m,m+1).compareToIgnoreCase(word[j+1].substring(m,m+1))<0) {//如果小于 break;//直接结束 } } } } } ArrayList<String> printWords = new ArrayList<>(); for (int i = 0; i < word.length; i++) { if(!printWords.contains(word[i])){//如果列表中不存在该元素 System.out.println(word[i]);//输出 printWords.add(word[i]);//将该元素加入列表 } } } }
(2)训练集05 日期问题面向对象设计(聚合一)
我的思路:
这道题是之前日期问题的迭代,观察类图后认为应该先从year类开始写,依次写Month,Day,DateUtil,Main类,内容和之前的题目是差不多的,只需要稍作调整修改,主要就是考察聚合。
我的代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int choice = input.nextInt();//输入选择 if(choice == 1){//选择1求下n天 int year = input.nextInt(); int month = input.nextInt(); int day = input.nextInt(); DateUtil date = new DateUtil(day, month, year);//输入年月日 int n = input.nextInt();//输入n if(n<0){ System.out.println("Wrong Format"); }else { if(date.checkInputValidity()){ System.out.println(date.getNextNDays(n).showDate());//求下n天 }else { System.out.println("Wrong Format"); } } } else if (choice == 2) {//选择2求前n天 int year = input.nextInt(); int month = input.nextInt(); int day = input.nextInt(); DateUtil date = new DateUtil(day, month, year);//输入年月日 int n = input.nextInt();//输入n if(n<0){ System.out.println("Wrong Format"); }else { if(date.checkInputValidity()){ System.out.println(date.getPreviousNDays(n).showDate());//求前n天 }else { System.out.println("Wrong Format"); } } } else if (choice == 3) {//选择3求两个日期相差天数 int year1 = input.nextInt(); int month1 = input.nextInt(); int day1 = input.nextInt(); int year2 = input.nextInt(); int month2 = input.nextInt(); int day2 = input.nextInt(); DateUtil date1 = new DateUtil(day1, month1, year1);//输入date1年月日 DateUtil date2 = new DateUtil(day2, month2, year2);//输入date2年月日 if(date1.checkInputValidity() && date2.checkInputValidity()){ System.out.println(date1.getDaysofDates(date2));//求相差天数 }else { System.out.println("Wrong Format"); } }else {//输入无效 System.out.println("Wrong Format"); } } } class DateUtil { private Day day; public DateUtil() { } public DateUtil(int d, int m, int y) { this.day = new Day(y,m,d); } public Day getDay() { return day; } public void setDay(Day d) { this.day = d; } //校验数据合法性 public boolean checkInputValidity(){ return day.getMonth().validate()&&day.validate()&&day.getMonth().getYear().validate();//年月日都合法返回true,否则返回false } //比较两个日期的大小,date1<date2返回true,反之返回false public boolean compareDates(DateUtil date){ if(day.getMonth().getYear().getValue() < date.getDay().getMonth().getYear().getValue()){//date1年小于date2年 return true; } else if (day.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()&& day.getMonth().getValue() < date.getDay().getMonth().getValue()) {//年相同但date1月更小 return true; } else return day.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue() && day.getMonth().getValue() == date.getDay().getMonth().getValue() && day.getValue() < date.getDay().getValue();//年月相同但date1日更小 } //判定两个日期是否相等 public boolean equalTwoDates(DateUtil date){ return day.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()&& day.getMonth().getValue() == date.getDay().getMonth().getValue() && day.getValue()==date.getDay().getValue();//年月日都相同 } //日期格式化 public String showDate(){ return day.getMonth().getYear().getValue()+"-"+day.getMonth().getValue()+"-"+day.getValue(); } //求下n天 public DateUtil getNextNDays(int n){ while(n>365){ if(day.getMonth().getYear().isLeapYear()){ n=n-365; day.getMonth().getYear().yearIncrement(); } else{ n=n-366; day.getMonth().getYear().yearIncrement(); } } for (int i = 1; i<=n; i++) { if (day.getMonth().getValue() == 12 && day.getValue() == 31) {//一年的最后一天 day.getMonth().getYear().yearIncrement(); day.getMonth().resetMin(); day.resetMin(); } else if (day.getValue() == day.getMon_maxnum()) {//每月最后一天 day.getMonth().monthIncrement(); day.resetMin(); } else {//其它的日期 day.dayIncrement(); } } showDate(); return new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue()); } //求前n天 public DateUtil getPreviousNDays(int n){ while(n>365){ if(day.getMonth().getYear().isLeapYear()){ n=n-365; day.getMonth().getYear().yearReduction(); } else{ n=n-366; day.getMonth().getYear().yearReduction(); } } for (int i = 1; i<=n; i++) { if (day.getMonth().getValue() == 1 && day.getValue() == 1) {//一年的第一天 day.getMonth().getYear().yearReduction(); day.getMonth().resetMax(); day.resetMax(); } else if (day.getValue() == 1) {//每月第一天 day.getMonth().monthReduction(); day.resetMax(); } else {//其它的日期 day.dayReduction(); } } showDate(); return new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue()); } //求两个日期之间的天数 public int getDaysofDates(DateUtil date){ int n=0;//相差的天数 if(equalTwoDates(date)){//相等 return n; } else if (compareDates(date)) {//date1<date2 while(!equalTwoDates(date)){ if(day.getMonth().getValue() == 12 && day.getValue() == 31){//一年的最后一天 day.getMonth().getYear().yearIncrement(); day.getMonth().resetMin(); day.resetMin(); }else if(day.getValue() == day.getMon_maxnum()) {//每月最后一天 day.getMonth().monthIncrement(); day.resetMin(); }else {//其他的日期 day.dayIncrement(); } n++; } return n; } else{//当前天数>date while(!equalTwoDates(date)){ if (day.getMonth().getValue() == 1 && day.getValue() == 1) {//一年的第一天 day.getMonth().getYear().yearReduction(); day.getMonth().resetMax(); day.resetMax(); } else if (day.getValue() == 1) {//每月第一天 day.getMonth().monthReduction(); day.resetMax(); } else {//其它的日期 day.dayReduction(); } n++; } return n; } } } 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.value = dayValue; this.month = new Month(yearValue,monthValue); } 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; } public int getMon_maxnum(){ if(!month.getYear().isLeapYear()){//如果是闰年 mon_maxnum[1] = 29;//2月最大日期改为29 }else { mon_maxnum[1] = 28;//否则2月还是28天 } return mon_maxnum[month.getValue()-1]; } //日期复位(1) public void resetMin(){ value = 1; } //日期设为该月最大值 public void resetMax(){ value = getMon_maxnum(); } //校验数据合法性 public boolean validate(){ return value >= 1 && value <= getMon_maxnum();//合法返回true,不合法返回false } //日期增1 public void dayIncrement(){ value = value + 1; } //日期减1 public void dayReduction(){ value = value - 1; } } 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(){ return value>=1&&value<=12;//合法返回true,不合法返回false } //月份增1 public void monthIncrement(){ value = value + 1; } //月份减1 public void monthReduction(){ value = value - 1; } } class Year { private int year; public Year() { } public Year(int value) { this.year = value; } public int getValue() { return year; } public void setValue(int value) { this.year = value; } //判断是否为闰年 boolean isLeapYear(){ return !(year % 4 == 0 && year % 100 != 0 || year % 400 == 0);//是平年返回true,不是平年返回false } //检验数据合法性 boolean validate(){ return year>=1900&&year<=2050;//合法返回true,不合法返回false } //年份增1 void yearIncrement(){ year = year + 1; } //年份减1 void yearReduction(){ year = year - 1; } }
(3)训练集05 7-6 日期问题面向对象设计(聚合二)
我的思路:
这道题是之前日期题的另一种迭代,另一种聚合方式,Year,Month,Day类在这里是一种“平级关系",按照类图来写也很容易,先把Day,Month,Year类写好,再将其它补充完整,依然可以直接复制之前的代码。
我的代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int choice = input.nextInt();//输入选择 if(choice == 1){//选择1求下n天 int year = input.nextInt(); int month = input.nextInt(); int day = input.nextInt(); DateUtil date = new DateUtil(new Year(year), new Month(month), new Day(day));//输入年月日 int n = input.nextInt();//输入n if(n<0){ System.out.println("Wrong Format"); }else { if(date.checkInputValidity()){ System.out.println(year+"-"+month+"-"+day+" next "+n+" days is:"+date.getNextNDays(n).showDate());//求下n天 }else { System.out.println("Wrong Format"); } } } else if (choice == 2) {//选择2求前n天 int year = input.nextInt(); int month = input.nextInt(); int day = input.nextInt(); DateUtil date = new DateUtil(new Year(year), new Month(month), new Day(day));//输入年月日 int n = input.nextInt();//输入n if(n<0){ System.out.println("Wrong Format"); }else { if(date.checkInputValidity()){ System.out.println(year+"-"+month+"-"+day+" previous "+n+" days is:"+date.getPreviousNDays(n).showDate());//求前n天 }else { System.out.println("Wrong Format"); } } } else if (choice == 3) {//选择3求两个日期相差天数 int year1 = input.nextInt(); int month1 = input.nextInt(); int day1 = input.nextInt(); int year2 = input.nextInt(); int month2 = input.nextInt(); int day2 = input.nextInt(); DateUtil date1 = new DateUtil(new Year(year1), new Month(month1), new Day(day1));//输入date1年月日 DateUtil date2 = new DateUtil(new Year(year2), new Month(month2), new Day(day2));//输入date2年月日 if(date1.checkInputValidity() && date2.checkInputValidity()){ System.out.println("The days between "+year1+"-"+month1+"-"+day1+" and "+year2+"-"+month2+"-"+day2+" are:" +date1.getDaysofDates(date2));//求相差天数 }else { System.out.println("Wrong Format"); } }else {//输入无效 System.out.println("Wrong Format"); } } } class DateUtil { private Year year; private 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(Year year, Month month, Day day) { this.year = year; this.month = month; this.day = day; } 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 int[] getMon_maxnum() { if(!year.isLeapYear()){//如果是闰年,2月改为29天,否则不变 mon_maxnum[1] = 29; }else { mon_maxnum[1] = 28; } return mon_maxnum; } //设置日期最小值(1) public void setDayMin(){ day.setValue(1); } //设置日期最大值(当月最大天数) public void setDayMax(){ day.setValue(getMon_maxnum()[month.getValue()-1]); } //校验输入数据合法性 public boolean checkInputValidity(){ return month.validate() && day.getValue() >= 1 && day.getValue() <= getMon_maxnum()[month.getValue()-1] && year.validate(); } //求下n天 public DateUtil getNextNDays(int n){ while(n>365){ if(year.isLeapYear()){ n=n-365; year.yearIncrement(); } else{ n=n-366; year.yearIncrement(); } } for (int i = 1; i<=n; i++) { if (month.getValue() == 12 && day.getValue() == 31) {//一年的最后一天 year.yearIncrement(); month.resetMin(); setDayMin(); } else if (day.getValue() == getMon_maxnum()[month.getValue()-1]) {//每月最后一天 month.monthIncrement(); setDayMin(); } else {//其它的日期 day.dayIncrement(); } } showDate(); return new DateUtil(year,month,day); } //求前n天 public DateUtil getPreviousNDays(int n){ while(n>365){ if(year.isLeapYear()){ n=n-365; year.yearReduction(); } else{ n=n-366; year.yearReduction(); } } for (int i = 1; i<=n; i++) { if (month.getValue() == 1 && day.getValue() == 1) {//一年的第一天 year.yearReduction(); month.resetMax(); setDayMax(); } else if (day.getValue() == 1) {//每月第一天 month.monthReduction(); setDayMax(); } else {//其它的日期 day.dayReduction(); } } showDate(); return new DateUtil(year,month,day); } //判定两个日期的先后,date1<date2返回true,反之返回false public boolean compareDates(DateUtil date){ if(year.getValue() < date.year.getValue()){//date1年小于date2年 return true; } else if (year.getValue() == date.year.getValue()&& month.getValue() < date.month.getValue()) {//年相同但date1月更小 return true; } else return year.getValue() == date.year.getValue() && month.getValue() == date.month.getValue() && day.getValue() < date.getDay().getValue();//年月相同但date1日更小 } //判定两个日期是否相等 public boolean equalTwoDates(DateUtil date){ return year.getValue() == date.year.getValue() && month.getValue() == date.month.getValue() && day.getValue() == date.getDay().getValue();//年月日都相同 } //求两个日期的天数差 public int getDaysofDates(DateUtil date){ int n=0;//相差的天数 if(equalTwoDates(date)){//相等 return n; } else if (compareDates(date)) {//date1<date2 while(!equalTwoDates(date)){ if(month.getValue() == 12 && day.getValue() == 31){//一年的最后一天 year.yearIncrement(); month.resetMin(); setDayMin(); }else if(day.getValue() == getMon_maxnum()[month.getValue()-1]) {//每月最后一天 month.monthIncrement(); setDayMin(); }else {//其他的日期 day.dayIncrement(); } n++; } return n; } else{//当前天数>date while(!equalTwoDates(date)){ if (month.getValue() == 1 && day.getValue() == 1) {//一年的第一天 year.yearReduction(); month.resetMax(); setDayMax(); } else if (day.getValue() == 1) {//每月第一天 month.monthReduction(); setDayMax(); } else {//其它的日期 day.dayReduction(); } n++; } return n; } } //日期按“年-月-日”格式化 public String showDate(){ return year.getValue()+"-"+month.getValue()+"-"+day.getValue(); } } 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(){ return !(value % 4 == 0 && value % 100 != 0 || value % 400 == 0);//平年返回true,闰年返回false } //数据合法性校验 public boolean validate(){ return value >= 1820 && value <= 2020; } //年增1 public void yearIncrement(){ value = value + 1; } //年减1 public void yearReduction(){ value = value - 1; } } 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(){ return value >= 1 && value <= 12; } //月增1 public void monthIncrement(){ value = value + 1; } //月减1 public void monthReduction(){ value = value - 1; } } class Day { private int value; 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 dayIncrement(){ value = value + 1; } //日减1 public void dayReduction(){ value = value - 1; } }
(4)训练集04 7-1,训练集06 7-1
由于我的拖延没能写完菜单题我深感愧疚,在此先分析我目前已有的思路,完成菜单题后我将会重新编辑这个博客(虽然也不知道对没对就是了。。)
我的思路:
首先要考虑是怎么把输入的一大串字符串按照需求分开,思考过后认为要用正则表达式来实现。然后开始画类图,除了题中给的几个类,另外我加上了Table类,根据题目要求,属性有桌号、用餐时间、点菜记录、代点菜信息、删除信息。还加上Time类,属性有calendar。这几个类用来进行输入信息的储存,另外还要有类来判断各种情况,从而进行输出。在写的过程中发现Menu类中的属性和方法可以用static进行修饰,因为在一次输入中,菜单是共有的。
点菜信息的储存用的是列表,因为并不能确定输入的点菜信息数量,也方便后面删除信息,储存是直接按照输入的序号进行储存。
这道题我写的很没有计划,我拿到这道题时我不知道该从哪里开始,在画类图的时候犹豫了很久,类与类之间的关系判断不出来,于是就一直卡着,后来按照一个暂定的类图开始写,但还是没有什么思路。
代码是半成品,就不展示了。
(1)首先是训练集04的7-2和7-3两道对重复数据的处理
我的做法:
这样写是能够得出结果的,但是当输入大量数据时会运行超时,每次作业有关这种需要对循环进行改进的题目我都写不来。。
(2)
训练集05中的7-5 7-6 判断日期合法性会出现问题,由于&&会按顺序进行判断,而且在day的判断中用到了每月最大天数的数组,如果先判断day,当输入的月份超过12,数组会超限,所以要先判断月份,当月份超过12时,会直接返回false。
要找到一个能够优化循环的方法,来应对大量数据的处理。最重要的是菜单题,在写的过程中我感觉到我的类图是有问题的,而且没有符合一些设计原则,菜单题不仅要写完,还要改进。
5.总结
这三次作业与上三次作业对比难度升了很多,不再是单纯java语法的应用,更需要自己去学会合理设计类,没能写出菜单题我很愧疚也很遗憾,我认为那是一道很具挑战性的题目,如果能够成功写出来会很有成就感。当然我不打算放弃,我会把菜单题写出来。但我有一个建议,下次这样的迭代的题目还是希望可以从最初的最简单的开始,我们的菜单题是直接从3开始的,如果写过1和2,应该会更有思路吧。