第二次Blog作业

发布时间 2023-04-30 20:21:48作者: 顾念乔安

1.前言

第四次作业集

  除了第一题比较难,其他的题目难度都中等,题目量也不算多,但有的题目需要按照题目给的要求来写,就必须要去学,例如7-7要通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。才能做出题目,不然是0分。q w q.

第五次作业集

  有3道题是练习正则表达式,有两道题是以前的题目迭代,还有一题是字符排序,除了迭代的两题比较难,其他的都比较简单,正则表达式刚开始也不会,所以看了一些网课,明白了它的用法就觉得也不是很难(可能是这些题比较简单),第一个迭代题目我觉得有些难,做了挺久的,试了好多次才对了,也是根据以前的题目改的。

第六次作业集

  这虽然只有一题,但是很难,也是一个迭代的题目,代码量也有1700+行,需用时20+h,之前的题目我没有写出来,对这题就感到“畏惧”,就感觉无从下手,所以没怎么写。到最后才追悔莫及。

2.设计与分析

第四次作业集

  7-1感觉太难了,而且当时没时间就没怎么写。导致后面的迭代的题目也没做不出来

  7-2 有重复的数据

在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。

 

你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES”这三个字母;如果没有,则输出“NO”。

 

输入格式:

 

你的程序首先会读到一个正整数n,n[1,100000],然后是n个整数。

 

输出格式:

 

如果这些整数中存在重复的,就输出:

 

YES

 

否则,就输出:

 

NO 

 

输入样例:

 

5
1 2 3 1 4

 

 

 

输出样例:

 

YES

代码如下:
import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        String m = input.nextLine();
        String inputStr = input.nextLine();
        String[] strArray = inputStr.split(" ");
        char[] a = new char[strArray.length];
        for(int k = 0 ; k < a.length ; k++){
            a[k] = strArray[k].charAt(0);
        }
        int count =0;
        if (n >= 1 && n <= 100000 && n == a.length) {
            for (int i = 0;i < a.length - 1;i++) {
                for (int j = i + 1; j < a.length; j++) {
                    if (a[i] == a[j]) {
                        count++;
                        break;
                    }
                }
                if (count != 0) {
                    System.out.print("YES");
                    return ;
                }
            }
            System.out.print("NO");
        } else {
            System.out.print("NO");
        }
    }
}

  分析如下:

  创建两个数组,将输入的数字放入第一个数组,通过for循环判断将不重复的数字放入第二个数组,再根据两个数组的长度是否相等判断输入的数字是否重复。

  7-5 面对对象程序(封装性)

  Student类具体要求如下:
私有成员变量:学号(sid,String类型),姓名(name,String类型),年龄(age,int类型),专业(major,String类型) 。
提供无参构造和有参构造方法。(注意:有参构造方法中需要对年龄大小进行判定)
普通成员方法:print(),输出格式为“学号:6020203100,姓名:王宝强,年龄:21,专业:计算机科学与技术”。
普通成员方法:提供setXxx和getXxx方法。(注意:setAge()方法中需要对年龄进行判定)
注意:
年龄age不大于0,则不进行赋值。
print()中的“:”和“,”为均为中文冒号和逗号。

  代码如下:

import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //调用无参构造方法,并通过setter方法进行设值
        String sid1 = sc.next();
        String name1 = sc.next();
        int age1 = sc.nextInt();
        String major1 = sc.next();
        Student student1 = new Student(sid1, name1, age1, major1);
        student1.setSid(sid1);
        student1.setName(name1);
        student1.setAge(age1);
        student1.setMajor(major1);
        //调用有参构造方法
        String sid2 = sc.next();
        String name2 = sc.next();
        int age2 = sc.nextInt();
        String major2 = sc.next();
        Student student2 = new Student(sid2, name2, age2, major2);
        //对学生student1和学生student2进行输出
        System.out.println("学号:" + student1.getSid() + ",姓名:" + student1.getName() +
                ",年龄:" + student1.getAge() + ",专业:" + student1.getMajor());
        System.out.printf("学号:" + sid2 + ",姓名:" + name2 + ",年龄:" + age2 + ",专业:" + major2);
    }
}
class Student{
    public Student(String sid,String name,int age,String major){
        this.sid = sid;
        this.name = name;
        this.age = age;
        this.major = major;
    }
    private String sid;
    private String name;
    private int age;
    private String major;


    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age > 0){
        this.age = age;
        }
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }
}

  分析如下:

  基本的代码老师都给我们了,就最后一点简单的要我们自己写,也没什么好分析的。

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

  

