第一次博客作业
关于java面向对象编程
这学期刚开始接触java,老师直接从后面开始讲就表示前面的只是应该与上学期学习的c语言差不多,虽然还是有些不是很懂。
相较于C语言,java有点抽象,思维更灵活,语法更多,知识点也更多,从这三次作业就能看出,学好java绝对不是一件容易的事,需要花时间和精力去理解。
前言:
三次题目集,涉及了类和对象的创建与使用与基础的增删改查。
题量也是由多逐渐变少,虽然题少,但是题目的难度大,想拿高分非常难,尤其是每次作业的最后一题,都是70分往上的分值,测试点和要求也非常多,很多人都拿的0分。
设计与分析:
第一次作业:
1、
题目:
设计一个名为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"和风扇颜色以及半径组合成的字符串。
请在自己的草稿本上画出UML图,养成良好的设计习惯。
要求:创建两个Fan对象:
第一个对象利用无参构造方法构造默认风扇对象Fan1;
第二个对象依据输入的风扇属性,调用有参构造方法构造自定义风扇对象Fan2。
通过调用它们的toString方法显示这些对象。
输入格式:
第二个对象的属性
输出格式:
分别输出默认风扇和自定义风扇的速度、颜色、半径以及风扇是否打开
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Fan f1 = new Fan();
System.out.println("-------");
System.out.println("Default");
System.out.println("-------");
System.out.println(f1);
int speed = sc.nextInt();
boolean on = "True".equals(sc.next());
double radius = sc.nextDouble();
String color = sc.next();
Fan f2 = new Fan(speed,on,radius,color);
System.out.println("-------");
System.out.println("My Fan");
System.out.println("-------");
System.out.println(f2);
}
}
class Fan{
private final int SLOW = 1;
private final int MEDIUM = 2;
private final int FAST = 3;
private int speed = SLOW;
private boolean on = false;
private double radius = 5;
private String color = "white";
public Fan(int speed, boolean on, double radius, String color) {
this.speed = speed;
this.on = on;
this.radius = radius;
this.color = color;
}
public Fan() {
}
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 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 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;
}
}
2、
题目:
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.输出结果参考“输出样例”
输入格式:
请在这里写输入格式。例如:输入在一行中给出2个绝对值不超过1000的整数A和B。
输出格式:
姓名:Tom,性别:23,学号:20221201234,年龄:23,专业:计算机科学
代码:
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);
String name = scanner.nextLine();
String sex = scanner.nextLine();
int age = scanner.nextInt();
scanner.nextLine();
String major = scanner.nextLine();
String studentID = scanner.nextLine();
Student student = new Student(name, sex, studentID, age, major);
student.printInfo();
scanner.close();
}
}
3、
题目:
创建学生类,包含
属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)
方法:计算总分、计算平均分
输入5个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
浮点数保留小数的相关知识可参考:
https://blog.csdn.net/huaishuming/article/details/17752365
注意:未用学生类对象封装数据的,本题计0分
输入格式:
5个学生信息,每个学生信息格式:
学号+英文空格+姓名+英文空格+语文成绩+英文空格+数学成绩+英文空格+物理成绩
例如:
22201311 张琳 80 80 80
22201312 黄昊 66 82 81
22201313 李少辰 77 76 80
22201314 袁婷 62 79 90
22201315 朱哲一 74 98 94
输出格式:
5个学生信息,每个学生信息格式:
学号+英文空格+姓名+英文空格+总成绩+英文空格+平均分
代码:
import java.util.Scanner;
class Student {
private String studentID;
private String name;
private int chineseScore;
private int mathScore;
private int physicsScore;
public Student(String studentID, String name, int chineseScore, int mathScore, int physicsScore) {
this.studentID = studentID;
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((double) calculateTotalScore() / 3 * 100) / 100.0; // 保留两位小数
}
public String toString() {
    return studentID + " " + name + " " + calculateTotalScore() + " " + String.format("%.2f", calculateAverageScore());
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 5; i++) {
String line = scanner.nextLine();
String[] info = line.split(" ");
String studentID = info[0];
String name = info[1];
int chineseScore = Integer.parseInt(info[2]);
int mathScore = Integer.parseInt(info[3]);
int physicsScore = Integer.parseInt(info[4]);
Student student = new Student(studentID, name, chineseScore, mathScore, physicsScore);
System.out.println(student.toString());
}
    scanner.close();
}
}
4、
题目:
创建成绩类,包含:
属性:平时成绩(int)、期末成绩(int)
方法:计算总成绩(计算规则:平时成绩0.4+期末成绩0.6,保留整数部分,小数部分直接丢弃)
创建学生类,包含:
属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类)
方法:计算总分、计算平均分
输入3个学生的信息,将每个学生的信息封装在一个学生对象中。
按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。
浮点数保留小数的相关知识可参考:https://blog.csdn.net/huaishuming/article/details/17752365
注意:未用学生类对象封装数据的,本题计0分
输入格式:
依次输入3个学生的每门课成绩,每个学生成绩信息格式:
学号+英文空格+姓名+英文空格+课程名+英文空格+平时成绩+英文空格+期末成绩
注:3个学生的课程顺序可能会不一致
例如:
22201311 张琳 语文 70 80
22201311 张琳 数学 85 89
22201311 张琳 物理 75 83
22201312 黄昊 语文 66 78
22201312 黄昊 数学 76 82
22201312 黄昊 物理 83 82
22201313 李少辰 语文 86 76
22201313 李少辰 数学 78 76
22201313 李少辰 物理 87 76
输出格式:
3个学生信息,每个学生信息格式:
学号+英文空格+姓名+英文空格+总成绩+英文空格+平均分
例如:
22201311 张琳 242 80.67
22201312 黄昊 234 78.00
22201313 李少辰 236 78.67
代码:
import java.util.Scanner;
class Grades{
private int ugrade;
private int fgrade;
public Grades(int ugrade,int fgrade)
{
this.ugrade=ugrade;
this.fgrade=fgrade;
}
public int getugrade()
{
return ugrade;
}
public int getfgrade()
{
return fgrade;
}
public int Tgrades()
{
return (int)(ugrade0.4+fgrade0.6);
}
}
class Student
{
private String id;
private String name;
private Grades yuwenscore;
private Grades shuxuescore;
private Grades wuliscore;
public Student(String id,String name)
{
this.id=id;
this.name= name;
}
public String getID()
{
return id;
}
public String getname()
{
return name;
}
public Grades getMathscore()
{
return shuxuescore;
}
public void setMathscore(Grades shuxuescore)
{
this.shuxuescore = shuxuescore;
}
public Grades getPhyscore()
{
return wuliscore;
}
public void setPhyscore(Grades wuliscore)
{
this.wuliscore = wuliscore;
}
public Grades getCnscore()
{
return yuwenscore;
}
public void setCnscore(Grades yuwenscore)
{
this.yuwenscore = yuwenscore;
}
public int getallscore()
{
return yuwenscore.Tgrades()+shuxuescore.Tgrades()+wuliscore.Tgrades();
}
public double getavgscore()
{
double sum=yuwenscore.Tgrades()+shuxuescore.Tgrades()+wuliscore.Tgrades();
return (double)(sum/3);
}
public double getuavgscore()
{
double sum=yuwenscore.getugrade()+shuxuescore.getugrade()+wuliscore.getugrade();
return (double)(sum/3);
}
public double getfavgscore()
{
double sum=yuwenscore.getfgrade()+shuxuescore.getfgrade()+wuliscore.getfgrade();
return (double)(sum/3);
}
}
public class Main
{
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
Student[] stu=new Student[3];
Grades[] stu1=new Grades[3];
int count=0;
for(int i=0;i<9;i++)
{
String id= sc.next();
String name = sc.next();
String km = sc.next();
int ugrade= sc.nextInt();
int fgrade =sc.nextInt();
int j=i%3;
if(j0)
{
stu[count]=new Student(id,name);
stu[count].setCnscore(new Grades(ugrade,fgrade));
}
if(j1)
{
stu[count].setMathscore(new Grades(ugrade,fgrade));
}
if(j==2)
{
stu[count].setPhyscore(new Grades(ugrade,fgrade));
count++;
}
}
for(int j=0;j<3;j++)
{
System.out.println(stu[j].getID()+" "+stu[j].getname()+" " + stu[j].getallscore() + " " + String.format("%.2f %.2f %.2f", stu[j].getuavgscore(),stu[j].getfavgscore(),stu[j].getavgscore()));
}
}
}
5、
题目:
设计实现答题程序,模拟一个小型的测试,要求输入题目信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。
输入格式:
程序输入信息分三部分:
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"之后的信息忽略。
输出格式:
1、题目数量
格式:整数数值,若超过1位最高位不能为0,
样例:34
2、答题信息
一行为一道题的答题信息,根据题目的数量输出多行数据。
格式:题目内容+" ~"+答案
样例:1+1=~2
      2+2= ~4
