(1)前言:总结三次题目集的知识点、题量、难度等情况

  第一次的作业基本就是熟悉一下java基本的语法,这部分Java就算需要自学也并不算难,并且本身就有了一些c语言的基础,作业的问题主要是我们对于输入输出和判断循环语句的使用,总体的难度很低。第二次的作业就是类的使用以及私有化和相关封装。第三次是是除了第二题都还算简单,了解LocalDate类中of()、isAfter()或者isBefore()等方法的使用规则基本就能写,第二题是目前所有题目中最难的,逻辑相对复杂,包含许多知识点,

 

(2)设计与分析:

2.1第一次作业
判断三角形类型
输入三角形三条边,判断该三角形为什么类型的三角形。

输入格式:

在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。

输出格式:

(1)如果输入数据非法,则输出“Wrong Format”;
(2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”;
(3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”;
(3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”;
(5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”;
(6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”;
(7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。

 

 踩坑心得

本题还是比较简单的,遇到问题主要是无法判断直角三角形,因为未考虑到精度问题,这里由于double类型的数在平方后精度丢失,输入的数据不一定为整数,程序是先四舍五入再进行勾股定理的,导致结果会有误差判断不相等无法判断三角形是否为直角。

 

 

把代码从直接用 == 判断改为用减法和误差进行判断,允许部分误差。

 

 

这题圈复杂度直接拉满达到惊人的28,就算代码很短现在的我去看一下也要梳理一下才能看懂,直接使用 if 堆起来还是不建议(虽然写起来好理解),算是理解了为什么要求圈复杂度要低了qwq。

import java.util.Scanner;


public class Main {
public static void main(String[] args) {
Scanner data = new Scanner(System.in);
Float side1, side2, side3;
side1 = data.nextFloat();
side2 = data.nextFloat();
side3 = data.nextFloat();


if(1 <= side1 && side1 <= 200 && 1 <= side2 && side2 <= 200 && 1 <= side3 && side3 <= 200){
if(side1 + side2 > side3 && side1 + side3 > side2 && side3 + side2 > side1 && side1 - side2 < side3 && side1 - side3 < side2 && side3 - side2 < side1){
if(side1.equals(side2) || side3.equals(side2) || side1.equals(side3)) {
if(side1.equals(side2) && side1.equals(side3))
System.out.println("Equilateral triangle");
else if(side1 * side1 + side2 * side2 - side3 * side3 <= 0.000001)
System.out.println("Isosceles right-angled triangle");
else if(side1 * side1 + side3 * side3 - side2 * side2<= 0.000001)
System.out.println("Isosceles right-angled triangle");
else if(side2 * side2 + side3 * side3 - side1 * side1<= 0.000001)
System.out.println("Isosceles right-angled triangle");
else
System.out.println("Isosceles triangle");
}
else if(side1 * side1 + side2 * side2 == side3 * side3 )
System.out.println("Right-angled triangle");
else if(side1 * side1 + side3 * side3 == side2 * side2)
System.out.println("Right-angled triangle");
else if(side2 * side2 + side3 * side3 == side1 * side1)
System.out.println("Right-angled triangle");
else
System.out.println("General triangle");
}
else
System.out.println("Not a triangle");
}
else
System.out.println("Wrong Format");


}
}

 

2.2.第二次作业1

成绩计算-1-类、数组的基本运用

创建学生类,包含

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

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

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

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

 

建一个类直接用就可以了,当时刚好学了一些私有,就用上了。

 源码

import java.util.Scanner;

class Student{
    private String ID;
    private String Name;
    private  int MathScore;
    private  int ChineseScore;
    private  int PhysicsScore;

    public  Student(String ID,String Name,int MathScore,int ChineseScore,int PhysicsScore){
        this.Name = Name;
        this.ID = ID;
        this.MathScore = MathScore;
        this.ChineseScore = ChineseScore;
        this.PhysicsScore = PhysicsScore;
    }
    public String getName() {
        return Name;
    }

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

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public int getMathScore() {
        return MathScore;
    }

    public void setMathScore(int mathScore) {
        this.MathScore = mathScore;
    }

    public int getChineseScore() {
        return ChineseScore;
    }

    public void setChineseScore(int chineseScore) {
        this.ChineseScore = chineseScore;
    }

    public int getPhysicsScore() {
        return PhysicsScore;
    }

    public void setPhysicsScore(int physicsScore) {
        this.PhysicsScore = physicsScore;
    }

    public static double AVerage(int MathScore,int ChineseScore, int PhysicsScore){
        double AVerage = (MathScore + ChineseScore + PhysicsScore)*1.00 / 3;
        return AVerage;
    }
    public static int ALL(int MathScore,int ChineseScore, int PhysicsScore){
        return MathScore + ChineseScore + PhysicsScore;
    }


}

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Student[] STU = new Student[5];
        for (int i = 0; i < 5; i++) {

            String ID = in.next();
            String name = in.next();
            int MScore = in.nextInt();
            int CScore = in.nextInt();
            int PSsore = in.nextInt();
            STU[i] =  new Student(ID,name,MScore,CScore,PSsore);
        }
        for (int j = 0; j < 5; j++) {
            int all = STU[j].ALL(STU[j].getMathScore(),STU[j].getChineseScore(),STU[j].getPhysicsScore());
            double average = STU[j].AVerage(STU[j].getMathScore(),STU[j].getChineseScore(),STU[j].getPhysicsScore());
            if(j < 4)
                System.out.println(STU[j].getID() + " "+STU[j].getName() + " " +  all + " " + String.format("%.2f",average ));
            else
                System.out.print(STU[j].getID() + " "+STU[j].getName() + " " + all + " " + String.format("%.2f", average));
        }
    }
}

 

 
2.3第二次作业2
成绩计算-2-关联类

创建成绩类,包含:

属性:平时成绩(int)、期末成绩(int)

方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃)

创建学生类,包含:

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

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

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

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

 

这题是做为上一题的升级版,增加了成绩类,题目之中只要求输出总成绩和平均成绩,但测试用例和最后的提交都表明了还需要输出平时成绩和考试成绩才是正确答案。

 (偷了个懒直接未判断成绩是哪一个科目的,直接给我满分过了 ?o?   要写加个字符判断应该也不难)

import java.util.Scanner;

class Scores{
    private int UsualGrades;
    private int FinalGrades;
    
    public  Scores(int UsualGrades,int FinalGrades){
        this.UsualGrades = UsualGrades;
        this.FinalGrades = FinalGrades;
    }
    public int getUsualGrades() {
        return UsualGrades;
    }

    public void setUsualGrades(int usualGrades) {
        UsualGrades = usualGrades;
    }

    public int getFinalGrades() {
        return FinalGrades;
    }

    public void setFinalGrades(int finalGrades) {
        FinalGrades = finalGrades;
    }


    public int AllGrades(int UsualGrades,int FinalGrades){
        double Allgrades = UsualGrades * 0.4 + FinalGrades * 0.6;
                return (int)Allgrades;
    }
}

class Student{
    private String ID;
    private String Name;
    private  Scores MathScore;
    private  Scores ChineseScore;
    private  Scores PhysicsScore;

    public  Student(String ID,String Name,Scores MathScore,Scores ChineseScore,Scores PhysicsScore){
        this.Name = Name;
        this.ID = ID;
        this.MathScore = MathScore;
        this.ChineseScore = ChineseScore;
        this.PhysicsScore = PhysicsScore;
    }

    public void setMathScore(Scores mathScore) {
        MathScore = mathScore;
    }

    public void setChineseScore(Scores chineseScore) {
        ChineseScore = chineseScore;
    }

    public void setPhysicsScore(Scores physicsScore) {
        PhysicsScore = physicsScore;
    }

    public String getName() {
        return Name;
    }

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

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public Scores getMathScore() {
        return MathScore;
    }

    public Scores getChineseScore() {
        return ChineseScore;
    }

    public Scores getPhysicsScore() {
        return PhysicsScore;
    }

    public static double AVerageAll(Scores MathScore, Scores ChineseScore, Scores PhysicsScore){
        double AVerage = (ChineseScore.AllGrades(ChineseScore.getUsualGrades(), ChineseScore.getFinalGrades()) +
                MathScore.AllGrades(MathScore.getUsualGrades(), MathScore.getFinalGrades()) +
                PhysicsScore.AllGrades(PhysicsScore.getUsualGrades(), PhysicsScore.getFinalGrades()))*1.00 / 3;
        return AVerage;
    }
    public static double AVerageusual(Scores MathScore, Scores ChineseScore, Scores PhysicsScore){
        double AVerage = (ChineseScore.getUsualGrades() + MathScore.getUsualGrades() + PhysicsScore.getUsualGrades())*1.00 / 3;
        return AVerage;
    }
    public static double AVeragefinal(Scores MathScore, Scores ChineseScore, Scores PhysicsScore){
        double AVerage = (ChineseScore.getFinalGrades() + MathScore.getFinalGrades() + PhysicsScore.getFinalGrades())*1.00 / 3;
        return AVerage;
    }
    public static int ALL(Scores MathScore,Scores ChineseScore, Scores PhysicsScore){
        return (ChineseScore.AllGrades(ChineseScore.getUsualGrades(), ChineseScore.getFinalGrades()) +
                MathScore.AllGrades(MathScore.getUsualGrades(), MathScore.getFinalGrades()) +
                PhysicsScore.AllGrades(PhysicsScore.getUsualGrades(), PhysicsScore.getFinalGrades()));
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Student[] STU = new Student[3];

        for (int i = 0; i < 3; i++) {
            String ID = in.next();
            String name = in.next();
            String subject = in.next();
            Scores MScore = new Scores(in.nextInt(),in.nextInt());
            String ID1 = in.next();
            String name1 = in.next();
            String subject1 = in.next();
            Scores CScore = new Scores(in.nextInt(),in.nextInt());
            String ID2 = in.next();
            String name2 = in.next();
            String subject2 = in.next();
            Scores PSsore = new Scores(in.nextInt(),in.nextInt());
            STU[i] =  new Student(ID,name,MScore,CScore,PSsore);
        }
        for (int j = 0; j < 3; j++) {
            int all = STU[j].ALL(STU[j].getMathScore(),STU[j].getChineseScore(),STU[j].getPhysicsScore());
            double averageall = STU[j].AVerageAll(STU[j].getMathScore(),STU[j].getChineseScore(),STU[j].getPhysicsScore());
            double averageusual = STU[j].AVerageusual(STU[j].getMathScore(),STU[j].getChineseScore(),STU[j].getPhysicsScore());
            double averagefinal = STU[j].AVeragefinal(STU[j].getMathScore(),STU[j].getChineseScore(),STU[j].getPhysicsScore());

            if(j < 2)
                System.out.println(STU[j].getID() + " "+STU[j].getName() + " " +  all + " "+ String.format("%.2f",averageusual ) +  " " +String.format("%.2f",averagefinal ) +  " " +String.format("%.2f",averageall ));
            else
                System.out.print(STU[j].getID() + " "+STU[j].getName() + " " + all + " " + String.format("%.2f",averageusual )+  " " +String.format("%.2f",averagefinal )+  " " +String.format("%.2f", averageall));
        }
    }
}

 

2.4第二次作业3
菜单计价程序-1

某饭店提供4种菜,每种菜品的基础价格如下:

西红柿炒蛋 15
清炒土豆丝 12
麻婆豆腐 12
油淋生菜 9

设计点菜计价程序,根据输入的订单,计算并输出总价格。
订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
每条点菜记录包含:菜名、份额两个信息。
份额可选项包括:1、2、3,分别代表小、中、大份)

不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格
2。
如果计算出现小数,按四舍五入的规则进行处理。

参考以下类的模板进行设计:
菜品类:对应菜谱上一道菜的信息。
Dish {
String name;//菜品名称
int unit_price; //单价
int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
Menu {
Dish[] dishs ;//菜品数组,保存所有菜品信息
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}

点菜记录类:保存订单上的一道菜品记录
Record {
Dish d;//菜品
int portion;//份额(1/2/3代表小/中/大份)
int getPrice()//计价,计算本条记录的价格
}

订单类:保存用户点的所有菜的信息。
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice()//计算订单的总价
Record addARecord(String dishName,int portion)
//添加一条菜品信息到订单中。
}

输入格式:

每条点菜记录的格式:
菜名+空格(英文)+份额
注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
最后一条记录以“end”结束。

输出格式:

订单上所有菜品的总价(整数数值),每份菜

如果订单中包含不能识别的菜名,则在总价之前输出“** does not exist”,**是不能识别的菜名

 

菜单计价程序题目的先锋,把各个类已经告诉了要什么内容,主要是理清楚各个类之间的关系,主函数用while持续接收,检测到end就停止,字符串判断本来用if条件写了一大堆,结果效果并不好,直接是结果有误,之后去找了一些资料写的,像Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等其他类中的一些方法的使用经常在字符判断中使用,调用之后也是简洁了不少。

import java.util.*;

class Dish {
    String name;
    int unit_price;

    Dish(StrA

class Menu {
    Dish[] dishes = new Dish[4];

    Menu() {
        dishes[0] = new Dish("西红柿炒蛋", 15);
        dishes[1] = new Dish("清炒土豆丝", 12);
        dishes[2] = new Dish("麻婆豆腐", 12);
        dishes[3] = new Dish("油淋生菜", 9);
    }

    Dish searchDish(String dishName) {
        for (Dish dish : dishes) {
            if (dish.name.equals(dishName)) {
                return dish;
            }
        }
        return null;
    }
}

class Record {
    Dish d;
    int portion;

    Record(Dish d, int portion) {
        this.d = d;
        this.portion = portion;
    }

    int getPrice() {
        return d.getPrice(portion);
    }
}

class Order {
    Record[] records = new Record[20];
    Menu menu;
    int count = 0;

    Order(Menu menu) {
        this.menu = menu;
    }

    void addARecord(String dishName, int portion) {
        Dish dish = menu.searchDish(dishName);
        if (dish != null) {
            records[count++] = new Record(dish, portion);
        } else {
            System.out.println(dishName + " does not exist");
        }
    }

    int getTotalPrice() {
        int total = 0;
        for (int i = 0; i < count; i++) {
            total += records[i].getPrice();
        }
        return total;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        Order order = new Order(new Menu());

        while (true) {
            String line = in.nextLine();
            if (line.equals("end")) break;

            String[] parts = line.split(" ");
            String dishName = parts[0];
            int portion = Integer.parseInt(parts[1]);

            order.addARecord(dishName, portion);
        }

        System.out.println(order.getTotalPrice());
    }
}

 

2.5第三次作业1
课程成绩统计程序-1

某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。

考察的总成绩直接等于期末成绩

必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。

1、输入:

包括课程、课程成绩两类信息。

课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。

课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式

课程性质输入项:必修、选修

考核方式输入选项:考试、考察

课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩

课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩

以上信息的相关约束:

1)平时成绩和期末成绩的权重默认为0.3、0.7

2)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】

3)学号由8位数字组成

4)姓名不超过10个字符

