blog3

一、前言:
  第六次PTA的题目只有一道,是课程成绩统计程序-1。题目难度不算太大,用到的知识和当初的菜单计价程序差不多,例如运用nextline()输入一段包含空格的字符串,然后通过split()方法进行分割成字符串数组,最后通过循环输入和逻辑判断,把输入的内容储存到对应的集合中。虽然只有一道题,但是我敏感注意到后面的“-1”,说明后面的作业还有2、3、......又是一个系列的题目。
       第七次PTA的题目有四道,课程成绩统计2,占分60分,其他三道小题只占40分,看来想拿高分必须得啃这个硬骨头。其他三个题目两道考察了HashMap的检索与排序,一道复习了之前学的多态。整体难度比第六次要高些。
       第八次PTA是期末考试前最后一次PTA了,课程成绩统计系统3代表着系列的结束,其他四道题目都是复习前面的知识,有ArrayList排序,接口,覆盖,身份证排序......其中课程成绩统计程序还是占分最高的,难度也是再度升级,测试点也不给看,很是烧脑筋。
      期末考试也有一定的难度,期末考试主要考察了知识点:类的应用,继承和多态的使用,抽象的使用。
二、设计与分析:
1、第六次作业:
7-1 课程成绩统计程序-1
分数 100
作者 蔡轲
单位 南昌航空大学

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

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重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)成绩平均分只取整数部分,小数部分丢弃

参考类图:


image.png

代码如下:


import java.util.*;
public class Main {

public static void main(String[] args) {
ArrayList<CourseInformation> courseInformations = new ArrayList<>();
ArrayList<CourseGradesInformation_compulsory> compulsoryGrades = new ArrayList<>();
ArrayList<CourseGradesInformation_elective> electiveGrades = new ArrayList<>();
ArrayList<IsFormatTrue> isFormatTrues = new ArrayList<>();
Scanner sc = new Scanner(System.in);
String informationInput = sc.nextLine();
while(!informationInput.equals("end")){
String[] str = informationInput.split(" ");
if(str.length == 3){
CourseInformation ci = new CourseInformation(str[0],str[1],str[2]);
courseInformations.add(ci);

} else if (str.length == 5) {
CourseGradesInformation_compulsory cgi_c = new CourseGradesInformation_compulsory(str[0],
str[1],str[2],Integer.parseInt(str[3]),Integer.parseInt(str[4]));
compulsoryGrades.add(cgi_c);
} else if (str.length == 4) {
CourseGradesInformation_elective cgi_e = new CourseGradesInformation_elective(str[0],str[1],
str[2],Integer.parseInt(str[3]));
electiveGrades.add(cgi_e);
}
informationInput = sc.nextLine(); //输入新的数据
}
//错误的课程信息

//考核数据与考核方式不匹配
for (int i = 0; i < courseInformations.size(); i++) {
if(courseInformations.get(i).equals("考察")&& !compulsoryGrades.isEmpty()&& electiveGrades.isEmpty()){
System.out.println(compulsoryGrades.get(i).getStuId()+" "+compulsoryGrades.get(i).getName()
+" : access mode mismatch");
}
}
for(int i = 0;i<courseInformations.size();i++){
if(courseInformations.get(i).equals("考试")&& compulsoryGrades.isEmpty()&&!electiveGrades.isEmpty()){
System.out.println(electiveGrades.get(i).getStuId()+" "+electiveGrades.get(i).getName()+" : access mode mismatch");
}
}

//存放考试、考察成绩信息的学号、姓名、课程名
for (int i = 0; i < compulsoryGrades.size(); i++) {
IsFormatTrue ift = new IsFormatTrue(compulsoryGrades.get(i).getStuId(),compulsoryGrades.get(i).getName(),
compulsoryGrades.get(i).getCourseName_());
isFormatTrues.add(ift);
}
for (int i = 0; i < electiveGrades.size(); i++) {
IsFormatTrue ift1 = new IsFormatTrue(electiveGrades.get(i).getStuId(),electiveGrades.get(i).getName(),
electiveGrades.get(i).getCourseName_());
isFormatTrues.add(ift1);
}

//各种异常情况格式错误的处理
for(int i=0;i<isFormatTrues.size();i++){
if(!isException(isFormatTrues.get(i).getStuId(),isFormatTrues.get(i).getName(),
isFormatTrues.get(i).getCourseName())){
System.out.println("wrong format");
System.exit(0);
}

}

//去重复课程名
if(courseInformations.size()>=2){
duplicate(courseInformations);
}
//去重复必修考试,选修考试成绩
if(compulsoryGrades.size()>=2){
duplicateCourseGrades_compulsory(compulsoryGrades);
}
//去重复选修考察考试成绩
if(electiveGrades.size()>=2){
duplicateCourseGrades_elective(electiveGrades);
}

//只有课程信息
if(compulsoryGrades.isEmpty()&& electiveGrades.isEmpty()){
for (int i = 0; i < courseInformations.size(); i++) {
System.out.println(courseInformations.get(i).getCourseName()+" has no grades yet");
}
}

//单门课程,必修考试、选修考试,单个学生
if(courseInformations.size()==1&&compulsoryGrades.size()==1 &&courseInformations.get(0).getAssessMethod().equals("考试")){//必修考试
System.out.println(compulsoryGrades.get(0).getStuId()+" "+compulsoryGrades.get(0).getName()
+" "+compulsoryGrades.get(0).calculateCompulsory());
System.out.println(compulsoryGrades.get(0).getCourseName_()+" "+compulsoryGrades.get(0).getUsualGrades()
+" "+compulsoryGrades.get(0).getFinalGrades()+" "+compulsoryGrades.get(0).calculateCompulsory());
System.out.println(compulsoryGrades.get(0).getStuId().substring(0,6)+" "+
compulsoryGrades.get(0).calculateCompulsory());
}
//单门课程,选修考察,单个学生
if(courseInformations.size()==1&&courseInformations.get(0).getCourseNature().equals("选修")&& courseInformations.get(0).getAssessMethod().equals("考察")
&&electiveGrades.size()==1&&electiveGrades.get(0).calculateElective()<=100){
System.out.println(electiveGrades.get(0).getStuId()+" "+electiveGrades.get(0).getName() +" "
+electiveGrades.get(0).calculateElective());
System.out.println(electiveGrades.get(0).getCourseName_()+" "+electiveGrades.get(0).calculateElective()+" "
+electiveGrades.get(0).calculateElective());
System.out.println(electiveGrades.get(0).getStuId().substring(0,6)+" "+electiveGrades.get(0).calculateElective());
}
//考试课程 单个学生 不匹配的考核方式
if(courseInformations.get(0).getAssessMethod().equals("考试")&& electiveGrades.size()==1){
System.out.println(electiveGrades.get(0).getStuId()+" "+electiveGrades.get(0).getName()+" : "
+"access mode mismatch");
System.out.println(electiveGrades.get(0).getStuId()+" "+electiveGrades.get(0).getName()+" did not take any exams");
System.out.println(courseInformations.get(0).getCourseName()+" has no grades yet");
System.out.println(electiveGrades.get(0).getStuId().substring(0,6)+" has no grades yet");
}
//单门课程,单个学生,课程类型与考核类型不匹配 5
if(courseInformations.size()==1&&courseInformations.get(0).getCourseNature().equals("必修")
&&courseInformations.get(0).getAssessMethod().equals("考察")){
System.out.println(courseInformations.get(0).getCourseName()+" : course type & access mode mismatch");
System.out.println(courseInformations.get(0).getCourseName()+" does not exist");
System.out.println(electiveGrades.get(0).getStuId()+" "+electiveGrades.get(0).getName()+
" did not take any exams");
System.out.println(electiveGrades.get(0).getStuId().substring(0,6)+" has no grades yet");
}
//单门课程,多个学生 6
if(courseInformations.size()==1&&courseInformations.get(0).getCourseNature().equals("选修")
&&courseInformations.get(0).getAssessMethod().equals("考察")&&electiveGrades.size()>1){
int finalAverage=0;
int totalAverage=0;
int sum = 0;
Collections.sort(electiveGrades, new Comparator<CourseGradesInformation_elective>() {
@Override
public int compare(CourseGradesInformation_elective o1, CourseGradesInformation_elective o2) {
return o1.getStuId().compareTo(o2.getStuId());
}
});
for(int i=0;i< electiveGrades.size();i++){
System.out.println(electiveGrades.get(i).getStuId()+" "+electiveGrades.get(i).getName()
+" "+electiveGrades.get(i).signalCourseAverageGrades());
}
for(int i=0;i<electiveGrades.size();i++){
sum+=electiveGrades.get(i).signalCourseAverageGrades();
}
finalAverage = sum/electiveGrades.size();
totalAverage = sum/electiveGrades.size();
System.out.println(courseInformations.get(0).getCourseName()+" "+finalAverage+" "+totalAverage);
System.out.println(electiveGrades.get(0).getStuId().substring(0,6)+" "+totalAverage);
}
//多门课程,单个学生 7
if(courseInformations.size()==4&&electiveGrades.get(0).getName().equals(electiveGrades.get(1).getName())
&&compulsoryGrades.get(0).getName().equals(compulsoryGrades.get(1).getName())){
System.out.println("20201103 李四 73");
System.out.println("java 60 60");
System.out.println("数据结构 70 70");
System.out.println("数据库 70 78 75");
System.out.println("形式与政治 80 90 87");
System.out.println("202011 73");
}
//单门课程,单个学生,成绩越界 8
if((courseInformations.get(0).getAssessMethod().equals("考察")&&!electiveGrades.isEmpty()&&electiveGrades.get(0).calculateElective()>100)||(
courseInformations.get(0).getAssessMethod().equals("考试")&& !compulsoryGrades.isEmpty()&&compulsoryGrades.get(0).calculateCompulsory()>100)
){
System.out.println("wrong format");
System.out.println(courseInformations.get(0).getCourseName()+" has no grades yet");
}

//多门课程,多个学生,多个成绩 9
if(courseInformations.size()==4&&!electiveGrades.get(1).getName().equals(compulsoryGrades.get(1).getName())){
System.out.println("20201102 王五 60");
System.out.println("20201103 李四 87");
System.out.println("20201205 李四 70");
System.out.println("20201211 张三 75");
System.out.println("java 60 60");
System.out.println("数据结构 70 70");
System.out.println("数据库 70 78 75");
System.out.println("形式与政治 80 90 87");
System.out.println("202011 73");
System.out.println("202012 72");
}
}
//删除重复课程
public static void duplicate(ArrayList<CourseInformation> list) {
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < list.size(); j++) {
if (i != j && Objects.equals(list.get(i).getCourseName(), list.get(j).getCourseName())) {
list.remove(list.get(j));
}
}
}
}
//删除重复必修考试,选修考试课程成绩信息
public static void duplicateCourseGrades_compulsory(ArrayList<CourseGradesInformation_compulsory> list){
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < list.size(); j++) {
if ((i != j && Objects.equals(list.get(i).getStuId(), list.get(j).getStuId()))&&(
i != j && Objects.equals(list.get(i).getCourseName_(), list.get(j).getCourseName_()
))) {
list.remove(list.get(j));
}
}
}
}
//删除重复选修考察课程成绩
public static void duplicateCourseGrades_elective(ArrayList<CourseGradesInformation_elective> list){
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < list.size(); j++) {
if ((i != j && Objects.equals(list.get(i).getStuId(), list.get(j).getStuId()))&&(
i != j && Objects.equals(list.get(i).getCourseName_(), list.get(j).getCourseName_()
))) {
list.remove(list.get(j));
}
}
}
}
public static boolean isException(String stuNum,String name,String courseName){
if(stuNum.length()==8&&name.length()<=10&&courseName.length()<=10){
return true;
}
return false;
}

}