从键盘输入两个日期,格式如:2022-06-18。判断两个日期的先后,并输出它们之间间隔的天数、周数(不足一周按0计算)。

预备知识:通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。

  代码如下:

  

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String input1 = in.nextLine();
        String input2 = in.nextLine();
        String[] date3 = input1.split("-");
        int year1 = Integer.parseInt(date3[0]);
        int month1 = Integer.parseInt(date3[1]);
        int day1 = Integer.parseInt(date3[2]);
        LocalDate date7 = LocalDate.of(year1,month1,day1);
        String[] date4 = input2.split("-");
        int year2 = Integer.parseInt(date4[0]);
        int month2 = Integer.parseInt(date4[1]);
        int day2 = Integer.parseInt(date4[2]);
        LocalDate date8 = LocalDate.of(year2,month2,day2);
        if (date7.isBefore(date8)) {
            System.out.println("第一个日期比第二个日期更早");
            long date5 = date7.until(date8, ChronoUnit.DAYS);
            long date6 = date7.until(date8, ChronoUnit.WEEKS);
            System.out.println("两个日期间隔" + date5 + "天");
            System.out.print("两个日期间隔" + date6 + "周");
        }
        if (date7.isAfter(date8)) {
            System.out.println("第一个日期比第二个日期更晚");
            long date5 = date8.until(date7, ChronoUnit.DAYS);
            long date6 = date8.until(date7, ChronoUnit.WEEKS);
            System.out.println("两个日期间隔" + date5 + "天");
            System.out.print("两个日期间隔" + date6 + "周");
        }

    }
}

  分析如下:

  老师已经给了我们方法,我们用这个方法做就行了,但是我开始不是完全按照这个方法写的,所以一直是非零返回,一直报错,找不到原因,后来问朋友说要按照给的方法来做,我试了之后才发现确实要这样,最后就写完了。

  第五次作业集

  7-5

  

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

类图.jpg

 

应用程序共测试三个功能:

 

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

  代码如下:

  

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner x=new Scanner(System.in);
        int year=0,month=0,day=0,a,b;
        a=x.nextInt();
        year=x.nextInt();month= x.nextInt();day=x.nextInt();
        DateUtil c=new DateUtil(year,month,day);
        if(a==1){
            b=x.nextInt();
            if(!c.checkInputValidity()||b<0){
                System.out.println("Wrong Format");
            }
            else
                System.out.println(c.getNextNDays(b).showDate());
        }
        else if(a==2){
            b=x.nextInt();
            if(!c.checkInputValidity()||b<0){
                System.out.println("Wrong Format");
            }
            else
                System.out.println(c.getPreviousNDays(b).showDate());
        }
        else if(a==3){
            int y1,m1,d1;
            y1=x.nextInt();m1= x.nextInt();d1=x.nextInt();
            DateUtil d=new DateUtil(y1,m1,d1);
            if(!c.checkInputValidity()||!d.checkInputValidity()){
                System.out.println("Wrong Format");
            }
            else
                System.out.println(c.getDaysofDates(d));
        }
        else
            System.out.println("Wrong Format");

    }
}
class DateUtil{
    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 equalTwoDates(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();
    }

    public int syts(DateUtil d){
        int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
        int b=0,i;
        for(i=d.getDay().getMonth().getValue()+1;i<=12;i++){
            b=b+a[i];
        }
        b=b+a[d.getDay().getMonth().getValue()]-d.getDay().getValue();
        if(d.getDay().getMonth().getYear().isLeapYear()&&d.getDay().getMonth().getValue()<=2)
            b++;
        return b;
    }


    public DateUtil getNextNDays(int n){
        int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
        int y=0,m=0,d=0;
        int i,j;
        int b=syts(this);
        if(b>n){
            y=this.getDay().getMonth().getYear().getValue();
            if(this.getDay().getMonth().getYear().isLeapYear()){
                a[2]=29;
            }
            int e=a[this.getDay().getMonth().getValue()];
            e=e-this.getDay().getValue();
            if(e>=n){
                m=this.getDay().getMonth().getValue();
                d=n+this.getDay().getValue();
            }
            else{
                n=n-e;
                m=this.getDay().getMonth().getValue()+1;
                i=m;
                while(n-a[i]>0&&i<=12){
                    n=n-a[i];
                    m++;
                    i++;
                }
                d=n;
            }
        }
        else{
            n=n-b;
            y=this.getDay().getMonth().getYear().getValue()+1;
            int c=365;
            if(new Year(y).isLeapYear()){
                c++;
            }
            while(n-c>0){
                n=n-c;
                y++;
                c=365;
                if(new Year(y).isLeapYear())
                    c++;
            }
            i=1;
            while(n-a[i]>0&&i<=12){
                n=n-a[i];
                i++;
            }
            m=i;
            d=n;
        }
        return new DateUtil(y, m, d);
    }