5)课程名称不超过10个字符

6)不特别输入班级信息,班级号是学号的前6位。

2、输出:

输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。

为避免误差,平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。

1)学生课程总成绩平均分按学号由低到高排序输出

格式:学号+英文空格+姓名+英文空格+总成绩平均分

如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams"

2)单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出

格式:课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分

如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet"

3)班级所有课程总成绩平均分按班级由低到高排序输出

格式:班级号+英文空格+总成绩平均分

如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet"

异常情况:

1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"

2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch"

以上两种情况如果同时出现,按第一种情况输出结果。

3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch"

4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format"

5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

信息约束:

1)成绩平均分只取整数部分,小数部分丢弃

 

本题由于一些未知原因只能实现部分功能,这题比较复杂,需要理清清楚各个类之间的逻辑关系,

通过各个类实现对订单总价得计算,将点菜记录类和菜谱类设计为数组集合类型,更方便对里面的数据进行处理。

import java.util.Scanner;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collections;


class Course {

  String name;
  String type; 
  String mode;
  double weight;


  public Course(String name, String type, String mode) {
    this.name = name;
    this.type = type;
    this.mode = mode;
 
    if (mode.equals("考试")) {
      this.weight = 0.3;
    } else {
      this.weight = 0;
    }
  }
}


class Student {
  // 定义学生的属性
  String id; // 学号
  String name; // 姓名
  HashMap<String, Integer> grades; // 成绩表


  public Student(String id, String name) {
    this.id = id;
    this.name = name;
    this.grades = new HashMap<String, Integer>();
  }

public int getAverage(HashMap<String, Course> courses) {
    int sum = 0; // 总成绩和
    int count = 0; // 总课程数
    for (String courseName : grades.keySet()) {

      if (courses.containsKey(courseName)) {
        Course course = courses.get(courseName);
        int grade = grades.get(courseName);
        sum += grade * (1 - course.weight); // 加上期末成绩部分
        if (course.mode.equals("考试")) {
          sum += grade * course.weight; // 加上平时成绩部分
        }
        count++;
      }
    }
    if (count == 0) { // 如果没有任何课程,返回-1表示无效值
      return -1;
    } else { // 否则,返回总成绩平均分(只取整数部分)
      return sum / count;
    }
  }
}


class Class {
  // 定义班级的属性
  String id; // 班级号
  ArrayList<Student> students; // 学生列表


  public Class(String id) {
    this.id = id;
    this.students = new ArrayList<Student>();
  }


  public void addStudent(Student student) {
    boolean exist = false; // 标记学生是否已存在
    for (Student s : students) {
      if (s.id.equals(student.id)) { 
        exist = true;
        break;
      }
    }
    if (!exist) { // 如果不存在,添加到学生列表中
      students.add(student);
    }
  }

  
  public int getAverage(HashMap<String, Course> courses) {
    int sum = 0; // 总成绩和
    int count = 0; // 总学生数(有成绩的)
    for (Student student : students) {
      int average = student.getAverage(courses); // 计算每个学生的总成绩平均分
      if (average != -1) {
        sum += average;
        count++;
      }
    }
    if (count == 0) { 
      return -1;
    } else { 
      return sum / count;
    }
  }
}