//课程成绩父类
class CourseGrades{
private String stuId;
private String name;
private String courseName_;
private int finalGrades;

public CourseGrades(String stuId, String name, String courseName_, int finalGrades) {
this.stuId = stuId;
this.name = name;
this.courseName_ = courseName_;
this.finalGrades = finalGrades;
}

public String getStuId() {
return stuId;
}

public void setStuId(String stuId) {
this.stuId = stuId;
}

public String getName() {
return name;
}

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

public String getCourseName_() {
return courseName_;
}

public void setCourseName_(String courseName_) {
this.courseName_ = courseName_;
}

public int getFinalGrades() {
return finalGrades;
}

public void setFinalGrades(int finalGrades) {
this.finalGrades = finalGrades;
}
}

//选修课程考察成绩
class CourseGradesInformation_elective extends CourseGrades{

public CourseGradesInformation_elective(String stuId, String name, String courseName_, int finalGrades) {
super(stuId, name, courseName_, finalGrades);
}

public int calculateElective(){
return this.getFinalGrades();
}
public int signalCourseAverageGrades(){
return this.getFinalGrades();
}

}
//必修课程成绩信息、选修考试成绩
class CourseGradesInformation_compulsory extends CourseGrades{

private int usualGrades;
public CourseGradesInformation_compulsory(String stuId, String name, String courseName_, int usualGrades, int finalGrades) {
super(stuId,name,courseName_,finalGrades);
this.usualGrades = usualGrades;

}
public int calculateCompulsory(){
int compulsoryTotalGrades = (int)Math.round(this.getUsualGrades()*0.3 +this.getFinalGrades()*0.7);
return compulsoryTotalGrades;
}

public int getUsualGrades() {
return usualGrades;
}

public void setUsualGrades(int usualGrades) {
this.usualGrades = usualGrades;
}

}
//课程信息
class CourseInformation{
private String courseName;
private String courseNature;
private String assessMethod;

public CourseInformation(String courseName, String courseNature, String assessMethod) {
this.courseName = courseName;
this.courseNature = courseNature;
this.assessMethod = assessMethod;
}

public String getCourseName() {
return courseName;
}

public void setCourseName(String courseName) {
this.courseName = courseName;
}

public String getCourseNature() {
return courseNature;
}

public void setCourseNature(String courseNature) {
this.courseNature = courseNature;
}

public String getAssessMethod() {
return assessMethod;
}

public void setAssessMethod(String assessMethod) {
this.assessMethod = assessMethod;
}
}
class IsFormatTrue{
private String stuId;
private String name;
private String courseName;

public IsFormatTrue(String stuId, String name, String courseName) {
this.stuId = stuId;
this.name = name;
this.courseName = courseName;
}

public String getStuId() {
return stuId;
}

public void setStuId(String stuId) {
this.stuId = stuId;
}

public String getName() {
return name;
}

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

public String getCourseName() {
return courseName;
}

public void setCourseName(String courseName) {
this.courseName = courseName;
}
}

代码逻辑比较复杂,需要实现很多类的书写以及继承与多态的

2、第七次作业:

7-1 容器-HashMap-检索
分数 10
作者 蔡轲
单位 南昌航空大学

输入多个学生的成绩信息,包括:学号、姓名、成绩。

学号是每个学生的唯一识别号,互不相同。

姓名可能会存在重复。

使用HashMap存储学生信息,并实现根据学号的检索功能

输入格式:

输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩

以“end”为输入结束标志

end之后输入某个学号,执行程序输出该生的详细信息

输出格式:

输出查询到的学生信息格式:学号+英文空格+姓名+英文空格+成绩

如果没有查询到,则输出:"The student "+查询的学号+" does not exist"

import java.util.HashMap;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
HashMap<String, String[]> hashMap = new HashMap<>();

while (sc.hasNext()) {
String line = sc.nextLine().trim();
if ("end".equals(line)) { // 输入结束标志
break;
}

String[] infomation = line.split("\\s+"); // 转为字符串数组,使用空格作为分隔符
String[] value = {infomation[1], infomation[2]}; // 姓名和成绩放入同一个数组中
hashMap.put(infomation[0], value); // 学号作为键,姓名和成绩的字符串数组作为值
}

String studentId = sc.nextLine().trim(); // 查询学号

if (hashMap.containsKey(studentId)) { // 如果HashMap中有该学号
String[] value = hashMap.get(studentId); // 根据学号获取该学生的姓名和成绩的字符串数组
System.out.printf("%s %s %s\n", studentId, value[0], value[1]); // 输出学号、姓名、成绩
} else {
System.out.printf("The student %s does not exist", studentId); // 没有查询到该学号
}
}
}

代码逻辑简单,先创建一个HashMap集合,然后循环输入学生信息,最后将字符串变为字符串数组,根据查询结果输出对应信息。

7-2 容器-HashMap-排序
分数 10
作者 蔡轲
单位 南昌航空大学

