oop训练集040506总结反思

wsq147 / 2023-05-03 / 原文

1.前言

(1)OOP训练集04:知识点主要是数据的处理、应用和输出,封装性的应用,日期类的应用,菜单题很考验对类如何进行合理的设计,题量有点多。我认为的重点是菜单题和两道对重复数据的处理,处理重复数据时运行超时是最头疼的。

(2)OOP训练集05:前四道有三道都是对正则表达式的考察,一道考察字符串的处理,剩下两道稍微有点难度,是之前的日期题的迭代,考察面向对象程序设计的聚合。我认为这次作业是没什么难度的,最后两道虽然比较长,但是有之前的基础,只是稍微有点花时间,还是写得出来的。

(3)OOP训练集06:只有一道菜单题,但是因为训练集04那道没写出来,了很久都没头绪,最后没在规定时间写出来。。。这道题进一步考察如何进行合理设计,需要考虑的点非常多

2.设计与分析

 

(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;
    }

}

(2)训练集05 7-6 日期问题面向对象设计(聚合二)

 我的思路: