PTA实验4~6分析及总结

LiuLile / 2023-05-03 / 原文

1.前言

      这是我们第二次的pta作业总结,这次主要是在上次作业的基础上加大了难度,考验了我们的编写代码能力和自主学习能力,考察了我们正则表达式训练,有参无参构造方法,(面对对象编程)(封装性)私有属性的表示和get,set方法的运用,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。这几次的作业其他的都还好,只有菜单计价程序这一题比较难,加上时间就比较紧张,导致最后我还是没有写出来这道题目。

2.设计与分析

第四次oop训练:

7-2 有重复的数据

   这一题没什么很大问题,主要是如果使用两个if语句来循环的话,速度太慢,达不到题目的需求,没办法得到全对,所以通过上网查阅资料了解到可以用HashSet方法来解决两个if 语句运行太慢的问题

具体代码如下所示

import java.util.*;
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
     Scanner input = new Scanner(System.in);
     int nember = input.nextInt();
     input.nextLine();
     String str = input.nextLine();
     String[] quantity = str.split(" ");
     HashSet<Integer> hs = new HashSet<Integer>();
     for (int i=0; i<nember; i++) {
            hs.add(Integer.parseInt(quantity[i]));
        }
     if (hs.size() == nember) 
            System.out.println("NO");
     else 
            System.out.println("YES");
     
    }
}

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

 这一题没什么很大难度主要是考察我们的自主学习和理解的能力,通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。很容易写出这道题目。注意一下输入和输出的格式问题就好了。

具体代码实现如下:

import java.util.*;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;


public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        String date1 = in.nextLine();
        String date2 = in.nextLine();
        int[] Newdate1 = new int[3];
        int[] Newdate2 = new int[3];
        String[] newdate1 = date1.split("-");
        String[] newdate2 = date2.split("-");
        for(int i = 0;i < 3;i++) {
            Newdate1[i] = Integer.parseInt(newdate1[i]);
        }
        LocalDateTime Date1 = LocalDateTime.of(Newdate1[0],Newdate1[1],Newdate1[2],0,0,0);
        for(int i = 0;i < 3;i++) {
            Newdate2[i] = Integer.parseInt(newdate2[i]);
        }
        LocalDateTime Date2 = LocalDateTime.of(Newdate2[0],Newdate2[1],Newdate2[2],0,0,0);

        if(Date1.isBefore(Date2)){
            System.out.println("第一个日期比第二个日期更早");
            System.out.println("两个日期间隔" + ChronoUnit.DAYS.between(Date1,Date2) + "天");
            System.out.println("两个日期间隔" + ChronoUnit.WEEKS.between(Date1,Date2) + "周");
        }
        else if(Date1.isAfter(Date2)){
            System.out.println("第一个日期比第二个日期更晚");
            System.out.println("两个日期间隔" + ChronoUnit.DAYS.between(Date2,Date1) + "天");
            System.out.println("两个日期间隔" + ChronoUnit.WEEKS.between(Date2,Date1) + "周");
        }
        
    }

}

 

第五次oop训练:

这一次的作业主要考察的是我们正则表达式的运用,正则表达式号称代码界的莫斯密码,刚开始理解的时候有点困难,通过请教同学后正确理解了正则表达的正确用法。

7-2 字符串训练-字符排序

 这题需要按ASCII码进行升序排序输出,没什么比较特殊的地方,这里直接附上源码:

import java.util.Scanner;
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        
        String a = in.next();
        
        int l = a.length();
        
        char[] n = new char[l];
        
        for(int i = 0;i<l;i++) {
            n[i] = a.charAt(i);
        }
 
        for(int i = 0;i<l-1;i++) {
            for(int j = i+1;j<l;j++) {
                if(n[i]>n[j]) {
                    char t = n[i];
                    n[i] = n[j];
                    n[j] = t;
                }
            }
        }
        
        System.out.print(n);
    
    }

}

7-4 正则表达式训练-学号校验

 这是这次作业中正则表达式最难的题目,考验了我们对正则表达式的掌握与理解运用,其实理解了正则表达式的具体原理之后,这一题非常简单。

具体代码如下:

import java.util.Scanner;
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        if(s.matches("^2020([1][1-7]|61|[7][1-3]|[8][1-2])([0][1-9]|[1-3][0-9]|40)$")) {
            System.out.println( "正确");
        }
        else {
            System.out.println( "错误");
        }

    }

}

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