3、判题信息
判题信息为一行数据,一条答题记录每个答案的判断结果,答案的先后顺序与题目题号相对应。
格式:判题结果+" "+判题结果
格式约束:
 1、判题结果输出只能是true或者false,
 2、判题信息的顺序与输入答题信息中的顺序相同
样例:true false true
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int questionCount = Integer.parseInt(scanner.nextLine());
Map<Integer, String> questionMap = new HashMap<>();
for (int i = 0; i < questionCount; i++) {
String line = scanner.nextLine();
String[] parts = line.split(" ");
int questionNumber = Integer.parseInt(parts[1]);
String questionContent = parts[3];
String answer = parts[5];
questionMap.put(questionNumber, questionContent + " ~" + answer);
}
List
String answerLine = scanner.nextLine();
while (!answerLine.equals("end")) {
studentAnswers.add(answerLine);
answerLine = scanner.nextLine();
}
String[] results = new String[questionCount];
for (String answer : studentAnswers) {
String[] parts = answer.split(" ");
for (int i = 0; i < parts.length; i++) {
if (!parts[i].equals("#A:")) {
int questionNumber = i + 1;
String studentAnswer = parts[i];
String correctAnswer = questionMap.get(questionNumber).split("~")[1].trim();
boolean result = studentAnswer.equals(correctAnswer);
results[i] = result ? "true" : "false";
}
}
}
System.out.println(questionCount);
for (int i = 1; i <= questionCount; i++) {
System.out.println(questionMap.get(i));
}
System.out.println(String.join(" ", results));
}
}
第二次作业:
1、
题目:
编写手机类(MobilePhone),含有type(型号,String类型)、price(价格,int类型)属性,要求该类实现Comparable接口,重写compareTo方法,实现按照price的大小来确定两个手机对象的大小关系。
在链表中添加三个手机对象(从键盘输入),通过Collections类的sort方法对链表中的对象按照price升序排序。输入第四个手机对象的信息,并查找它的price是否与链表中某个对象的price相同。
输入格式:
先输入三部手机的型号、价格信息
再输入要查找的第四部手机的型号、价格信息
每部手机信息的格式如:Redmi9A 599
输出格式:
先输出三部手机排序前的信息
再输出三部手机排序后的信息
最后输出第四部手机是否与前面某部手机价格相同
具体格式参考输出样例
代码:
import java.util.*;
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 int getPrice() {
    return price;
}
public int compareTo(MobilePhone other) {
    return Integer.compare(this.price, other.price);
}
public String toString() {
    return "型号:" + type + ",价格:" + price;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
    List<MobilePhone> phones = new LinkedList<>();
    for (int i = 0; i < 3; i++) {
        String input = scanner.nextLine();
        String[] parts = input.split("\\s+");
        
        MobilePhone phone = new MobilePhone(parts[0], Integer.parseInt(parts[1]));
        phones.add(phone);
    }
    System.out.println("排序前,链表中的数据:");
    for (MobilePhone phone : phones) {
        System.out.println(phone);
    }
    Collections.sort(phones);
    System.out.println("排序后,链表中的数据:");
    for (MobilePhone phone : phones) {
        System.out.println(phone);
    }
    String input = scanner.nextLine();
    String[] parts = input.split("\\s+");
    
    MobilePhone fourthPhone = new MobilePhone(parts[0], Integer.parseInt(parts[1]));
    boolean found = false;
    for (MobilePhone phone : phones) {
        if (phone.getPrice() == fourthPhone.getPrice()) {
            found = true;
            System.out.println(fourthPhone.getType() + "与链表中的" + phone.getType() + "价格相同");
            break;
        }
    }
    if (!found) {
        System.out.println("链表中的对象,没有一个与" + fourthPhone.getType() + "价格相同的");
    }
}
}
2、
题目:
按要求完成程序的编写。
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的面积后输出。
输入格式:
输入有多行。每行包括一个整数的圆的半径。
输出格式:
按照题目要求,输出圆构造方法的输出信息、圆对象的字符中描述信息、及圆的面积(其中圆的面积保留2位小数)。上述信息各占一行。
代码:
import java.util.Scanner;
class Circle {
private int radius;
public Circle() {
    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
    Circle c2 = new Circle();
    System.out.println(c2);
    System.out.printf("%.2f\n", c2.getArea());
    int radius = scanner.nextInt();
    c2.setRadius(radius);
    System.out.println(c2);
    System.out.printf("%.2f\n", c2.getArea());
    radius = scanner.nextInt();
    Circle c3 = new Circle(radius);
    System.out.println(c3);
    System.out.printf("%.2f\n", c3.getArea());
    scanner.close();
}
}
3、
题目:
设计一个用来描述汽车的类,使用类的非静态成员变量来表示汽车的车主姓名、当前的速率和当前方向盘的转向角度,使用类的非静态成员方法来表示改变汽车的速率和停车两个操作。在下图中的【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】
}
}
输入格式:
无
输出格式:
车主:bob,速度:0.0,角度:0.0
车主:bob,速度:10.0,角度:0.0
车主:bob,速度:0.0,角度:0.0
输入样例:
在这里给出一组输入。例如:
输出样例:
在这里给出相应的输出。例如:
车主:bob,速度:0.0,角度:0.0
车主:bob,速度:10.0,角度:0.0
车主:bob,速度:0.0,角度:0.0
代码:
public class Main {
public static void main(String[] args) {
Car car = new Car("bob");
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());
}
}
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 newSpeed) {
if (newSpeed >= 0) {
curSpeed = newSpeed;
}
}
public void stop() {
curSpeed = 0;
}
}
4、
题目:
设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-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"之后的信息忽略。
输出格式:
1、试卷总分警示
该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100分,该部分忽略,不输出。
格式:"alert: full score of test paper"+试卷号+" is not 100 points"
样例:alert: full score of test paper2 is not 100 points
2、答卷信息
一行为一道题的答题信息,根据试卷的题目的数量输出多行数据。
格式:题目内容+""+答案++""+判题结果(true/false)
约束:如果输入的答案信息少于试卷的题目数量,答案的题目要输"answer is null"
样例:3+2=5true
     4+6=~22~false.
  answer is null
3、判分信息
判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。
格式:题目得分+" "+....+题目得分+"~"+总分
格式约束:
1、没有输入答案的题目计0分
2、判题信息的顺序与输入答题信息中的顺序相同
样例:5 8 0~13
根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。
4、提示错误的试卷号
如果答案信息中试卷的编号找不到,则输出”the test paper number does not exist”,参见样例9。
设计建议:
参考答题判题程序-1,建议增加答题类,类的内容以及类之间的关联自行设计。
代码:
import java.util.*;
class Question {
private int number;
private String content;
private String answer;
public Question(int number, String content, String answer) {
    this.number = number;
    this.content = content;
    this.answer = answer;
}
public int getNumber() {
    return number;
}
public String getContent() {
    return content;
}
public String getAnswer() {
    return answer;
}
}
class TestPaper {
private int number;
private Map<Integer, Integer> questionScores;
public TestPaper(int number, Map<Integer, Integer> questionScores) {
    this.number = number;
    this.questionScores = questionScores;
}
public int getNumber() {
    return number;
}
public Map<Integer, Integer> getQuestionScores() {
    return questionScores;
}
}
class AnswerSheet {
private int testPaperNumber;
private List
public AnswerSheet(int testPaperNumber, List<String> answers) {
    this.testPaperNumber = testPaperNumber;
    this.answers = answers;
}
public int getTestPaperNumber() {
    return testPaperNumber;
}
public List<String> getAnswers() {
    return answers;
}
}
public class TestProgram {
private List
private List
private List
public void addQuestion(int number, String content, String answer) {
    Question question = new Question(number, content, answer);
    questions.add(question);
}
public void addTestPaper(int number, Map<Integer, Integer> questionScores) {
    TestPaper testPaper = new TestPaper(number, questionScores);
    testPapers.add(testPaper);
}
public void addAnswerSheet(int testPaperNumber, List<String> answers) {
    AnswerSheet answerSheet = new AnswerSheet(testPaperNumber, answers);
    answerSheets.add(answerSheet);
}
public void process() {
    for (AnswerSheet answerSheet : answerSheets) {
        int testPaperNumber = answerSheet.getTestPaperNumber();
        List<String> answers = answerSheet.getAnswers();
        TestPaper testPaper = getTestPaperByNumber(testPaperNumber);
        if (testPaper == null) {
            System.out.println("the test paper number does not exist");
            continue;
        }
        Map<Integer, Integer> questionScores = testPaper.getQuestionScores();
        int totalScore = 0;
        for (int i = 0; i < answers.size(); i++) {
            String answer = answers.get(i);
            int questionNumber = i + 1;
            int score = questionScores.getOrDefault(questionNumber, 0);
            String standardAnswer = getStandardAnswer(questionNumber);
            boolean correct = answer.equals(standardAnswer);
            if (correct) {
                totalScore += score;
            }
            System.out.println(questionNumber + "~" + answer + "~" + correct);
        }
        System.out.println(totalScore);
    }
}
private TestPaper getTestPaperByNumber(int number) {
    for (TestPaper testPaper : testPapers) {
        if (testPaper.getNumber() == number) {
            return testPaper;
        }
    }
    return null;
}
private String getStandardAnswer(int questionNumber) {
    for (Question question : questions) {
        if (question.getNumber() == questionNumber) {
            return question.getAnswer();
        }
    }
    return "";
}
public static void main(String[] args) {
    TestProgram testProgram = new TestProgram();
    testProgram.addQuestion(1, "1+1=", "2");
    testProgram.addQuestion(2, "2+2=", "4");
    Map<Integer, Integer> questionScores1 = new HashMap<>();
    questionScores1.put(1, 5);
    questionScores1.put(2, 8);
    testProgram.addTestPaper(1, questionScores1);
    List<String> answers = new ArrayList<>();
    answers.add("2");
    answers.add("4");
    testProgram.addAnswerSheet(1, answers);
    testProgram.process();
}
}
第三次作业:
1、
题目:
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();
}
}
/* 请在这里填写答案 */
输入格式:
无
输出格式:
学号:6020203110,姓名:王宝强,年龄:21,专业:计算机科学与技术
学号:6020203119,姓名:张三丰,年龄:23,专业:软件工程
代码:
import java.util.Scanner;
class Student {
private String sid;
private String name;
private int age;
private String major;
public Student() {
}
public Student(String sid, String name, int age, String major) {
    this.sid = sid;
    this.name = name;
    if (age > 0) {
        this.age = age;
    }
    this.major = major;
}
public void setSid(String sid) {
    this.sid = sid;
}
public String getSid() {
    return sid;
}
public void setName(String name) {
    this.name = name;
}
public String getName() {
    return name;
}
public void setAge(int age) {
    if (age > 0) {
        this.age = age;
    }
}
public int getAge() {
    return age;
}
public void setMajor(String major) {
    this.major = major;
}
public String getMajor() {
    return major;
}
public void print() {
    System.out.println("学号:" + sid + ",姓名:" + name + ",年龄:" + age + ",专业:" + major);
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
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.print();
student2.print();
}
}
2、
题目:
给定一个日期,判定是否为合法日期。如果合法,判断该年是否闰年,该日期是当年第几天、当月第几天、当周第几天、。
给定起始日期与结束日期,判定日期是否合法且结束日期是否早于起始日期。如果均合法,输出结束日期与起始日期之间的相差的天数、月数、念书。
输入格式:
第一行输入一个日期字符串,格式为"YYYY-MM-dd"
第二行输入两个日期字符串,中间使用空格隔开。分别代表开始日期与结束日期。
输出格式:
如果第一行日期字符串非法,输出自定义的错误信息。
如果第一行日期有效,输出相关信息,如果是闰年要输出是闰年。
如果第二行两个日期,只要有一个无效。就输出相关错误信息。
如果第二行两个日期有效且结束日期不早于开始日期,输出相关信息。
代码:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.Year;
import java.util.Calendar;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.regex.Pattern;
    public class Main {
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            String line = input.nextLine();
            String nextLine = input.nextLine();//输入日期 格式为2020/3/21
            String[] arr = line.split("-");  // 以/为分隔符,提取年月日
            int year = Integer.parseInt(arr[0]);   //转换为int型
            int mouth = Integer.parseInt(arr[1]);
            int day = Integer.parseInt(arr[2]);
            boolean valid=Main.isValidDate(line,"yyyy-MM-dd");
            if ((judge(year,mouth,day)==true)&&valid==true){
                Calendar c = Calendar.getInstance();
                //这里有bug必须减1
                c.set(year, mouth-1, day); // 设置年月日,时分秒将默认采用当前值
                int weekDay = c.get(Calendar.DAY_OF_WEEK);
                int monthDay = c.get(Calendar.DAY_OF_MONTH);
                int yearDay = c.get(Calendar.DAY_OF_YEAR);
                if (weekDay == 1) {
                    weekDay = 7;
                } else {
                    weekDay = weekDay - 1;
                }
                Year firstYear = Year.of(year);
                if (firstYear.isLeap()){
                    System.out.println(line+"是闰年.");
                }
                System.out.println(line+"是当年第"+yearDay+"天" +",当月第"+monthDay+
                        "天,当周第"+weekDay+"天.");
            }else {
                System.out.println(line+"无效!");
            }
            String[] arr1 = nextLine.split(" ");
            boolean valid1=Main.isValidDate(arr1[0],"yyyy-MM-dd");
            boolean valid2=Main.isValidDate(arr1[1],"yyyy-MM-dd");
            if (valid1==false||valid2==false){
                System.out.println(arr1[0]+"或"+arr1[1]+"中有不合法的日期.");
                System.exit(0);
            }
            DateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date star = dft.parse(arr1[0]);//开始时间
                String[] st1=arr1[0].split("-");
                int t1=Integer.parseInt(st1[1]);
                int t11=Integer.parseInt(st1[0]);
                String[] st2=arr1[1].split("-");
                int t2=Integer.parseInt(st2[1]);
                int t22=Integer.parseInt(st2[0]);
                Date end = dft.parse(arr1[1]);
                int i1=0;
                int i2=0;
                int i3=0;
                if (star.before(end)){
                    Year firstYear = Year.of(t11);
                    i3=t22-t11;
                    Calendar c1 = Calendar.getInstance();
                    //这里有bug必须减1
                    c1.set(t11, t1-1, Integer.parseInt(st1[2])); // 设置年月日,时分秒将默认采用当前值
                    int yearDay = c1.get(Calendar.DAY_OF_YEAR);
                    Calendar c2 = Calendar.getInstance();
                    //这里有bug必须减1
                    c2.set(t22, t2-1, Integer.parseInt(st2[2])); // 设置年月日,时分秒将默认采用当前值
                    int yearDa2y = c2.get(Calendar.DAY_OF_YEAR);
                    if (firstYear.isLeap(t11)){
                        int temp=yearDa2y+(366-yearDay);
                        for (int i=t11+1;i<t22;i++){
                            if (firstYear.isLeap(i)){
                                i1=i1+366;
                            }else {
                                i1=i1+365;
                            }
                        }
                        i1=i1+temp;
                    }else {
                                                    int temp=yearDa2y+(365-yearDay);
                        for (int i=t11+1;i<t22;i++){
                            if (firstYear.isLeap(i)){
                                i1=i1+366;
                            }else {
                                i1=i1+365;
                            }
                        }
                        i1=i1+temp;
                    }
                    i2=Integer.parseInt(st2[1])-Integer.parseInt(st1[1]);
                }
                if (end.before(star)){
                    System.out.println(arr1[1]+"早于"+arr1[0]+",不合法!");
                    System.exit(0);
                }
                if ((judge(t11,t1,Integer.parseInt(st1[2]))==true)&&judge(t22,t2,Integer.parseInt(st2[2]))==true){
                    System.out.println(arr1[1]+"与"+arr1[0]+"之间相差"+i1+"天,"+"所在月份相差"+i2+",所在年份相差"+i3+".");
                }else {
                    System.out.println(arr1[0]+"或"+arr1[1]+"中有不合法的日期.");
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        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;
        }
        public static boolean judge(int y,int sum,int date) {
            boolean count=false;
            if(sum==1||sum==3||sum==5||sum==7||sum==8||sum==10||sum==12) {
                if(date<=31) {
                    count = true;}
                else {
                    count = false;
                }
            }
            else if(sum<1||sum>12) {
                count=false;}
            else if(sum==2) {
                if(y%400==0||(y%4==0&&y%100!=0)) {
                    if(date>29) {
                        count=false;
                    }
                    else {
                        count = true;
                    }
                }
                else {
                    if(date>28) {
                        count=false;
                    }
                    else{
                        count=true;
                    }
                }
            }
            else {
                if(date>30) {
                    count = false;
                }
                else{
                    count = true;
                }
            }
            return count;
        }
    }
