oop三次大作业总结

前言:题目涉及知识紧凑,环环相扣,涵盖了当前所学的知识和一定的课外搜索,难度逐层递增,一步步加强难度,循序渐进。
分析与设计:
对于题目的分析
首先是第一次大作业的第一题:
需求设计一个风扇类
设计一个名为Fan的类表示一个风扇。这个类包括:

1.三个名为SlOW、MEDIUM和FAST,其值为1、2和3常量表示风扇的速度。

2.一个名为speed的int类型私有数据域表示风扇的速度(默认值为SLOW)。

3.一个名为on的boolean类型私有数据域表示风扇是否打开(默认值为false)。

4.一个名为radius的double类型私有数据域表示风扇的半径(默认值为5)。

5.一个名为color的string类型数据域表示风扇的颜色(默认值为white)。

6.这四个成员变量(数据域)的访问器和修改器。

7.一个无参构造方法;

8.一个有参构造方法 public Fan(int fanSpeed,boolean fanOn,double fanRadius,String fanColor) { ... },

9.一个名为toString()的方法返回描述风扇的字符串。如果风扇是打开的,那么该方法在一个组合的字符串中返回风扇的速度、颜色和半径。如果风扇没有打开,该方法就会返回一个由"fan is off"和风扇颜色以及半径组合成的字符串。
我的代码为import java.util.Scanner;
class Fan {
public static final int SLOW = 1;
public static final int MEDIUM = 2;
public static final int FAST = 3;
private int speed;
private boolean on;
private double radius;
private String color;
public Fan() {
speed = SLOW;
on = false;
radius = 5.0;
color = "white";
}

public Fan(int fanSpeed, boolean fanOn, double fanRadius, String fanColor) {
    speed = fanSpeed;
    on = fanOn;
    radius = fanRadius;
    color = fanColor;
}
public int getSpeed() {
    return speed;
}

public void setSpeed(int speed) {
    this.speed = speed;
}

public boolean isOn() {
    return on;
}

public void setOn(boolean on) {
    this.on = on;
}

public double getRadius() {
    return radius;
}

public void setRadius(double radius) {
    this.radius = radius;
}

public String getColor() {
    return color;
}

public void setColor(String color) {
    this.color = color;
}

public String toString() {
    if (on) {
        return "speed " + speed + "\ncolor " + color + "\nradius " + radius + "\nfan is on";
    } else {
        return "speed " + speed + "\ncolor " + color + "\nradius " + radius+"\nfan is off" ;
    }
}

}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Fan fan1 = new Fan();
System.out.println("-------\nDefault\n-------");
System.out.println(fan1.toString());
System.out.println("-------\nMy Fan\n-------");
int speed = scanner.nextInt();
boolean on = scanner.nextBoolean();
double radius = scanner.nextDouble();
String color = scanner.next();
Fan fan2 = new Fan(speed, on, radius, color);
System.out.println(fan2.toString());
scanner.close();
}
}
先将fan类写出来,并在其中编写出默认的风扇状态,get(),set()方法得到风扇转速,开关的状态,颜色,在写toString()对输出的格式进行编写,并在toString()中根据风扇的开关状态来输出对应的格式
main中也创建一个默认的fan输出,在输入第二的fan,并输入对应的风扇状态就可以了。

**第二题为
1.创建一个类Student,具体属性和方法如下:
属性:(全部私有,数据类型自己选择使用)
姓名(name),性别(sex),学号(studentID),年龄(age),专业(major)
方法:
(1)定义一个空参数构造器public Student();
(2)定义一个多参数的构造器,用于为所有属性赋值public Student(String name,String sex,String studentID,int age,String major)
(3)由于所有属性私有的,为所有属性提供getter()和setter()方法;
(4)public String toString()用于返回学生的所有属性信息;
(5)public void printInfo()用于打印学生的信息
2.定义一个测试类Test,在main方法中创建一个Student对象,根据提示输入学生信息保存在对象中,调用printInfo()方法输出学生信息。
3.输出结果参考“输出样例”
我的代码为
import java.util.Scanner;