public class Main {
public static boolean isInteger(String s) {
    try {
      Integer.parseInt(s); // 尝试转换为整数
      return true; // 如果成功,返回true
    } catch (NumberFormatException e) { // 如果失败,捕获异常
      return false; // 返回false
    }
  }

  public static boolean isGrade(String s) {
    if (isInteger(s)) { 
      int n = Integer.parseInt(s);
      return n >= 0 && n <= 100; // 如果在0-100之间,返回true
    } else { // 否则,返回false
      return false;
    }
  }

  public static boolean isStudentId(String s) {
    if (s.length() == 8 && isInteger(s)) { // 如果长度为8且是整数,返回true
      return true;
    } else { // 否则,返回false
      return false;
    }
  }


  public static boolean isName(String s) {
    if (s.length() <= 10) { // 如果长度不超过10,返回true
      return true;
    } else { // 否则,返回false
      return false;
    }
  }


  public static boolean isCourseName(String s) {
    if (s.length() <= 10) { 
      return true;
    } else { 
      return false;
    }
  }


  public static boolean isCourseType(String s) {
    if (s.equals("必修") || s.equals("选修")) { 
      return true;
    } else { // 否则,返回false
      return false;
    }
  }


  public static boolean isAccessMode(String s) {
    if (s.equals("考试") || s.equals("考察")) {
      return true;
    } else { 
      return false;
    }
  }


  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in); 

    HashMap<String, Course> courses = new HashMap<String, Course>();
    HashMap<String, Student> students = new HashMap<String, Student>(); 
    HashMap<String, C