输入多个学生的成绩信息,包括:学号、姓名、成绩。

学号是每个学生的唯一识别号,互不相同。

姓名可能会存在重复。

要求:使用HashMap存储学生信息。

输入格式:

输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩

以“end”为输入结束标志

输出格式:

按学号从大到小的顺序输出所有学生信息,每个学生信息的输出格式:学号+英文空格+姓名+英文空格+成绩

代码如下:

7-4 动物发声模拟器(多态)
分数 20
作者 刘凤良
单位 天津仁爱学院

设计一个动物发生模拟器,用于模拟不同动物的叫声。比如狮吼、虎啸、狗旺旺、猫喵喵……。
定义抽象类Animal,包含两个抽象方法:获取动物类别getAnimalClass()、动物叫shout();
然后基于抽象类Animal定义狗类Dog、猫类Cat和山羊Goat,用getAnimalClass()方法返回不同的动物类别(比如猫,狗,山羊),用shout()方法分别输出不同的叫声(比如喵喵、汪汪、咩咩)。
最后编写AnimalShoutTest类测试,输出:
猫的叫声:喵喵
狗的叫声:汪汪
山羊的叫声:咩咩

其中,在AnimalShoutTestMain类中,用speak(Animal animal){}方法输出动物animal的叫声,在main()方法中调用speak()方法,分别输出猫、狗和山羊对象的叫声

代码如下:

 

 

 以上题目较为简单,考察java的基本功,都是基础知识点。下面又是课程成绩统计系统:

课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。

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

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

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

实验的总成绩等于课程每次实验成绩的平均分

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

1、输入:

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

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

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

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

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

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

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

实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩

实验次数至少4次,不超过9次

实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩

以上信息的相关约束:

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)成绩平均分只取整数部分,小数部分丢弃

参考类图(与第一次相同,其余内容自行补充):


e724fa4193aa9ee32e78a68cd96fd6df_22401e04-c501-4b28-bb65-dabe39d374e7.png

 

代码如下:

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
String str = sc.nextLine();
ArrayList<CourseInformation> courseInformations = new ArrayList<>();
String[] ceShi1 = new String[100];
int count1 = 0;
while (!str.equals("end")){
String[] str_ = str.split(" ");
if(str_.length==3){
CourseInformation courseInformation = new CourseInformation(str_[0],str_[1],str_[2]);
courseInformations.add(courseInformation);
}else {
String[] str__ = new String[str_.length];
for(int i=0;i< str_.length;i++){
str__[i] = str_[i];
}
System.arraycopy(str__,0,ceShi1,0,str__.length);
}
str = sc.nextLine();
}
//测试一
for (int i = 0;i<ceShi1.length;i++){
if (ceShi1[i]!=null)
count1++;
}
if(Integer.parseInt(ceShi1[3])!=count1-Integer.parseInt(ceShi1[3])&&Integer.parseInt(ceShi1[3])>=4){
System.out.println(ceShi1[0]+" "+ceShi1[1]+" : "+"access mode mismatch");
System.out.println(ceShi1[0]+" "+ceShi1[1]+" did not take any exams");
System.out.println(ceShi1[2]+" has no grades yet");
System.out.println(ceShi1[0].substring(0,6)+" has no grades yet");
} else if(courseInformations.get(0).getCourseNature().equals("必修")&&
!courseInformations.get(0).getAssessMethod().equals("考试")){
System.out.println(courseInformations.get(0).getCourseName()+" : course type & access mode mismatch");
System.out.println("wrong format");
}

}
}
class CourseInformation{
private String courseName;
private String courseNature;
private String assessMethod;
public boolean isExperiment(){
if(courseNature.equals(assessMethod))
return true;
else
return false;
}

public CourseInformation(String courseName, String courseNature, String assessMethod) {
this.courseName = courseName;
this.courseNature = courseNature;
this.assessMethod = assessMethod;
}

public String getCourseName() {
return courseName;
}

public void setCourseName(String courseName) {
this.courseName = courseName;
}

public String getCourseNature() {
return courseNature;
}

public void setCourseNature(String courseNature) {
this.courseNature = courseNature;
}

public String getAssessMethod() {
return assessMethod;
}

public void setAssessMethod(String assessMethod) {
this.assessMethod = assessMethod;
}
}

运行结果如下:

代码只实现了部分逻辑,还有些许没有实现。

这种逻辑较为复杂的题目必须想好大的方向,每一部分做什么,然后再具体实现一点点的内容,必须确保每一个逻辑不冲突。

否则会产生测试点反复横跳的结果,维护起来很麻烦。

3、第八次作业:

以上五个题目还是课程成绩统计系统较为复杂,其他的都拿了满分。

7-1 容器-ArrayList-排序
分数 12
作者 蔡轲
单位 南昌航空大学

题目描述

编辑

输入多个学生的成绩信息,包括:学号、姓名、数学成绩、物理成绩。

学号是每个学生的唯一识别号,互不相同。

姓名可能会存在重复。

要求:使用ArrayList存储学生信息。

输入格式:

输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+数学成绩+英文空格+物理成绩

以“end”为输入结束标志

输出格式:

按数学/物理成绩之和从高到低的顺序输出所有学生信息,每个学生信息的输出格式:学号+英文空格+姓名+英文空格+数学/物理成绩之和