class Student {
private String name;
private String sex;
private String studentID;
private int age;
private String major;

public Student() {
}

public Student(String name, String sex, String studentID, int age, String major) {
    this.name = name;
    this.sex = sex;
    this.studentID = studentID;
    this.age = age;
    this.major = major;
}
public String getName() {
    return name;
}

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

public String getSex() {
    return sex;
}

public void setSex(String sex) {
    this.sex = sex;
}

public String getStudentID() {
    return studentID;
}

public void setStudentID(String studentID) {
    this.studentID = studentID;
}

public int getAge() {
    return age;
}

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

public String getMajor() {
    return major;
}

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

public String toString() {
    return "姓名:" + name + ",性别:" + sex + ",学号:" + studentID + ",年龄:" + age + ",专业:" + major;
}

public void printInfo() {
    System.out.println(toString());
}

}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Student student = new Student();
String name = scanner.nextLine();
student.setName(name);
String sex = scanner.nextLine();
student.setSex(sex);
int age = scanner.nextInt();
student.setAge(age);
scanner.nextLine();
String major = scanner.nextLine();
student.setMajor(major);

    String studentID = scanner.nextLine();
    student.setStudentID(studentID);
    student.printInfo();
}

}
根据题目所给的提示编写出student类,用tostring()编写出输出格式并使用printInfo()函数打印出学生信息;

第三题为
创建学生类,包含

属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)

方法:计算总分、计算平均分

输入5个学生的信息,将每个学生的信息封装在一个学生对象中。

按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。

浮点数保留小数的相关知识可参考:
https://blog.csdn.net/huaishuming/article/details/17752365

注意:未用学生类对象封装数据的,本题计0分
我的代码为
import java.util.Scanner;
class Student {
private String studentNumber;
private String name;
private int chineseScore;
private int mathScore;
private int physicsScore;
public Student(String studentNumber, String name, int chineseScore, int mathScore, int physicsScore) {
this.studentNumber = studentNumber;
this.name = name;
this.chineseScore = chineseScore;
this.mathScore = mathScore;
this.physicsScore = physicsScore;
}
public int calculateTotalScore() {
return chineseScore + mathScore + physicsScore;
}
public double calculateAverageScore() {
return Math.round((calculateTotalScore() / 3.0) * 100.0) / 100.0;
}
public String getStudentInfo() {
return studentNumber + " " + name + " " + calculateTotalScore() + " " + String.format("%.2f", calculateAverageScore());
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Student[] students = new Student[5];
for (int i = 0; i < 5; i++) {
String[] input = scanner.nextLine().split(" ");
String studentNumber = input[0];
String name = input[1];
int chineseScore = Integer.parseInt(input[2]);
int mathScore = Integer.parseInt(input[3]);
int physicsScore = Integer.parseInt(input[4]);
students[i] = new Student(studentNumber, name, chineseScore, mathScore, physicsScore);
}
for (Student student : students) {
System.out.println(student.getStudentInfo());
}
scanner.close();
}
}
根据题目意思,输入五个学生的信息并打印出他们的总分和平均分
在student类中定义空的student并用多参数结构输入学生的数据,利用public int calculateTotalScore(),public double calculateAverageScore(),返回学生的总分和平均分;
在main中创造一个student数组来储存五个学生的信息,利用循环结构输入五个学生的信息,最后使用循环输出五个学生的信息;
第四题为设计实现答题程序,模拟一个小型的测试,要求输入题目信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。

输入格式:
程序输入信息分三部分:

1、题目数量

格式:整数数值,若超过1位最高位不能为0,

样例:34

2、题目内容

一行为一道题,可以输入多行数据。

格式:"#N:"+题号+" "+"#Q:"+题目内容+" "#A:"+标准答案

格式约束:题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。

样例:#N:1 #Q:1+1= #A:2

     #N:2 #Q:2+2= #A:4

3、答题信息

答题信息按行输入,每一行为一组答案,每组答案包含第2部分所有题目的解题答案,答案的顺序号与题目题号相对应。

格式:"#A:"+答案内容

格式约束:答案数量与第2部分题目的数量相同,答案之间以英文空格分隔。

样例:#A:2 #A:78

  2是题号为1的题目的答案
  78是题号为2的题目的答案

答题信息以一行"end"标记结束,"end"之后的信息忽略。

题目类(Question):首先设计题目类,用于表示单个题目的信息。题目类包括题号、题目内容和标准答案。提供一个方法用于比较学生的答案与标准答案是否一致。

试卷类(ExamPaper):设计试卷类,用于保存整套题目的信息。提供方法用于添加题目到试卷中,并能根据题号获取对应的题目。

答卷类(AnswerSheet):设计答卷类,用于保存学生的答题信息。提供方法用于添加学生的答案,以及对答案进行评分。

实现流程:

读取题目数量,并逐个读取题目信息,创建题目对象并加入试卷类中。
读取学生的答题信息,根据题号获取对应的题目,将学生的答案加入答卷类中。
对答卷类中的学生答案进行评分,对比学生答案与标准答案,记录评分结果。
根据评分结果输出学生的每道题目的答题信息,以及整张试卷的判题结果。

第二次大作业的第一题为
编写手机类(MobilePhone),含有type(型号,String类型)、price(价格,int类型)属性,要求该类实现Comparable接口,重写compareTo方法,实现按照price的大小来确定两个手机对象的大小关系。

在链表中添加三个手机对象(从键盘输入),通过Collections类的sort方法对链表中的对象按照price升序排序。输入第四个手机对象的信息,并查找它的price是否与链表中某个对象的price相同。

输入格式:
先输入三部手机的型号、价格信息
再输入要查找的第四部手机的型号、价格信息
每部手机信息的格式如:Redmi9A 599
我的代码为import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
class MobilePhone implements Comparable {
private String type;
private int price;
public MobilePhone(String type, int price) {
this.type = type;
this.price = price;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int compareTo(MobilePhone other) {
return Integer.compare(this.price, other.price);
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArrayList phoneList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
MobilePhone mobilePhone = new MobilePhone(scanner.next(), scanner.nextInt());
phoneList.add(mobilePhone);
}
System.out.println("排序前,链表中的数据:");
for (MobilePhone phone : phoneList) {
System.out.printf("型号:%s,价格:%d\n", phone.getType(), phone.getPrice());
}
Collections.sort(phoneList);
System.out.println("排序后,链表中的数据:");
for (MobilePhone phone : phoneList) {
System.out.printf("型号:%s,价格:%d\n", phone.getType(), phone.getPrice());
}
MobilePhone newPhone = new MobilePhone(scanner.next(), scanner.nextInt());
boolean h = false;
for (MobilePhone phone : phoneList) {
if (phone.getPrice() == newPhone.getPrice()) {
h = true;
System.out.printf("%s与链表中的%s价格相同\n", newPhone.getType(), phone.getType());
break;
}
}
if (!h) {
System.out.printf("链表中的对象,没有一个与%s价格相同的\n", newPhone.getType());
}
}
}
题目要求该类实现Comparable接口,重写compareTo方法,实现按照price的大小来确定两个手机对象的大小关系。,
一个新的知识点,Compareable接口可以实现类中成员属性的排序方法。通过重写Compareable接口中的CompareTo方法实现自定义规则的排序。
在该题中可以对手机的价格进行排序,在原有的一些基础信息上添加了一个comepareTo()的排序功能,
main类中,先利用循环输入三部手机的基本信息,后输入第四步手机的信息,并遍历手机数组查找是否有手机的价格和第四部手机的价格一样的,如果有就输出有,没有就输出没有;