从这一题开始作业开始变得有难度,代码量也变得越来越多,题目越来越长,理解起来越困难,测试点也很多,需要我们花大把的时间和精力投入上去。

 这题给了类图,属性和方法名都给了,按照上面的和上次的日期类的基础上进行修改就好了,主要是代码量比较大。

具体代码如下:

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;

        int choice = input.nextInt();

        if (choice == 1) { // test getNextNDays method
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

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

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

            m = input.nextInt();

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

            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { // test getPreviousNDays method
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

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

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

            n = input.nextInt();

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

            System.out.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;

    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 (this.value%400 == 0|| (this.value%4 == 0 && this.value%100 != 0)) {
            return true;
        } else {
            return false;
        }
    }

    public boolean validate() {
        if (this.value > 2050 || this.value < 1900) {
            return false;
        } else {
            return true;
        }
    }

    public void yearIncrement() {
        this.value = this.value + 1;
    }

    public void yearReduction() {
        this.value = this.value - 1;
    }

}


class Month {
    private int value;
    private Year year = new Year();

    public Month() {

    }

    public Month(int yearValue, int montnValue) {
        this.year = new Year(yearValue);
        this.setValue(montnValue);
    }

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

    public void resetMin() {
        this.setValue(1);
    }

    public void resetMax() {
        this.setValue(12);
    }

    public boolean validate () {
        if (this.value > 12 || this.value < 1) {
            return false;
        } else {
            return true;
        }
    }

    public void monthIncrement() {
        if (this.validate()) {
           if (this.value == 12) {
               this.resetMin();
               this.year.yearIncrement();
           } else {
               this.value++;
           }
        }
    }

    public void monthReduction() {
        if (this.validate()) {
            if (this.value == 1) {
                this.resetMax();
                this.year.yearReduction();
            } else {
                this.value--;
            }

        }
    }

}


class Day {
    private int value;
    private Month month = new 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.getMonth().getYear().setValue(yearValue);;
        this.getMonth().setValue(monthValue);
        this.setValue(dayValue);
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public Month getMonth() {
        return month;
    }

    public void setMonth(Month value) {
        this.month = value;
    }

    public void resetMin() {
        this.value = 1;
    }

    public void resetMax() {
        int maxNum = this.mon_maxnum[this.month.getValue() - 1];
        if (this.getMonth().getYear().isLeapYear() && this.month.getValue() == 2) {
            maxNum = 29;
        }
        this.value = maxNum;
    }

    public boolean validate() {
        int maxNum = this.mon_maxnum[this.month.getValue() - 1];
        if (this.getMonth().getYear().isLeapYear() && this.month.getValue() == 2) {
            maxNum = 29;
        }
        if (this.value > 0 && this.value <= maxNum) {
            return true;
        } else {
            return false;
        }
    }

    public void dayIncrement() {
        int maxNum = this.mon_maxnum[this.month.getValue() - 1];
        if (this.getMonth().getYear().isLeapYear() && this.month.getValue() == 2) {
            maxNum = 29;
        }
        if (this.validate()) {
            if (this.value == maxNum) {
                this.month.monthIncrement();
                this.resetMin();
            } else {
                this.value++;
            }
        }

    }

    public void dayRuduction() {
        if (this.validate()) {
            if (this.value == 1) {
                this.month.monthReduction();
                this.resetMax();
            } else {
                this.value--;
            }

        }
    }

}


class DateUtil {
    private Day day = new Day();

    public DateUtil() {

    }

    public DateUtil(int yearValue, int monthValue, int dayValue) {
        this.day = new Day(yearValue, monthValue, dayValue );
    }

    public Day getDay() {
        return day;
    }

    public void setDay(Day d) {
        this.day = d;
    }

    public boolean checkInputValidity() {
        if (!this.getDay().getMonth().validate()) return false;
        if (this.getDay().validate()
            && this.getDay().getMonth().getYear().validate()) {
            return true;
        } else {
            return false;
        }

    }

    public boolean compareDates(DateUtil date) {
        if (this.getDay().getMonth().getYear().getValue()
                > date.getDay().getMonth().getYear().getValue()) {
            return true;
        } else if (this.getDay().getMonth().getYear().getValue()
                == date.getDay().getMonth().getYear().getValue()
                && this.getDay().getMonth().getValue() > date.getDay().getMonth().getValue()) {
            return true;
        } else if (this.getDay().getMonth().getYear().getValue()
                == date.getDay().getMonth().getYear().getValue()
                && this.getDay().getMonth().getValue() == date.getDay().getMonth().getValue()
                && this.getDay().getValue() > date.getDay().getValue()) {
            return true;
        } else {
            return false;
        }

    }