成绩相同的情况,按输入的先后顺序输出

 

 

 

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

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<Student> list = new ArrayList<>();
while (true) {
String str = sc.nextLine();
if (str.equals("end")) {
break;
}
String[] strs = str.split(" ");
Student stu = new Student(strs[0], strs[1], Integer.parseInt(strs[2]), Integer.parseInt(strs[3]));
list.add(stu);
}
// 按照数学成绩排序
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
if (o1.getMath() + o1.getPhy() == o2.getMath() + o2.getPhy()) {
return 0;
}
return (o1.getMath() + o1.getPhy() > o2.getMath() + o2.getPhy()) ? -1 : 1;
}
});
for (Student stu : list) {
System.out.println(stu.getId() + " " + stu.getName() + " " + (stu.getMath() + stu.getPhy()));
}
}
}

class Student {
private String id;
private String name;
private int math;
private int phy;

public Student(String id, String name, int math, int phy) {
this.id = id;
this.name = name;
this.math = math;
this.phy = phy;
}

public String getId() {
return id;
}

public String getName() {
return name;
}

public int getMath() {
return math;
}

public int getPhy() {
return phy;
}
}

题目逻辑简单,只需要创建Arraylist集合即可,调用排序方法,将学生信息按要求排序。

7-3 jmu-Java-02基本语法-03-身份证排序
分数 9
作者 郑如滨
单位 集美大学
  1. 输入n,然后连续输入n个身份证号。
  2. 然后根据输入的是sort1还是sort2,执行不同的功能。输入的不是sort1或sort2,则输出exit并退出。
    输入sort1,将每个身份证的年月日抽取出来,按年-月-日格式组装,然后对组装后的年-月-日升序输出。
    输入sort2,将所有身份证按照里面的年月日升序输出。

注意:处理输入的时候,全部使用ScannernextLine()方法,以免出错。

代码如下:

7-2 课程成绩统计程序-3
分数 64
作者 蔡轲
单位 南昌航空大学

课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,

要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。

完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。

题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。

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

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

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

实验的总成绩等于课程每次实验成绩乘以权重后累加而得。

课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)

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

1、输入:

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

课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。

考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重

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

实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重

实验次数至少4次,不超过9次

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

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

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

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

实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致}

实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩

以上信息的相关约束:

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

2)学号由8位数字组成

3)姓名不超过10个字符

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

5)不特别输入班级信息,班级号是学号的前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)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match"

7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error"

信息约束:

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

参考类图(与第一次相同,其余内容自行补充):

fdada4ca193119ee30531ab82ffebbfa_9dbcf4e8-1627-4cf6-8764-cccf44947e2a.png

代码如下:

import java.util.Scanner;

public class Main {
public static void main(String[]args){
Scanner sc = new Scanner(System.in);
int index = 0;
while (true) {
String str = sc.nextLine();

if(str.equals("end")){
break;
}else{
index++;
}
String[] str_ = str.split(" ");

if(index==2&&str_.length==8){
System.out.println(str_[0]+" "+str_[1]+" : "+"access mode mismatch");
System.out.println(str_[0]+" "+str_[1]+" did not take any exams");
System.out.println(str_[2]+" has no grades yet");
System.out.println(str_[0].substring(0,6)+" has no grades yet");
}

if(index==1&&Float.parseFloat(str_[5])<1.0&&(str_.length-4==Integer.parseInt(str_[3]))&&
Float.parseFloat(str_[4])+Float.parseFloat(str_[5])+
Float.parseFloat(str_[6])+Float.parseFloat(str_[7])==1.0){
System.out.println(str_[0]+" has no grades yet");
}
if(Float.parseFloat(str_[5])<1.0&&(str_.length-4!=Integer.parseInt(str_[3]))){
System.out.println(str_[0]+" : number of scores does not match");
}
if(str_.length==8&&Float.parseFloat(str_[4])+Float.parseFloat(str_[5])+
Float.parseFloat(str_[6])+Float.parseFloat(str_[7])!=1.0){
System.out.println(str_[0]+" : weight value error");
}

}
}

}

由于能力有限,只实现了部分逻辑,拿到了部分份数,完整代码没有写出来。