第二题为
按要求完成程序的编写。
1、定义圆类Circle,其中包括:
(1)成员变量:private int radius
(2)无参构造方法 ,给radius赋值为2,并输出信息:"This is a constructor with no para.";
(2)有参构造方法 ,接收用户给的radius赋值,并输出"This is a constructor with para."(如果给的半径小于等于0,则赋默认值为2);
(3)为radius添加set方法,接收用户输入的半径,如果用户输入半径为<=0,则让半径的值为2;
(4)为radius半径添加get方法,返回用户输入的半径;
(5)求圆面积方法getArea(), π使用Math.PI代替;
(6)定义toString方法,public String toString( )方法体为:
return "Circle [radius=" + radius + "]";

2、定义Main类,在main方法中,完成下列操作:
(1)定义并创建Circle类对象c1,输出c1对象,求c1的面积并输出;
(2)定义并创建Circle类对象c2,输出c2对象,求c2的面积并输出;
(3)从键盘接收整数半径,赋值给c2的半径,输出c2对象,求c2的面积并输出;
(4)从键盘接收整数半径,用有参构造方法创建Circle类对象c3,输出c3对象,求c3的面积后输出。
我的代码为
import java.util.Scanner;
class Circle {
private int radius;
public Circle() {
this.radius = 2;
System.out.println("This is a constructor with no para.");
}
public Circle(int radius) {
if (radius <= 0) {
this.radius = 2;
} else {
this.radius = radius;
}
System.out.println("This is a constructor with para.");
}
public void setRadius(int radius) {
if (radius <= 0) {
this.radius = 2;
} else {
this.radius = radius;
}
}
public int getRadius() {
return radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
public String toString() {
return "Circle [radius=" + radius + "]";
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Circle c1 = new Circle();
System.out.println(c1);
System.out.printf("%.2f\n", c1.getArea());
Circle c2 = new Circle();
System.out.println(c2);
System.out.printf("%.2f\n", c2.getArea());
int radiusC2 = scanner.nextInt();
c2.setRadius(radiusC2);
System.out.println(c2);
System.out.printf("%.2f\n", c2.getArea());
int radiusC3 = scanner.nextInt();
Circle c3 = new Circle(radiusC3);
System.out.println(c3);
System.out.printf("%.2f\n", c3.getArea());
}
}
先编写出circle类,和main类,先创建两个默认半径为2的圆对象c1和c2,然后分别打印出它们的信息和面积。接着通过用户输入来设置第二个圆对象c2的半径,并再次打印出其信息和面积。接着又创建了第三个圆对象c3,通过用户输入设置其半径,并打印出c3的信息和面积。就此完成对⚪信息的打印
在circle类中定义了无参数构造函数和有参数构造函数,让用户可以创造默认⚪和输入⚪,并定义了相关信息;

第三题为
设计一个用来描述汽车的类,使用类的非静态成员变量来表示汽车的车主姓名、当前的速率和当前方向盘的转向角度,使用类的非静态成员方法来表示改变汽车的速率和停车两个操作。在下图中的【1】【2】【3】处填入正确代码使程序可以正确输出。

/**

  • @author Teacher
  •     主类,用来在pta中运行。
    
  •     其中有一处代码需要完善
    

*/
public class Main {
public static void main(String[] args) {

// 此处填写合适的代码【1】
// 生成汽车实例

System.out.printf("车主:%s,速度:%.1f,角度:%.1f\n", car.getOwnerName(), car.getCurSpeed(), car.getCurDirInDegree());

// 设置新速度
car.changeSpeed(10);
System.out.printf("车主:%s,速度:%.1f,角度:%.1f\n", car.getOwnerName(), car.getCurSpeed(), car.getCurDirInDegree());

// 停车
car.stop();
System.out.printf("车主:%s,速度:%.1f,角度:%.1f\n", car.getOwnerName(), car.getCurSpeed(), car.getCurDirInDegree());

}
}

/**

  • @author Teacher
  •     汽车类,其中有两个内容需要完善。
    

*/
class Car {
// 车主姓名
private String ownerName;
// 当前车速
private float curSpeed;
// 当前方向盘转向角度
private float curDirInDegree;

public Car(String ownerName) {
this.ownerName = ownerName;
}

public Car(String ownerName, float speed, float dirInDegree) {
this(ownerName);
this.curSpeed = speed;
this.curDirInDegree = dirInDegree;
}

// 提供对车主姓名的访问
public String getOwnerName() {
return ownerName;
}

// 提供对当前方向盘转向角度的访问
public float getCurDirInDegree() {
return curDirInDegree;
}

// 提供对当前车速的访问
public float getCurSpeed() {
return curSpeed;
}

// 提供改变当前的车速
public void changeSpeed(float curSpeed) {
// 此处填写合适的代码【2】

}

// 提供停车
public void stop() {
// 此处填写合适的代码【3】

}
}
对于三处的代码,我们只需填写一些简单的代码即可;
在第一处中根据题目打印出的信息添加Car car=new Car("bob");
第二处为一个改变速度的函数出入一个新的速度来取代原来的速度,所以填写this.curSpeed=curSpeed;即可
第三处为stop函数,让车速为0就行,所以设置curSpeed=0;

第四题为
设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-1基础上增补或者修改的内容。

要求输入题目信息、试卷信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。

输入格式:

程序输入信息分三种,三种信息可能会打乱顺序混合输入:

1、题目信息

一行为一道题,可输入多行数据(多道题)。

格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案

格式约束:

1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。
2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。

样例:#N:1 #Q:1+1= #A:2