    public DateUtil getPreviousNDays(int n){
        int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
        int y=0,m=0,d=0;
        int i,b;
        b=365-syts(this);
        if(this.getDay().getMonth().getYear().isLeapYear()){
            b++;
        }
        if (b>n){
            y=this.getDay().getMonth().getYear().getValue();
            int e=this.getDay().getValue();
            if(e>n){
                m=this.getDay().getMonth().getValue();
                d=e-n;
            }
            else{
                n=n-e;
                m=this.getDay().getMonth().getValue()-1;
                i=m;
                while(n-a[i]>0&&i>=0){
                    n=n-a[i];
                    m--;
                    i--;
                }
                d=a[i]-n;
                if(new Year(y).isLeapYear()&&m==2){
                    d++;
                }
            }
        }
        else{
            n=n-b;
            y=this.getDay().getMonth().getYear().getValue()-1;
            int f=365;
            if(new Year(y).isLeapYear()){
                f++;
            }
            while(n-f>0){//找到年
                n=n-f;
                y--;
                f=365;
                if(new Year(y).isLeapYear())
                    f++;
            }
            i=12;
            while(n-a[i]>0&&i>=0){
                n=n-a[i];
                i--;
            }
            m=i;
            d=a[i]-n;
            if(new Year(f).isLeapYear()&&m==2){
                d++;
            }
        }
        return new DateUtil(y, m, d);
    }

    public int getDaysofDates(DateUtil date){
        DateUtil b1=this;
        DateUtil b2=date;
        if(this.equalTwoDates(date)){
            return 0;
        }
        else if(!this.compareDates(date)){
            b1=date;
            b2=this;
        }
        int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
        int i,j,ts=0;
        for(i=b1.getDay().getMonth().getYear().getValue()+1;i<b2.getDay().getMonth().getYear().getValue();i++){
            ts=ts+365;
            if(new Year(i).isLeapYear())
                ts++;
        }
        if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()
                &&b1.getDay().getMonth().getValue()==b2.getDay().getMonth().getValue()){
            ts=b2.getDay().getValue()-b1.getDay().getValue();
        }
        else if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()
                &&b1.getDay().getMonth().getValue()!=b2.getDay().getMonth().getValue()){
            if(b1.getDay().getMonth().getYear().isLeapYear())
                a[2]=29;
            ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();
            ts=ts+b2.getDay().getValue();
            for(j=b1.getDay().getMonth().getValue()+1;j<=b2.getDay().getMonth().getValue()-1;j++)
                ts+=a[j];
        }
        else if(b1.getDay().getMonth().getYear().getValue()!=b2.getDay().getMonth().getYear().getValue()){
            ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();
            ts=ts+b2.getDay().getValue();
            for(j=b1.getDay().getMonth().getValue()+1;j<=12;j++)
                ts=ts+a[j];
            for(j=b2.getDay().getMonth().getValue()-1;j>0;j--)
                ts=ts+a[j];
            if(b1.getDay().getMonth().getYear().isLeapYear()&&b1.getDay().getMonth().getValue()<=2)
                ts++;
            if(b2.getDay().getMonth().getYear().isLeapYear()&&b2.getDay().getMonth().getValue()>2)
                ts++;
        }
        return ts;
    }
}
class Year{
    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<=2050&&value>=1900)
            return true;
        else
            return false;
    }

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

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

class Month{
    int value;
    Year year;

    public Month(){
    }

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

    public int getValue(){
        return value;
    }
    public Year getYear(){
        return year;
    }

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

    public void resetMin(){
        value=1;
    }

    public void resetMax(){
        value=12;
    }

    public boolean validate(){
        if(value>=1&&value<=12)
            return true;
        else
            return false;
    }

    public void dayIncrement(){
        value=value+1;
    }

    public void dayReduction(){
        value=value-1;
    }
}