HashMap<String, Student>(); // 创建一个学生表 HashMap<String, Class> classes = new HashMap<String, Class>(); // 创建一个班级表 System.out.println("请输入课程信息(输入end结束):"); while (true) { String line = scanner.nextLine(); // 输入一行课程信息 if (line.equals("end")) { // 如果输入end,退出循环 break; }
String[] parts = line.split(" "); // 按空格分割字符串 if (parts.length < 2 || parts.length > 3) { // 如果分割后的长度不是2或3,输出格式错误并继续循环 System.out.println("wrong format"); continue; } String courseName = parts[0]; // 获取课程名称
String courseType = parts[1]; // 获取课程性质 String accessMode = ""; // 初始化考核方式为空字符串 if (!isCourseName(courseName)) { // 如果

if (!isCourseName(courseName)) {
  System.out.println("wrong format");
  continue;
}
// 如果课程性质不合法,输出格式错误并继续循环
if (!isCourseType(courseType)) {
  System.out.println("wrong format");
  continue;
}

if (parts.length == 2) {
  if (courseType.equals("必修")) {
    accessMode = "考试";
  } else {
    accessMode = "考察";
  }
} else { 
  accessMode = parts[2];
}

if (!isAccessMode(accessMode)) {
  System.out.println("wrong format");
  continue;
}