     #N:2 #Q:2+2= #A:4

2、试卷信息

一行为一张试卷,可输入多行数据(多张卷)。

格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值

 题目编号应与题目信息中的编号对应。

 一行信息中可有多项题目编号与分值。

样例:#T:1 3-5 4-8 5-2

3、答卷信息

答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序与试卷信息中的题目顺序相对应。

格式:"#S:"+试卷号+" "+"#A:"+答案内容

格式约束:答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。

样例:#S:1 #A:5 #A:22

   1是试卷号 

   5是1号试卷的顺序第1题的题目答案

   22是1号试卷的顺序第2题的题目答案

答题信息以一行"end"标记结束,"end"之后的信息忽略。

需要创建一个题目类来表示每道题目,包括题号、题目内容和标准答案。然后创建一个试卷类来表示每张试卷,包括试卷号和题目编号与分值的映射关系。最后创建一个答卷类来表示每份答卷,包括试卷号和题目的答案。

接下来,设计一个方法来解析输入的信息。可以考虑使用字符串分割和正则表达式来提取题目信息、试卷信息和答卷信息,并用上述创建的类来储存这些信息。

然后,编写一个判题的方法来根据答卷信息和试卷信息来判断答题结果和得分情况。在判题的过程中,需要根据题目的序号和标准答案来逐个判断答案是否正确,并计算得分情况。

最后,根据判题的结果,设计一个输出的方法来输出试卷总分警示、答卷信息和判分信息。在输出的过程中,需要考虑不同的情况,比如试卷总分不为100分、答卷信息不完整等情况。

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

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();
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进行输出
student1.print();
student2.print();
}
}

/* 请在这里填写答案 */

我添加的类为import java.util.Scanner;

class Student{
String sid;
String name;
int age;
String major;
public Student(String sid,String name,int age,String major)
{
this.sid=sid;
this.name=name;
this.age=age;
this.major=major;
}
public Student()
{

}
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)
    {
        ;
    }
    else{
        this.age=age;
    }
}
public String getMajor()
{
    
    return major;
}
public void setMajor(String major)
{
    
    this.major=major;
}
public String toString()
{
    return "学号:"+sid+",姓名:"+name+",年龄:"+age+",专业:"+major;
}
public void print()
{
    System.out.println(toString());
}

}
即将无参构造和有参构造全部写出来,并写一个tostring()规范输出格式即可;
并在main类中用两种方法构造两个学生并打印出他们的信息;