3、
题目:
设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-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"之后的信息忽略。
输出格式:
1、试卷总分警示
该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100 分,该部分忽略,不输出。
格式:"alert: full score of test paper"+试卷号+" is not 100 points"
样例:alert: full score of test paper2 is not 100 points
2、答卷信息
一行为一道题的答题信息,根据试卷的题目的数量输出多行数据。
格式:题目内容+""+答案++""+判题结果(true/false)
约束:如果输入的答案信息少于试卷的题目数量,答案的题目要输"answer is null"
样例:
3+2=5true
4+6=22false.
answer is null
3、判分信息
判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。
格式:**学号+" "+姓名+": "**+题目得分+" "+....+题目得分+"~"+总分
格式约束:
 1、没有输入答案的题目、被删除的题目、答案错误的题目计0分
 2、判题信息的顺序与输入答题信息中的顺序相同
样例:20201103 Tom: 0 0~0
   根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。
4、被删除的题目提示信息
当某题目被试卷引用,同时被删除时,答案中输出提示信息。样例见第5种输入信息“删除题目信息”。
5、题目引用错误提示信息
试卷错误地引用了一道不存在题号的试题,在输出学生答案时,提示”non-existent question~”加答案。例如:
输入:
N:1 #Q:1+1= #A:2
T:1 3-8
X:20201103 Tom-20201104 Jack-20201105 Www
S:1 20201103 #A:1-4
end
输出:
alert: full score of test paper1 is not 100 points
non-existent question~0
20201103 Tom: 0~0
如果答案输出时,一道题目同时出现答案不存在、引用错误题号、题目被删除,只提示一种信息,答案不存在的优先级最高,例如:
输入:
N:1 #Q:1+1= #A:2
T:1 3-8
X:20201103 Tom-20201104 Jack-20201105 Www
S:1 20201103
end
输出:
alert: full score of test paper1 is not 100 points
answer is null
20201103 Tom: 0~0
6、格式错误提示信息
输入信息只要不符合格式要求,均输出”wrong format:”+信息内容。
  例如:wrong format:2 #Q:2+2= #4