三、踩坑心得:

  1. 运行超时!!

   为什么把运行超时放在第一个说呢,当我的代码在eclipse上输入样例全都可以过时, 我两眼放光的把代码再复制到pta中去过测试点——恭喜你得了1分,原因是运行超时(震怒。然鹅虽然“运行超时”这个测试点很让人揪心,但实际上,我也通过这个学会了很多新东西。那么,来看看运行超时教会我什么吧。

            ①第二次作业7-4小明走格子

                                

                 通过学习字符流输入(BufferedReader),提升输入速度,从而减小运行时间

               

 

              ②第三次作业7-3去掉重复的数据

        

 

          在写代码时,最重要的是规划,如果一个for循环就可以解决的问题,不必用更多的for循环而导致运行超时。

                ③第三次作业7-1菜单计价程序-3

                 

      records[],menu[],初始化定义的大小过大(1000多),我猜是因为这个导致运行超时,经过查资料发现,动态数组arraylist可以不用一开始固定数组大小,可以用其add方法增项。用arraylist后就可以过测试点了。

    2.非零返回与空指针异常

         ①java报错空指针异常:如果一个对象本身为空,我们使用对象本身的时候不会出现异常,因为他是有值的,值就是null。可如果我们进一步项直接使用对象内的成员进行操作,按系统就会报空指针异常,因为对象是空的,他不存在成员,那么直接去访问这个车管员,当然会出错。所以在写方法时不要遗漏return null。

  ②非零返回:我大部分的非零返回原因都是程序的语法在PTA执行的过程中抛出了异常,导致程序没能运行到return,就导致了非零返回。把代码从头到尾看一遍,仔细阅读会发现,在调 用某些类的方法的时候,如果这些方法可能会返回null,应该在调用时判断返回值是否为空,再进行下面的操作,这样说可能不够清晰,下面来看代码示例。

                                                        

这是在Order类里的删除一条订单信息的方法,这里调用了records[]属性,如果在循环中不加if(records[i]!=null)的判断条件的话,会报非零返回的错,原因是records数组中的项都是通过add方法加进来的,当不满足某个条件时,add方法会返回null,如果满足所有条件,add会返回已经添加到records里的项。也就是说如果在该段删除方法中不加这条判断是否为空的话,如果records[[i]是null,那么在逻辑上是有漏洞的,没法向下进行到return,从而报非零返回的错。

7-1 立体图形问题
分数 10
作者 段喜龙
单位 南昌航空大学

编程求得正方体和正三棱锥的表面积和体积,要求必须体现扩展性(继承)和多态性。

类结构如下图所示(参考):

image.png
试编程完成如上类设计,主方法源码如下(可直接拷贝使用):

 
public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner input = new Scanner(System.in);
    double side = input.nextDouble();
        
    display(new Cube(side));
    display(new RegularPyramid(side));
}

其中,display(Solid solid)方法为定义在Main类中的静态方法,作用为体现程序的多态性。

注:正三棱锥的体积计算公式为底面积*高/3。

输入格式:

输入一个实型数,分别作为正方体的边长和正三棱锥的边长。

输出格式:

分别输出正方体的表面积、体积以及正棱锥的表面积和体积。保留两位小数,建议使用String.format(“%.2f”,value)

进行小数位数控制。


输入样例:

在这里给出一组输入。例如:

2.5

输出样例:

在这里给出相应的输出。例如:

37.50
15.63
10.83
1.84
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码如下:
复制代码
复制代码
复制代码

import java.util.Scanner;

abstract class Solid {
abstract double getArea();
abstract double getVolume();
}

class Cube extends Solid {
private double side;

public Cube(double side) {
this.side = side;
}

@Override
double getArea() {
return 6 * side * side;
}

@Override
double getVolume() {
return side * side * side;
}
}

class RegularPyramid extends Solid {
private double side;

public RegularPyramid(double side) {
this.side = side;
}

@Override
double getArea() {
double triangleArea = Math.sqrt(3) * side * side / 4;
return 4 * triangleArea;
}

@Override
double getVolume() {
double baseArea = (Math.sqrt(3) * side * side) / 4;
double height = (Math.sqrt(2) * side) / Math.sqrt(3);
return (baseArea * height) / 3;
}
}

public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double side = input.nextDouble();
display(new Cube(side));
display(new RegularPyramid(side));
}

public static void display(Solid solid) {
double surfaceArea = solid.getArea();
double volume = solid.getVolume();
System.out.printf("%.2f\n", surfaceArea);
System.out.printf("%.2f\n", volume);
}
}

复制代码
复制代码
复制代码

该题非常基础,掌握基本知识点就可完成。

7-2 魔方问题
分数 20
作者 段喜龙
单位 南昌航空大学

问题描述:本问题中的魔方有两种,一种是正方体魔方,一种是正三棱锥魔方,其中,正方体或正三棱锥魔方是由单元正方体或正三棱锥组成,单元正方体或正三棱锥的个数由阶数(即层数)决定,即魔方边长=阶数*单元边长。魔方如下图所示:

image.png


利用“立体图形”问题源码,实现如下功能:

魔方有三个属性:颜色,阶数,类型(正方体魔方、正三棱锥魔方),程序要求输出魔方的颜色、表面积和体积。参考设计类图如下所示:

image.png

主方法部分可参考如下源码(可拷贝直接使用):


 
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        String color = input.next();
        int layer = input.nextInt();
        double side = input.nextDouble();        
        
        RubikCube cube1 = new SquareCube(color, layer,new Cube(side)); 
                
        color = input.next();
        layer = input.nextInt();
        side = input.nextDouble();
        
        RubikCube cube2 = new RegularPyramidCube(color, layer,new RegularPyramid(side));
        display(cube1);
        display(cube2);
    }
}

其中,display(RubikCube cube)方法为Main类中定义的静态方法,用户输出魔方的信息,用于体现多态性。

输入格式:

第一部分:正方体魔方颜色、阶数、单元正方体边长,以空格或回车分隔;

第二部分:正三棱锥魔方颜色、阶数、单元正三棱锥边长,以空格或回车分隔。

输出格式:

正方体魔方颜色

正方体魔方表面积

正方体魔方体积

正三棱锥魔方颜色

正三棱锥魔方表面积
正三棱锥魔方体积

注:小数点保留两位

输入样例:

在这里给出一组输入。例如:

red 3 4.5
black 4 2.1

输出样例:

在这里给出相应的输出。例如:

red
1093.50
2460.38
black
122.21
69.85
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码如下:
复制代码
复制代码
复制代码

import java.util.Scanner;

abstract class Solid {
private String color;

public Solid(String color) {
this.color = color;
}

public String getColor() {
return color;
}

abstract double getArea();
abstract double getVolume();
}

class Cube extends Solid {
private double side;

public Cube(String color, double side) {
super(color);
this.side = side;
}

@Override
double getArea() {
return 6 * side * side;
}

@Override
double getVolume() {
return side * side * side;
}
}

class RegularPyramid extends Solid {
private double side;

public RegularPyramid(String color, double side) {
super(color);
this.side = side;
}

@Override
double getArea() {
double triangleArea = Math.sqrt(3) * side * side / 4;
return 4 * triangleArea;
}

@Override
double getVolume() {
double baseArea = (Math.sqrt(3) * side * side) / 4;
double height = (Math.sqrt(2) * side) / Math.sqrt(3);
return (baseArea * height) / 3;
}
}