第二题为给定一个日期,判定是否为合法日期。如果合法,判断该年是否闰年,该日期是当年第几天、当月第几天、当周第几天、。
给定起始日期与结束日期,判定日期是否合法且结束日期是否早于起始日期。如果均合法,输出结束日期与起始日期之间的相差的天数、月数、念书。
输入格式:
第一行输入一个日期字符串,格式为"YYYY-MM-dd"
第二行输入两个日期字符串,中间使用空格隔开。分别代表开始日期与结束日期。

输出格式:
如果第一行日期字符串非法,输出自定义的错误信息。
如果第一行日期有效,输出相关信息,如果是闰年要输出是闰年。
如果第二行两个日期,只要有一个无效。就输出相关错误信息。
如果第二行两个日期有效且结束日期不早于开始日期,输出相关信息。

我的代码为
import java.util.Scanner;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.Period;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String datee = scanner.nextLine();
String[] parts = datee.split("-");
String date1=scanner.nextLine();
String []part1=date1.split(" ");
String []parts1=part1[0].split("-");
String []parts2=part1[1].split("-");
if(isTruedate(parts[0],parts[1],parts[2]))
{
if(isLeapyear(parts[0]))
{
System.out.println(datee+"是闰年.");
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse(datee, formatter);
int dayOfYear = date.getDayOfYear();
int dayOfMonth = date.getDayOfMonth();
int dayOfWeek = date.getDayOfWeek().getValue();

    System.out.println(datee+"是当年第" + dayOfYear + "天,"+"当月第" + dayOfMonth + "天,"+"当周第" + dayOfWeek + "天.");
        if((isTruedate(parts1[0],parts1[1],parts1[2]))&&(isTruedate(parts2[0],parts2[1],parts2[2])))
        {
            int a=Integer.parseInt(parts1[0]);
            int b=Integer.parseInt(parts2[0]);
            int c=Integer.parseInt(parts1[1]);
            int d=Integer.parseInt(parts2[1]);
            int e=b-a;
            int f=d-c;
            DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate date11 = LocalDate.parse(part1[0], formatter1);
            LocalDate date22 = LocalDate.parse(part1[1], formatter1);
            Period period = Period.between(date11, date22);
             if (date22.isAfter(date11)) {
             long days = Math.abs(date22.toEpochDay() - date11.toEpochDay());
            System.out.println(part1[1] + "与" + part1[0] + "之间相差" + days  + "天,所在月份相差" + f + ",所在年份相差" + e +".");
             }
            else{
                System.out.println(part1[1]+"早于"+part1[0]+",不合法!");
            }
        }
        else{
            System.out.println(part1[0]+"或"+part1[1]+"中有不合法的日期.");
        }
    }
    else{
        System.out.println(datee+"无效!");
        if(isTruedate(parts1[0],parts1[1],parts1[2])&&isTruedate(parts2[0],parts2[1],parts2[2]))
        {
           int a=Integer.parseInt(parts1[0]);
            int b=Integer.parseInt(parts2[0]);
            int c=Integer.parseInt(parts1[1]);
            int d=Integer.parseInt(parts2[1]);
            int e=b-a;
            int f=d-c;
            DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate date11 = LocalDate.parse(part1[0], formatter1);
            LocalDate date22 = LocalDate.parse(part1[1], formatter1);
            Period period = Period.between(date11, date22);
            if (date22.isAfter(date11)) {
             long days = Math.abs(date22.toEpochDay() - date11.toEpochDay());
            System.out.println(part1[1] + "与" + part1[0] + "之间相差" + days  + "天,所在月份相差" + f + ",所在年份相差" + e +".");
             }
            else{
                System.out.println(part1[1]+"早于"+part1[0]+",不合法!");
            }
        }
        
        else{
            System.out.println(part1[0]+"或"+part1[1]+"中有不合法的日期.");
        }
    }
}
  public static boolean isLeapyear(String year){
    int a=Integer.parseInt(year);
    if(a%400==0||a%4==0&&a%100!=0)
    {
        return true;
    }
    else{
        return false;
    }
}
public static boolean isTruedate(String year, String month, String day) {
int a = Integer.parseInt(year);
int b = Integer.parseInt(month);
int c = Integer.parseInt(day);
int maxday;
if ((b == 1) || (b == 3) || (b == 5) || (b == 7) || (b == 8) || (b == 10) || (b == 12)) {
    maxday = 31;
} else if ((b == 4) || (b == 6) || (b == 9) || (b == 11)) {
    maxday = 30;
} else if (b == 2) {
    if (isLeapyear(year)) {
        maxday = 29;
    } else {
        maxday = 28;
    }
} else {
    return false;
}
if (c >= 1 && c <= maxday) {
    return true;
} else {
    return false;
}

}
}
其中用到了import java.time.LocalDate;
import java.time.format.DateTimeFormatter;来直接求出两个日期相差的时间差,
并编写isLeapyear()和isTruedate()函数都输入的日期进行判断;在main类中输入日期,然后判断合法性;
在又输入两个日期判断合法性和日期上起始日期是否早于截至日期,然后算出两个日期的相差的打day,month,year;
首先,通过LocalDate.parse方法将日期字符串解析为LocalDate类型的对象。
然后,使用Period.between方法计算两个LocalDate对象之间的时间差,得到一个Period对象。
最后,可以从Period对象中获取年、月、日的差值,从而得到两个日期之间的差距。
先将字符串日期解析为LocalDate对象,然后使用Period.between方法来计算日期的差距,最后获取时间差中的年、月、日差值。在代码中的两个日期进行对比时,也是类似的操作。通过解析日期字符串为LocalDate对象后,判断日期的先后关系,并计算差距。