7、试卷号引用错误提示输出
如果答卷信息中试卷的编号找不到,则输出”the test paper number does not exist”,答卷中的答案不用输出,参见样例8。
8、学号引用错误提示信息
如果答卷中的学号信息不在学生列表中,答案照常输出,判分时提示错误。参见样例9。
本题暂不考虑出现多张答卷的信息的情况。
代码:
import java.util.*;
class TestPaper {
int totalScore = 0;
Map<Integer, Integer> questionScores = new HashMap<>();
}
class Student {
String name;
Map<Integer, String> answers = new HashMap<>();
int totalScore = 0;
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<Integer, String> questions = new HashMap<>();
Map<Integer, TestPaper> testPapers = new HashMap<>();
Map<Integer, Student> students = new HashMap<>();
Set
    while (scanner.hasNextLine()) {
        String line = scanner.nextLine().trim();
        if (line.equals("end")) {
            break;
        }
        String[] parts = line.split("\\s+");
        String type = parts[0];
        switch (type) {
            case "#N:":
                int questionNumber = Integer.parseInt(parts[1]);
                String questionText = parts[3];
                questions.put(questionNumber, questionText);
                break;
            case "#T:":
                int paperNumber = Integer.parseInt(parts[1]);
                TestPaper paper = new TestPaper();
                for (int i = 2; i < parts.length; i++) {
                    String[] qScore = parts[i].split("-");
                    int qNumber = Integer.parseInt(qScore[0]);
                    int score = Integer.parseInt(qScore[1]);
                    paper.totalScore += score;
                    paper.questionScores.put(qNumber, score);
                }
                testPapers.put(paperNumber, paper);
                break;
            case "#X:":
                for (int i = 1; i < parts.length; i++) {
                    String[] studentInfo = parts[i].split("-");
                    int studentId = Integer.parseInt(studentInfo[1]);
                    String studentName = studentInfo[0];
                    Student student = new Student();
                    student.name = studentName;
                    students.put(studentId, student);
                }
                break;
            case "#S:":
                int paperId = Integer.parseInt(parts[1]);
                int studentId = Integer.parseInt(parts[2]);
                Student student = students.get(studentId);
                for (int i = 3; i < parts.length; i++) {
                    String[] answer = parts[i].split("-");
                    int qNumber = Integer.parseInt(answer[0]);
                    String qAnswer = answer[1];
                    student.answers.put(qNumber, qAnswer);
                }
                break;
            case "#D:":
                String[] deleteInfo = parts[1].split("-");
                int deleteQNumber = Integer.parseInt(deleteInfo[1]);
                deletedQuestions.add(deleteQNumber);
                break;
        }
    }
    for (Map.Entry<Integer, Student> entry : students.entrySet()) {
        int studentId = entry.getKey();
        Student student = entry.getValue();
        int totalScore = 0;
        for (Map.Entry<Integer, String> answerEntry : student.answers.entrySet()) {
            int qNumber = answerEntry.getKey();
            String studentAnswer = answerEntry.getValue();
            if (deletedQuestions.contains(qNumber)) {
                studentAnswer = "invalid";
                totalScore += 0;
            } else {
                String correctAnswer = questions.getOrDefault(qNumber, "");
                int score = 0;
                if (correctAnswer.equals(studentAnswer)) {
                    score = testPapers.get(1).questionScores.getOrDefault(qNumber, 0);
                    totalScore += score;
                }
            }
            student.totalScore = totalScore;
        }
    }
    for (Map.Entry<Integer, Student> entry : students.entrySet()) {
        int studentId = entry.getKey();
        Student student = entry.getValue();
        System.out.print(student.name + ": ");
        for (Map.Entry<Integer, String> answerEntry : student.answers.entrySet()) {
            int qNumber = answerEntry.getKey();
            String studentAnswer = answerEntry.getValue();
            if (deletedQuestions.contains(qNumber)) {
                System.out.print("the question " + qNumber + " " + studentAnswer + "~0 ");
            } else {
                String correctAnswer = questions.getOrDefault(qNumber, "");
                boolean isCorrect = correctAnswer.equals(studentAnswer);
                System.out.print(questions.get(qNumber) + "~" + studentAnswer + "~" + isCorrect + " ");
            }
        }
        System.out.println("~" + student.totalScore);
    }
    for (Map.Entry<Integer, TestPaper> entry : testPapers.entrySet()) {
        int paperNumber = entry.getKey();
        TestPaper paper = entry.getValue();
        if (paper.totalScore != 100) {
            System.out.println("alert: full score of test paper" + paperNumber + " is not 100 points");
        }
    }
}
}
踩坑心得:
1、
答题信息的结束标记:容易忘记检查答题信息的结束标记,导致程序陷入死循环或者读取过多的答案信息。
2、
输入输出格式的一致性:容易忘记确保输出格式与题目要求一致,导致格式错误。
3、
题目编号与题目内容的解析:在addQuestion方法中,错误地解析题目编号和内容,导致题目信息存储错误。
4、
标准答案的判断:在getStandardAnswer方法中忘记根据题号查询标准答案,而是硬编码标准答案,导致答案判断错误。
5、
答题信息的结束标记:在process方法中,可能会忘记检查答题信息的结束标记"end",导致程序陷入死循环或者读取过多的答案信息。
改进建议:
作业一
1、
错误处理:在读取输入时,应该考虑到可能出现的异常情况,例如题目数量输入不合法或答题信息不完整等情况。
2、
可读性和可维护性:可以将一些功能模块化,例如将读取题目和答题信息的部分封装成方法,提高代码的可读性和可维护性。
3、
更好的标准答案处理方式:标准答案应该根据题目编号来确定,可以使用一个Map或者其他数据结构来存储标准答案,而不是硬编码。
改进后的作业一:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
    // 输入题目数量
    int questionCount = Integer.parseInt(scanner.nextLine().trim());
    // 读取题目信息
    Map<Integer, String> questions = readQuestions(scanner, questionCount);
    // 读取答题信息
    List<String> answers = readAnswers(scanner);
    // 输出题目数量
    System.out.println(questionCount);
    // 输出答题信息
    printAnswers(questions, answers);
    // 判断答题结果并输出
    printResults(questions, answers);
    scanner.close();
}
private static Map<Integer, String> readQuestions(Scanner scanner, int questionCount) {
    Map<Integer, String> questions = new HashMap<>();
    for (int i = 0; i < questionCount; i++) {
        String line = scanner.nextLine().trim();
        String[] parts = line.split(" ");
        int number = Integer.parseInt(parts[0].substring(4));
        String content = parts[1].substring(3);
        questions.put(number, content);
    }
    return questions;
}
private static List<String> readAnswers(Scanner scanner) {
    List<String> answers = new ArrayList<>();
    String answerLine = scanner.nextLine().trim();
    while (!answerLine.equals("end")) {
        answers.add(answerLine.substring(4));
        answerLine = scanner.nextLine().trim();
    }
    return answers;
}
private static void printAnswers(Map<Integer, String> questions, List<String> answers) {
    for (Map.Entry<Integer, String> entry : questions.entrySet()) {
        int number = entry.getKey();
        String content = entry.getValue();
        String answer = answers.get(number - 1);
        System.out.println(content + " ~" + answer);
    }
}
private static void printResults(Map<Integer, String> questions, List<String> answers) {
    for (int i = 0; i < answers.size(); i++) {
        String answer = answers.get(i);
        int number = i + 1;
        String standardAnswer = questions.containsKey(number) ? questions.get(number) : "";
        boolean correct = answer.equals(standardAnswer);
        System.out.print(correct + " ");
    }
}
}
作业二
1、
异常处理:在读取输入时,可以添加异常处理来处理可能的输入格式错误或者输入不完整的情况,比如 NumberFormatException 和 NoSuchElementException。
2、
更好的输入提示:可以在读取输入时给用户更好的提示信息,指导用户如何正确输入数据。
3、
使用更具表现力的数据结构:考虑使用更具表现力和语义化的数据结构来表示题目、试卷和答题信息,例如使用自定义的类来表示题目、试卷和答卷。
4、
代码重构:根据需要对代码进行重构,提高代码的清晰度和可维护性。
5、
更好的错误处理:在发现错误时,给出更具体的错误信息,帮助用户理解并解决问题。
改进后的作业二:
import java.util.*;
// 题目类
class Question {
private int number;
private String content;
private String answer;
public Question(int number, String content, String answer) {
    this.number = number;
    this.content = content;
    this.answer = answer;
}
public int getNumber() {
    return number;
}
public String getContent() {
    return content;
}
public String getAnswer() {
    return answer;
}
}
// 试卷类
class TestPaper {
private int number;
private Map<Integer, Integer> questionScores;
public TestPaper(int number, Map<Integer, Integer> questionScores) {
    this.number = number;
    this.questionScores = questionScores;
}
public int getNumber() {
    return number;
}
public Map<Integer, Integer> getQuestionScores() {
    return questionScores;
}
}
// 答卷类
class AnswerSheet {
private int testPaperNumber;
private List
public AnswerSheet(int testPaperNumber, List<String> answers) {
    this.testPaperNumber = testPaperNumber;
    this.answers = answers;
}
public int getTestPaperNumber() {
    return testPaperNumber;
}
public List<String> getAnswers() {
    return answers;
}
}
public class Main {
private List
private List
private List
public void addQuestion(int number, String content, String answer) {
    Question question = new Question(number, content, answer);
    questions.add(question);
}
public void addTestPaper(int number, Map<Integer, Integer> questionScores) {
    TestPaper testPaper = new TestPaper(number, questionScores);
    testPapers.add(testPaper);
}
public void addAnswerSheet(int testPaperNumber, List<String> answers) {
    AnswerSheet answerSheet = new AnswerSheet(testPaperNumber, answers);
    answerSheets.add(answerSheet);
}
public void process() {
    for (AnswerSheet answerSheet : answerSheets) {
        int testPaperNumber = answerSheet.getTestPaperNumber();
        List<String> answers = answerSheet.getAnswers();
        TestPaper testPaper = getTestPaperByNumber(testPaperNumber);
        if (testPaper == null) {
            System.out.println("the test paper number does not exist");
            continue;
        }
        Map<Integer, Integer> questionScores = testPaper.getQuestionScores();
        int totalScore = 0;
        for (int i = 0; i < answers.size(); i++) {
            String answer = answers.get(i);
            int questionNumber = i + 1;
            int score = questionScores.getOrDefault(questionNumber, 0);
            String standardAnswer = getStandardAnswer(questionNumber);
            boolean correct = answer.equals(standardAnswer);
            System.out.println(questionNumber + "~" + answer + "~" + correct);
            if (correct) {
                totalScore += score;
            }
        }
        System.out.println(totalScore);
    }
}
private TestPaper getTestPaperByNumber(int number) {
    for (TestPaper testPaper : testPapers) {
        if (testPaper.getNumber() == number) {
            return testPaper;
        }
    }
    return null;
}
private String getStandardAnswer(int questionNumber) {
    for (Question question : questions) {
        if (question.getNumber() == questionNumber) {
            return question.getAnswer();
        }
    }
    return "";
}
public static void main(String[] args) {
    Main testProgram = new Main(); // 创建 Main 类的实例
    // 添加题目信息
    testProgram.addQuestion(1, "1+1=", "2");
    testProgram.addQuestion(2, "2+2=", "4");
    // 添加试卷信息
    Map<Integer, Integer> questionScores1 = new HashMap<>();
    questionScores1.put(1, 5);
    questionScores1.put(2, 8);
    testProgram.addTestPaper(1, questionScores1);
    // 添加答卷信息
    List<String> answers = new ArrayList<>();
    answers.add("2");
    answers.add("4");
    testProgram.addAnswerSheet(1, answers);
    testProgram.process();
}
}
作业三:
1、
变量命名:变量名应该具有描述性,让人一看就知道其作用。例如,可以将qNumber改为questionNumber,isCorrect改为correct等。
2、
代码重复:有一些代码逻辑可以抽取成方法来复用,比如判断学生答案是否正确的逻辑可以抽取成方法。
3、
逻辑简化:在判断学生答案是否正确时,可以使用三元运算符来简化代码,避免使用不必要的if-else结构。
4、
异常处理:在处理输入时,应该考虑到可能出现的异常情况,比如转换整数时可能会出现NumberFormatException。
5、
代码风格:建议遵循统一的代码风格,比如缩进、代码布局等,使代码更易读。
6、
优化循环:在遍历students和testPapers时,可以使用增强的for循环来简化代码。
7、
错误处理:在处理题目和答案时,应该考虑到可能出现的错误情况,比如题目编号不存在、答案为空等情况。
8、
性能优化:在处理题目和答案时,应该尽量避免不必要的循环和查找操作,可以考虑使用HashMap等数据结构来提高效率。
改进后的作业三:
import java.util.*;
class TestPaper {
int totalScore = 0;
Map<Integer, Integer> questionScores = new HashMap<>();
}
class Student {
String name;
Map<Integer, String> answers = new HashMap<>();
int totalScore = 0;
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<Integer, String> questions = new HashMap<>();
Map<Integer, TestPaper> testPapers = new HashMap<>();
Map<Integer, Student> students = new HashMap<>();
Set
    try {
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            if (line.equals("end")) {
                break;
            }
            String[] parts = line.split("\\s+");
            String type = parts[0];
            switch (type) {
                case "#N:":
                    int questionNumber = Integer.parseInt(parts[1]);
                    String questionText = parts[3];
                    questions.put(questionNumber, questionText);
                    break;
                case "#T:":
                    int paperNumber = Integer.parseInt(parts[1]);
                    TestPaper paper = new TestPaper();
                    for (int i = 2; i < parts.length; i++) {
                        String[] qScore = parts[i].split("-");
                        int qNumber = Integer.parseInt(qScore[0]);
                        int score = Integer.parseInt(qScore[1]);
                        paper.totalScore += score;
                        paper.questionScores.put(qNumber, score);
                    }
                    testPapers.put(paperNumber, paper);
                    break;
                case "#X:":
                    for (int i = 1; i < parts.length; i++) {
                        String[] studentInfo = parts[i].split("-");
                        int studentId = Integer.parseInt(studentInfo[1]);
                        String studentName = studentInfo[0];
                        Student student = new Student();
                        student.name = studentName;
                        students.put(studentId, student);
                    }
                    break;
                case "#S:":
                    int paperId = Integer.parseInt(parts[1]);
                    int studentId = Integer.parseInt(parts[2]);
                    Student student = students.get(studentId);
                    for (int i = 3; i < parts.length; i++) {
                        String[] answer = parts[i].split("-");
                        int qNumber = Integer.parseInt(answer[0]);
                        String qAnswer = answer[1];
                        student.answers.put(qNumber, qAnswer);
                    }
                    break;
                case "#D:":
                    String[] deleteInfo = parts[1].split("-");
                    int deleteQNumber = Integer.parseInt(deleteInfo[1]);
                    deletedQuestions.add(deleteQNumber);
                    break;
                default:
                    System.out.println("Invalid input format");
                    break;
            }
        }
        processResults(questions, testPapers, students, deletedQuestions);
    } catch (NumberFormatException e) {
        System.out.println("Invalid input format. Please enter valid numbers.");
    } finally {
        scanner.close();
    }
}
private static void processResults(Map<Integer, String> questions, Map<Integer, TestPaper> testPapers,
                                    Map<Integer, Student> students, Set<Integer> deletedQuestions) {
    for (Map.Entry<Integer, Student> entry : students.entrySet()) {
        int studentId = entry.getKey();
        Student student = entry.getValue();
        int totalScore = 0;
        for (Map.Entry<Integer, String> answerEntry : student.answers.entrySet()) {
            int qNumber = answerEntry.getKey();
            String studentAnswer = answerEntry.getValue();
            if (deletedQuestions.contains(qNumber)) {
                studentAnswer = "invalid";
                totalScore += 0;
            } else {
                String correctAnswer = questions.getOrDefault(qNumber, "");
                int score = 0;
                if (correctAnswer.equals(studentAnswer)) {
                    score = testPapers.get(1).questionScores.getOrDefault(qNumber, 0);
                    totalScore += score;
                }
            }
            student.totalScore = totalScore;
        }
    }
    for (Map.Entry<Integer, Student> entry : students.entrySet()) {
        int studentId = entry.getKey();
        Student student = entry.getValue();
        System.out.print(student.name + ": ");
        for (Map.Entry<Integer, String> answerEntry : student.answers.entrySet()) {
            int qNumber = answerEntry.getKey();
            String studentAnswer = answerEntry.getValue();
            if (deletedQuestions.contains(qNumber)) {
                System.out.print("the question " + qNumber + " " + studentAnswer + "~0 ");
            } else {
                String correctAnswer = questions.getOrDefault(qNumber, "");
                boolean isCorrect = correctAnswer.equals(studentAnswer);
                System.out.print(questions.get(qNumber) + "~" + studentAnswer + "~" + isCorrect + " ");
            }
        }
        System.out.println("~" + student.totalScore);
    }
    for (Map.Entry<Integer, TestPaper> entry : testPapers.entrySet()) {
        int paperNumber = entry.getKey();
        TestPaper paper = entry.getValue();
        if (paper.totalScore != 100) {
            System.out.println("alert: full score of test paper" + paperNumber + " is not 100 points");
        }
    }
}
}
总结:
学习Java是一个很有趣的过程,但也可能会让人感到困惑。作为一个初学者,我可能会遇到各种各样的挑战。不过,不要担心,因为这是学习过程中的一部分。
掌握基础知识:首先要确保对Java的基本概念有所了解,比如面向对象编程(OOP)、变量、数据类型、循环和条件语句等。
练习编程:通过实际编写代码来巩固所学知识。可以尝试解决一些简单的问题,或者参与一些项目。
阅读和理解代码:阅读他人编写的代码可以帮助你学习新的技术和方法。可以看看开源项目或者一些教程中的代码。
参加社区和论坛:加入Java开发者社区,与其他开发者交流经验和想法。这样可以帮助你更快地学习和成长。
不断学习:Java是一个广泛使用的编程语言,它的生态系统和技术都在不断发展。因此,要时刻保持学习的状态,跟上最新的发展。
坚持不懈:学习编程需要耐心和毅力。不要因为遇到困难就放弃,要坚持不懈地学习下去。
最重要的是,享受学习的过程,Java是一门非常强大和有趣的编程语言,掌握它将为你的编程生涯打下坚实的基础。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号