if (courseType.equals("必修") && !accessMode.equals("考试")) {
  System.out.println(courseName + " : course type & access mode mismatch");
  continue;
}

if (courses.containsKey(courseName)) {
  continue;
}

Course course = new Course(courseName, courseType, accessMode);
courses.put(courseName, course);

 

 

 

2.6第三次作业2

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

 

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

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

输入格式:

输入两行,每行输入一个日期,日期格式如:2022-06-18

输出格式:

第一行输出:第一个日期比第二个日期更早(晚)
第二行输出:两个日期间隔XX天
第三行输出:两个日期间隔XX周

 

 本题的主要的难点是正则表达式判断输入的时间格式是否正确以及时间类的应用,这题难就难在对时间类的使用上,通过nextline对输入的字符串时间处理得到输入事件的年月日,判断时间的输入格式,j函数判断是否是闰年,最后在进行一系列判断输出我们想要的年月日格式。

 

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String StartDate = in.next();
        String EndDate = in.next();
        StartDate = judge(StartDate);
        EndDate = judge(EndDate);
        long Dateday = Math.abs(day(StartDate,EndDate));
        System.out.println("两个日期间隔" + Dateday + "天");
        System.out.println("两个日期间隔" + Dateday / 7 + "周");
    }
    public static String judge(String StartDate) {
        String[] arr = StartDate.split("-");  // 以/为分隔符,提取年月日
        int year = Integer.parseInt(arr[0]);   //转换为int型
        int mouth = Integer.parseInt(arr[1]);
        int day = Integer.parseInt(arr[2]);
        if(mouth < 10)
        if (mouth < 10 && day < 10) {
            StartDate = arr[0] + '-' + 0 + arr[1] + '-'+ 0 + arr[2];
        }
        else if(mouth < 10){
            StartDate = arr[0] + '-'+ 0 + arr[1] + '-'+ arr[2];
        }
        else if (day < 10)
            StartDate = arr[0]+ '-'+  arr[1] + '-' + 0 + arr[2];
        return StartDate;
    }

    public static long day(String StartDate, String EndDate){
        DateFormat dft;
            dft = new SimpleDateFormat("yyyy-MM-dd");
        try {
            LocalDate startDate = LocalDate.parse(StartDate);
            LocalDate endDate = LocalDate.parse(EndDate);
            if (endDate.isBefore(startDate))
                System.out.println("第一个日期比第二个日期更晚");
            else
                System.out.println("第一个日期比第二个日期更早");
            Date star = dft.parse(StartDate);
            Date endDay = dft.parse(EndDate);
            Long starTime = star.getTime();
            Long endTime = endDay.getTime();
            Long num = endTime - starTime;//haomiao
            num = num / 24 / 60 / 60 / 1000;
            return num;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }
    public static boolean isValidDate(String dttm,String format) {
        if (dttm == null || dttm.isEmpty() || format == null || format.isEmpty()) {
            return false;
        }
        if (format.replaceAll("'.+?'", "").indexOf("y") < 0) {
            format += "/yyyy";
            DateFormat formatter = new SimpleDateFormat("/yyyy");
            dttm += formatter.format(new Date());
        }
        String regex = "^\\d{4}\\-(0[1-9]|1[012])\\-(0[1-9]|[12][0-9]|3[01])$";
        if (!dttm.matches(regex)){
            return false;
        }
        DateFormat formatter = new SimpleDateFormat(format);
        formatter.setLenient(false);
        ParsePosition pos = new ParsePosition(0);
        Date date = formatter.parse(dttm, pos);
        if (date == null || pos.getErrorIndex() > 0) {
            return false;
        }
        if (pos.getIndex() != dttm.length()) {
            return false;
        }
        if (formatter.getCalendar().get(Calendar.YEAR) > 9999) {
            return false;
        }
        return true;

    }
}