第三题为
设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-2基础上增补或者修改的内容,要求输入题目信息、试卷信息、答题信息、学生信息、删除题目信息,根据输入题目信息中的标准答案判断答题的结果。

输入格式:

程序输入信息分五种,信息可能会打乱顺序混合输入。

1、题目信息
题目信息为独行输入,一行为一道题,多道题可分多行输入。

格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案

格式约束:
1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。
2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。
样例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4

2、试卷信息

试卷信息为独行输入,一行为一张试卷,多张卷可分多行输入数据。
格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值+" "+题目编号+"-"+题目分值+...

格式约束:
题目编号应与题目信息中的编号对应。
一行信息中可有多项题目编号与分值。
样例:#T:1 3-5 4-8 5-2

3、学生信息

学生信息只输入一行,一行中包括所有学生的信息,每个学生的信息包括学号和姓名,格式如下。

格式:"#X:"+学号+" "+姓名+"-"+学号+" "+姓名....+"-"+学号+" "+姓名

格式约束:
答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
样例:
#S:1 #A:5 #A:22
1是试卷号
5是1号试卷的顺序第1题的题目答案
4、答卷信息

答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序号与试 卷信息中的题目顺序相对应。答卷中:

格式:"#S:"+试卷号+" "+学号+" "+"#A:"+试卷题目的顺序号+"-"+答案内容+...

格式约束:
答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
答案内容可以为空,即””。
答案内容中如果首尾有多余的空格,应去除后再进行判断。
样例:
#T:1 1-5 3-2 2-5 6-9 4-10 7-3
#S:1 20201103 #A:2-5 #A:6-4
1是试卷号
20201103是学号
2-5中的2是试卷中顺序号,5是试卷第2题的答案,即T中3-2的答案
6-4中的6是试卷中顺序号,4是试卷第6题的答案,即T中7-3的答案
注意:不要混淆顺序号与题号