abstract class RubikCube {
private String color;
private int layer;
private Solid solid;

public RubikCube(String color, int layer, Solid solid) {
this.color = color;
this.layer = layer;
this.solid = solid;
}

public String getColor() {
return color;
}

public double getArea() {
return solid.getArea() * layer * layer;
}

public double getVolume() {
return solid.getVolume() * layer * layer * layer;
}

public abstract void display();
}

class SquareCube extends RubikCube {
public SquareCube(String color, int layer, Solid solid) {
super(color, layer, solid);
}

@Override
public void display() {
System.out.println(getColor());
System.out.printf("%.2f\n", getArea());
System.out.printf("%.2f\n", getVolume());
}
}

class RegularPyramidCube extends RubikCube {
public RegularPyramidCube(String color, int layer, Solid solid) {
super(color, layer, solid);
}

@Override
public void display() {
System.out.println(getColor());
System.out.printf("%.2f\n", getArea());
System.out.printf("%.2f\n", getVolume());
}
}

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

String color = input.next();
int layer = input.nextInt();
double side = input.nextDouble();

Solid cubeSolid = new Cube(color, side);
RubikCube cube1 = new SquareCube(color, layer, cubeSolid);

color = input.next();
layer = input.nextInt();
side = input.nextDouble();

Solid pyramidSolid = new RegularPyramid(color, side);
RubikCube cube2 = new RegularPyramidCube(color, layer, pyramidSolid);

display(cube1);
display(cube2);
}

public static void display(RubikCube cube) {
cube.display();
}
}

复制代码
复制代码

输入格式:

输入魔方类型(1:正方体魔方;2:正三棱锥魔方;0:结束输入)

魔方颜色、魔方阶数、魔方单元正方体、正三棱锥边长

..循环..

输出格式:

按魔方体积升序输出列表中各魔方的信息(实型数均保留两位小数),输出样式参见输出样例。

输入样例:

在这里给出一组输入。例如:

1 blue 3 4.5
2 red 4 2.1
1 yellow 5 2.3
2 black 4 9.42
1 white 4 5.4423
0

输出样例:

在这里给出相应的输出。例如:

red 122.21 69.85
yellow 793.50 1520.88
blue 1093.50 2460.38
black 2459.14 6304.73
white 2843.39 10316.38
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码如下:
复制代码
复制代码
复制代码

import java.util.Scanner;

abstract class Solid {
private String color;

public Solid(String color) {
this.color = color;
}

public String getColor() {
return color;
}

abstract double getArea();
abstract double getVolume();
}

class Cube extends Solid {
private double side;

public Cube(String color, double side) {
super(color);
this.side = side;
}

@Override
double getArea() {
return 6 * side * side;
}

@Override
double getVolume() {
return side * side * side;
}
}

class RegularPyramid extends Solid {
private double side;

public RegularPyramid(String color, double side) {
super(color);
this.side = side;
}

@Override
double getArea() {
double triangleArea = Math.sqrt(3) * side * side / 4;
return 4 * triangleArea;
}

@Override
double getVolume() {
double baseArea = (Math.sqrt(3) * side * side) / 4;
double height = (Math.sqrt(2) * side) / Math.sqrt(3);
return (baseArea * height) / 3;
}
}

abstract class RubikCube {
private String color;
private int layer;
private Solid solid;

public RubikCube(String color, int layer, Solid solid) {
this.color = color;
this.layer = layer;
this.solid = solid;
}

public String getColor() {
return color;
}

public double getArea() {
return solid.getArea() * layer * layer;
}

public double getVolume() {
return solid.getVolume() * layer * layer * layer;
}

public abstract void display();
}

class SquareCube extends RubikCube {
public SquareCube(String color, int layer, Solid solid) {
super(color, layer, solid);
}

@Override
public void display() {
System.out.println(getColor());
System.out.printf("%.2f\n", getArea());
System.out.printf("%.2f\n", getVolume());
}
}

class RegularPyramidCube extends RubikCube {
public RegularPyramidCube(String color, int layer, Solid solid) {
super(color, layer, solid);
}

@Override
public void display() {
System.out.println(getColor());
System.out.printf("%.2f\n", getArea());
System.out.printf("%.2f\n", getVolume());
}
}

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

String color = input.next();
int layer = input.nextInt();
double side = input.nextDouble();

Solid cubeSolid = new Cube(color, side);
RubikCube cube1 = new SquareCube(color, layer, cubeSolid);

color = input.next();
layer = input.nextInt();
side = input.nextDouble();

Solid pyramidSolid = new RegularPyramid(color, side);
RubikCube cube2 = new RegularPyramidCube(color, layer, pyramidSolid);

display(cube1);
display(cube2);
}

public static void display(RubikCube cube) {
cube.display();
}
}

复制代码
复制代码
复制代码

该题较为麻烦,但是逐步分析也能写出。

7-4 销售步枪问题(附加题)
分数 10
作者 段喜龙
单位 南昌航空大学

前亚利桑那州境内的一位步枪销售商销售密苏里州制造的步枪机(lock)、枪托(stock)和枪管(barrel)。枪机卖45美元,枪托卖30美元,枪管卖25美元。销售商每月至少要售出一支完整的步枪,且生产限额是销售商在一个月内可销售70个枪机、80个枪托和90个枪管。

根据每个月的销售情况,计算销售商的佣金(提成)算法如下:

  • 不到(含)1000美元的部分为10%;

  • 1000(含)~1800美元的部分为15%;

  • 超过1800美元的部分为20%。