(4)主要困难以及改进建议:

空指针异常;空指针就是空引用,java空指针异常就是引用本身为空,却调用了方法,这个时候就会出现空指针异常。可以理解,成员变量和方法是属于对象的(除去静态),在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法。对于空指针来说,它不指向任何对象,也就没有所谓的成员变量和方法,这个时候用它去调用某些属性和方法,自然就会出现空指针异常;这里的数组想通过C语言一样基本类型数组那样去赋值,但是那样写编译器总是抛出空引用(空指针)异常  ST u[i]在这里相当于还没有创建空间,导致指针指向为空。

解决方法:每次赋值之前,都通过构造器创建对象,因此避免了空指针的出现

 

对解题过程中自己遇到的困难进行分析,并对相应题目的编码改进给出自己的见解,做到可持续改进

(5)总结:

通过前三次JavaPTA的作业,我对Java编程有了更深入的理解和掌握。在这个过程中,我可以明显感觉到题目的难度在逐步增加,不断涉及到了一些新的知识点,如正则表达式、方法的重载和覆盖、类的继承和多态等,或者有些题目我不太熟悉如何使用这些知识点,有些题目我在调试时遇到了一些错误和异常,有些题目我在提交时没有通过所有的测试点。为了解决这些困难,我查阅了一些资料和教程,学习了一些相关的语法和用法完成题目。其次,我学到的知识和技能主要是在以下几个方面:一是对Java语言的基本语法和特性有了更深入的理解,如数据类型、运算符、流程控制、数组、字符串等;二是对Java中的面向对象编程有了更清晰的认识,如类和对象、封装和继承、多态和抽象等;三是对Java中的一些常用的类和方法有了更熟练的运用;四是对Java中的一些高级的特性和技巧有了更广泛的掌握,如正则表达式等,我还有一些不足和需要改进的地方比如变量命名不够清晰,有时候注释不够详细或者注释很少,有时候代码结构不够简洁代码逻辑还不够严谨和高效,有时候会出现一些逻辑错误或者冗余代码,圈复杂度也是比较高,此外是我的代码测试还不够充分和完善,有时候只考虑了正常输入或者输出,忽略一些边界条件或者特殊情况没有考虑到异常输入或者输出,在一些测试点是十分难通过,总之,通过这几次作业,我收获了很多新知识对Java编程有了更多的兴趣和信心,也对自己有了更多的反思和提升。我会继续努力学习,改正缺点,争取做得更好。