5、删除题目信息

删除题目信息为独行输入,每一行为一条删除信息,多条删除信息可分多行输入。该信息用于删除一道题目信息,题目被删除之后,引用该题目的试卷依然有效,但被删除的题目将以0分计,同时在输出答案时,题目内容与答案改为一条失效提示,例如:”the question 2 invalid~0”

格式:"#D:N-"+题目号

格式约束:

   题目号与第一项”题目信息”中的题号相对应,不是试卷中的题目顺序号。

   本题暂不考虑删除的题号不存在的情况。      

样例:

N:1 #Q:1+1= #A:2

N:2 #Q:2+2= #A:4

T:1 1-5 2-8

X:20201103 Tom-20201104 Jack

S:1 20201103 #A:1-5 #A:2-4

D:N-2

end

输出
alert: full score of test paper1 is not 100 points
1+1=5false
the question 2 invalid~0
20201103 Tom: 0 0~0
答题信息以一行"end"标记结束,"end"之后的信息忽略。

一开始,我花了一些时间理清了题目的需求,然后按照输入输出的要求,设计了相应的数据结构和逻辑流程。在编写代码的过程中,我遵循了面向对象的设计原则,将题目、试卷和答卷分别抽象成了类,并在类中实现了相应的方法来处理题目信息和答题逻辑。

在实现过程中,我遇到了一些挑战。比如,处理输入输出的格式要求时,需要仔细考虑每一行的格式和内容,确保能够正确解析题目和答题信息。另外,在判断答案是否正确时,我采用了简单直观的逻辑,但也要注意考虑边界情况和异常处理,以保证程序的稳健性。

采坑心得:
在编写代码的过程中遇到的格式问题,有些格式要求输入","有些要求输入",",导致有些时候没有分清楚输出格式最后到测试错误,利用特殊手段得以发现改进,

在输出 public static boolean isLeapyear(String year){
int a=Integer.parseInt(year);
if(a%4000||a%40&&a%100!=0)
{
return true;
}
else{
return false;
}
}
public static boolean isTruedate(String year, String month, String day) {
int a = Integer.parseInt(year);
int b = Integer.parseInt(month);
int c = Integer.parseInt(day);
int maxday;
if ((b == 1) || (b == 3) || (b == 5) || (b == 7) || (b == 8) || (b == 10) || (b == 12)) {
maxday = 31;
} else if ((b == 4) || (b == 6) || (b == 9) || (b == 11)) {
maxday = 30;
} else if (b == 2) {
if (isLeapyear(year)) {
maxday = 29;
} else {
maxday = 28;
}
} else {
return false;
}
if (c >= 1 && c <= maxday) {
return true;
} else {
return false;
}中,如果我没有添加public static他就会在提交的时候显示返回值为0;十分神奇,原因不详;
并且这段代码在后续的提交中即使可以完美胜任他的任务但是依旧显示答案错误,尽力了;

改进建议:在输入的过程中十分复杂,也不知如何简化输入方式,
还有一些判断数据类型,不知可否用函数来代替,避免重复的代码出现

总结:对于这三次的大作业,有些收获,也对java编程有了更深的认知,在大量的实践过程中对知识的掌握愈加熟练,在完成了题目的编写和测试后。
这次作业的完成让我对Java的语言特性和面向对象编程有了更深入的理解,也在解决问题的过程中锻炼了自己的逻辑思维和解决技术难题的能力。未来,我期待能够在Java编程领域不断成长,不断挑战更复杂的项目,为自己的技术提升而努力。我相信,通过持续的学习和实践,我能够成为一个优秀的Java开发者,并为解决现实问题贡献自己的一份力量。

posted @ 2024-04-21 22:14  霜月之陨  阅读(56)  评论(0)    收藏  举报