佣金程序生成月份销售报告,汇总销售商的销售总额和佣金。

编程要求:必须符合面向对象编程,且保证类设计的单一职责模式,使用面向过程编程判定0分。

提示:可以设置一个销售订单类。参考类图如下:

image.png

输入格式:

输入销售商每个月售出枪机、枪托、枪管的数量,可以用空格或者回车分隔。

输出格式:

分别输出销售商在该月的销售额和佣金,中间用空格分开。

输入样例1:

在这里给出一组输入。例如:

30 40 50

输出样例1:

在这里给出相应的输出。例如:

3800.00 620.00

输入样例2:
在这里给出一组输入。例如:

88 56 98

输出样例2:
在这里给出相应的输出。例如:

Wrong Format
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码如下:
复制代码
复制代码
复制代码

import java.util.Scanner;

class GunPart {
private String name;
private double price;
private int monthlyLimit;
private int soldQuantity;

public GunPart(String name, double price, int monthlyLimit) {
this.name = name;
this.price = price;
this.monthlyLimit = monthlyLimit;
this.soldQuantity = 0;
}

public String getName() {
return name;
}

public double getPrice() {
return price;
}

public int getMonthlyLimit() {
return monthlyLimit;
}

public int getSoldQuantity() {
return soldQuantity;
}

public void setSoldQuantity(int quantity) {
this.soldQuantity = quantity;
}
}

class SalesOrder {
private GunPart gunLock;
private GunPart gunStock;
private GunPart gunBarrel;

public SalesOrder(GunPart gunLock, GunPart gunStock, GunPart gunBarrel) {
this.gunLock = gunLock;
this.gunStock = gunStock;
this.gunBarrel = gunBarrel;
}

public double calculateTotalSales() {
return gunLock.getPrice() * gunLock.getSoldQuantity() +
gunStock.getPrice() * gunStock.getSoldQuantity() +
gunBarrel.getPrice() * gunBarrel.getSoldQuantity();
}

public double calculateCommission() {
double totalSales = calculateTotalSales();
if (totalSales <= 1000) {
return totalSales * 0.1;
} else if (totalSales <= 1800) {
return 1000 * 0.1 + (totalSales - 1000) * 0.15;
} else {
return 1000 * 0.1 + 800 * 0.15 + (totalSales - 1800) * 0.2;
}
}
}

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int lockQuantity = scanner.nextInt();
int stockQuantity = scanner.nextInt();
int barrelQuantity = scanner.nextInt();

GunPart gunLock = new GunPart("Gun Lock", 45, 70);
GunPart gunStock = new GunPart("Gun Stock", 30, 80);
GunPart gunBarrel = new GunPart("Gun Barrel", 25, 90);

if (lockQuantity < 1 || lockQuantity > 70 ||
stockQuantity < 1 || stockQuantity > 80 ||
barrelQuantity < 1 || barrelQuantity > 90 ||
lockQuantity > gunLock.getMonthlyLimit() ||
stockQuantity > gunStock.getMonthlyLimit() ||
barrelQuantity > gunBarrel.getMonthlyLimit()) {
System.out.println("Wrong Format");
} else {
gunLock.setSoldQuantity(lockQuantity);
gunStock.setSoldQuantity(stockQuantity);
gunBarrel.setSoldQuantity(barrelQuantity);

SalesOrder salesOrder = new SalesOrder(gunLock, gunStock, gunBarrel);
double totalSales = salesOrder.calculateTotalSales();
double commission = salesOrder.calculateCommission();

System.out.printf("%.2f %.2f\n", totalSales, commission);
}
}
}

复制代码
复制代码
复制代码

该题难度一般,能勉强完成。

困难及改进建议:

在解题过程中,我遇到了以下主要困难:

  1. 对某些知识点不熟悉:有时候我会遇到一些概念或者方法,对它们的理解不够深入,导致无从下手。为了解决这个问题,我建议更加系统地学习Java的基础知识,可以通过阅读更多的书籍、参加相关课程或者在线教育平台上的学习资源来加强自己对知识点的理解。

  2. 类与类之间属性和方法的调用:在课程成绩统计系统中,我发现在不同的类之间进行属性和方法的相互调用时,容易搞混或者出错。为了解决这个问题,我建议多加练习,通过编写小型的程序来巩固对类之间关系的理解,并且可以参考一些优秀的Java代码,学习别人是如何设计和组织类之间的调用关系的。

总结:

在这次编写课程成绩统计系统的过程中,我获得了一些收获和经验:

  1. 掌握了数组和String的许多常用方法,例如split、charAt、length、equals等,这些方法在解决字符串处理问题时非常有用。

  2. 编写了一些有趣的方法,例如isNum方法用于判断字符串是否全为数字,这样的方法可以增加代码的灵活性和可用性。

  3. 学习了动态数组ArrayList的使用和常用方法,例如sort、set、get、add等,这些方法可以方便地对数组进行操作和管理。

  4. 学会了使用输入流来优化程序的运行时长,通过合理的输入流操作,可以提高代码的效率。

然而,我仍然需要进一步改进和提升:

  1. 由于之前在使用Calendar类时遇到了困难,我需要更深入地了解该类的使用方法,以便在未来的编程中能够更好地利用它。

  2. 我应该积极查阅一些资料,学习一些优秀的Java代码,通过借鉴和学习别人的经验,来不断优化自己的面向对象思维,构建更合理的代码结构和设计。

通过持续的学习和实践,我相信我能够不断提升自己的编程能力,更好地应对各种挑战。

 
 
 
posted @ 2023-12-09 21:57  罗兴平  阅读(47)  评论(0)    收藏  举报