    public boolean equalTwoDates(DateUtil date) {
        if (this.getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()
            && this.getDay().getMonth().getValue() == date.getDay().getMonth().getValue()
            && this.getDay().getValue() == date.getDay().getValue()) {
            return true;
        } else {
            return false;
        }
    }

    public String showDate() {
        return String.format("%d-%d-%d",this.getDay().getMonth().getYear().getValue(),
                this.getDay().getMonth().getValue(),this.getDay().getValue() );
    }

    public DateUtil getNextNDays(int n) {
        for (int i = 0; i < n; i++) {
            this.day.dayIncrement();
        }
       return this;
    }

    public DateUtil getPreviousNDays(int n) {
        for (int i = 0; i < n; i++) {
            this.day.dayRuduction();
        }
       return this;

    }

    public int getDaysofDates(DateUtil date) {
        int daysBetween=0;
        int[]mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        int yearSum=0;
        int monthSum1=0;
        int monthSum2=0;

        DateUtil dateChange = new DateUtil();


        if(this.getDay().getMonth().getYear().getValue()
                > date.getDay().getMonth().getYear().getValue()) {
            dateChange.getDay().getMonth().getYear().setValue(date.getDay().getMonth().getYear().getValue());
            date.getDay().getMonth().getYear().setValue(this.getDay().getMonth().getYear().getValue());
            this.getDay().getMonth().getYear().setValue(dateChange.getDay().getMonth().getYear().getValue());
        }
        for(int i = this.getDay().getMonth().getYear().getValue(); i < date.getDay().getMonth().getYear().getValue(); i++) {
            dateChange.getDay().getMonth().getYear().setValue(i);
            if(dateChange.getDay().getMonth().getYear().isLeapYear()) {
                yearSum += 366;
            }
            else {
                yearSum += 365;
            }
        }
        for(int i = 1; i < this.getDay().getMonth().getValue(); i++) {
            monthSum1 += mon_maxnum[i];
        }
        if(this.getDay().getMonth().getYear().isLeapYear()
                && this.getDay().getMonth().getValue() > 2) {
            monthSum1++;
        }
        for(int i = 1; i < date.getDay().getMonth().getValue(); i++) {
            monthSum2 += mon_maxnum[i];
        }
        if(date.getDay().getMonth().getYear().isLeapYear()
                && date.getDay().getMonth().getValue() > 2) {
            monthSum2++;
        }

        daysBetween = yearSum + monthSum2 + date.getDay().getValue() - monthSum1 - this.getDay().getValue();
        return daysBetween;

    }


}

 

 

第六次oop训练:

主要涉及的知识点是类的设计和类与类的关系处理。题量只有一题,但难度较大,预计代码行数1000+,需用时20h+。我光是理解题目便花了一个多小时,后面因为时间和能力问题没有写出来。只写出来几个类,这里就不现丑了。

3.踩坑心得

有的时候用for循环非常慢,有的测试点过不了,这个时候要学着用点其他方法解决,如7-2有重复数据,

这是用for语句的时候

 下面为用hashset之后的改进代码:

import java.util.*;
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
     Scanner input = new Scanner(System.in);
     int nember = input.nextInt();
     input.nextLine();
     String str = input.nextLine();
     String[] quantity = str.split(" ");
     HashSet<Integer> hs = new HashSet<Integer>();
     for (int i=0; i<nember; i++) {
            hs.add(Integer.parseInt(quantity[i]));
        }
     if (hs.size() == nember) 
            System.out.println("NO");
     else 
            System.out.println("YES");
     
    }
}

 

再要注意的便是输入和输出时的格式问题,我就是有一题,中文的符号和英文的符号用错了,导致结果一直出错,我查了半天才发现错误。

 

4.改进建议

1.以后的学习要花更多的时间在作业上面,不能光说不练习,不要每次作业都留到最后来写,会来不及的,平时就应该多花时间在pta上面。

2.我们需要具有自主学习能力,遇到问题不会要多去询问,在语言学习的过程中不断丰富自我,同学老师都是我们很好的学习对象。

3.要学会分析和设计,再下手做题目,不要一边做一边写,要记住磨刀不误砍柴功。

5.总结

段老师说得好,如果效率不够就花更多的时间,时间不够那就只能提升效率,像我这样没能力又不愿意花时间的最后只能被淘汰,所以我没能力就要花更多的时间在学习上面,不断丰富和打磨自己。同学和老师都是我们很好的请教对象,不要一味的盲目思考,一个人的思想和能力终究是有限的,有不会的也许问一下同学老师会有更好的答案。