class Day{
    int value;
    Month month;
    int a[]={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 Month getMonth(){
        return month;
    }

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

    public void resetMin(){
        value=1;
    }

    public void resetMax(){
        value=a[month.getValue()-1];
    }

    public boolean validate(){
        if(this.getMonth().getYear().isLeapYear())
            a[1]=29;
        if(value>=1&&value<=a[month.getValue()-1])
            return true;
        else
            return false;
    }
    //日期加一
    public void dayIncrement() {
        value=value+1;
    }

    public void dayReduction() {
        value=value-1;
    }
}

  分析如下:

  这一题是日期问题面向对象设计,类与类之间是聚合的关系,通过类图可以知道这几个类是通过把一个类放在另一个类里当成属性,从而使该类可以引用属性的方法,而且是一类聚合一个类。其实这题就是要学会如何使用getter/setter方法去一层层调用不同类中的属性与方法。计算前n天的话,就是循环n次一天一天减回去,虽然费时但不容易错,在减的时候要注意日期边界值,比如1号减一天之后day改为前一个月的最大值,month--,如果该月为1月,那么还要year--,同时注意闰年和平年的二月总天数,这一点如果不考虑将会相差好多天。计算后n天的话算法一样,就是循环n次一天一天加上去,加的时候也需注意边界值,比如31号加一天之后day改为1,month++,如果该月为12月,则还要year++,一样要考虑闰年和平年。

   7-7

  参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

类图.jpg

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

  当时没时间写了我就直接用7-5的代码复制上去,所以也给不了代码,但这题是7-5的升级版,类之间的聚合关系更强,耦合性弱一点。通过DateUtil聚合了年月日三个类,将它们都作为属性来调用它们的方法。应该就差不多了。

  第五次作业集

  7-1

  我之前的那题没怎么写,所以这题感觉就很难,又有那么多异常情况,我就觉得自己肯定写不出来,又看见排名那里很多人都没写出来,我就没怎么写了。

3.踩坑总结

  第四次作业

  这次印象深刻的题目是7-6,最后的结果要么是保留5位小数,要么是第六位小数错了,改了好久都没对,后来让朋友看,才发现了错的地方,当时在IDEA上的结果没对就没放到PTA上,结果对了之后放上去就一遍过,所以就没有截图了。还有7-7,前面没完全按照老师要求的方法去做就一直非零返回。

 后来看老师给的方法去用到最后才对了

import·java.time.temporal.ChronoUnit;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String input1 = in.nextLine();
        String input2 = in.nextLine();
        String[] date3 = input1.split("-");
        int year1 = Integer.parseInt(date3[0]);
        int month1 = Integer.parseInt(date3[1]);
        int day1 = Integer.parseInt(date3[2]);
        LocalDate date7 = LocalDate.of(year1,month1,day1);
        String[] date4 = input2.split("-");
        int year2 = Integer.parseInt(date4[0]);
        int month2 = Integer.parseInt(date4[1]);
        int day2 = Integer.parseInt(date4[2]);
        LocalDate date8 = LocalDate.of(year2,month2,day2);
        if (date7.isBefore(date8)) {
            System.out.println("第一个日期比第二个日期更早");
            long date5 = date7.until(date8, ChronoUnit.DAYS);
            long date6 = date7.until(date8, ChronoUnit.WEEKS);
            System.out.println("两个日期间隔" + date5 + "天");
            System.out.print("两个日期间隔" + date6 + "周");
        }
        if (date7.isAfter(date8)) {
            System.out.println("第一个日期比第二个日期更晚");
            long date5 = date8.until(date7, ChronoUnit.DAYS);
            long date6 = date8.until(date7, ChronoUnit.WEEKS);
            System.out.println("两个日期间隔" + date5 + "天");
            System.out.print("两个日期间隔" + date6 + "周");
        }

    }
}

 

4.改进建议:

  (1)题目集要早点写,不然等下没时间写,不仅这次没做好,万一以后有迭代的题目就更做不出来。

  (2)写代码的时候要记得写注释,不然一大行代码在那里自己都可能看不懂,以后写总结的时候就很难总结。

  (3)要学会分析类与类之间的关系,先画类图再写代码。这样思路才清晰,更容易写对。

5.总结

  要早点写作业,不然做不完;不能看别人没写,我自己就不写了。不能认为法不责众。要先把题目读懂再做题,不然很难做出来。细节问题总是出错:像格式错误,读题不仔细这种,确实是不应该犯的错误。