7-8次PTA题目集(成绩计算系列)以及期末考试

发布时间 2023-12-09 21:50:38作者: nchu-sg

一、前言

第7-8次的题目集相对于前几次的题目集而言题量虽多了点,但是难度有适当的降低,比较考察学生上课学习到基本的算法和知识,考察多的为课程成绩统计程序2-3这一类题目,这两题代码量还是比较大的,不比之前写的菜单计价少,但难度相比菜单计价还是低了一点的,整个题目集主要都考察多态与继承。下面进入记录

二、设计与分析

第七次题目集

7-3 课程成绩统计程序-2

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

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

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

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

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

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

1、输入:

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

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

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

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

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

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

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

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

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

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

分析:第七次题目集最为困难的一题。主要考查点:

(1)考察对于数据计算的把握能力。课程成绩统计程序相比于第一次题目新加入了实验课程。而难度就在于要将实验课程成绩的所有成绩统计出来在算出平均成绩,这在代码实现上面就有不少难度。

(2)考察对于题目的阅读能力,能否正确理解题意,根据指示正确编写代码实现相应功能,因为新加入了实验课程的成绩,所以在输入输出上面又新增了许多的限制情况,这对于我们对题目的阅读理解能力有相当的考验。

类图:

 结果截图:

 源代码:

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String tip = s.nextLine();
systemin pi=new systemin();
while (!tip.equals("end")) {
pi.systemin(tip);
tip = s.nextLine();
}
pi.Sort();
pi.getnum();
pi.getcourse();
pi.getclass();
}
}

abstract class gd{
double Totalgd;
public int getTotalgd() {
return (int) Totalgd;
}
public int getUsualgd() {
return 0;
}
public int getFinalgd() {
return 0;
}
}

class Examgd extends gd{
int Usualgd;
int Finalgd;
public int getTotalgd(){
return (int)(0.3*this.getUsualgd()+0.7*this.getFinalgd());
}
public int getUsualgd() {
return Usualgd;
}
public void setUsualgd(int usualgd) {
Usualgd = usualgd;
}
public int getFinalgd() {
return Finalgd;
}
public void setFinalgd(int finalgd) {
Finalgd = finalgd;
}
}


class NoExamgd extends gd{
int Finalgd;
public int getTotalgd(){
return Finalgd;
}
public int getFinalgd() {
return Finalgd;
}
public void setFinalgd(int finalgd) {
Finalgd = finalgd;
}
}


class Course{
String name;
String kind;
String method;

public Course(String name, String kind, String method) {
this.name = name;
this.kind = kind;
this.method = method;
}
public String getName() {
return name;
}
public String getMethod() {
return method;
}
}

class Student{
String num;
String name;
public Student(String num, String name) {
this.num = num;
this.name = name;
}
public String getNum() {
return num;
}
public String getName() {
return name;
}
}


class SelectCourse{
Course course;
Student student;
gd gd;
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public gd getgd() {
return gd;
}
public void setgd(gd gd) {
this.gd = gd;
}
}

class systemin{
private final ArrayList<SelectCourse> selectCourses = new ArrayList<>();
private final ArrayList<Course> courses = new ArrayList<>();
private final ArrayList<Student> students = new ArrayList<>();
private final ArrayList<String> Class = new ArrayList<>();
private final HashMap<String,String> cm=new HashMap();
public void systemin(String input){
String []inputs=input.split(" ");
if(Imatch.minput(input)==1){
cm.put(inputs[0],inputs[2]);
if(checkC(inputs[0])!=null)return;
else {
if(inputs[1].equals("必修")&&(!inputs[2].equals("考试"))){
System.out.println(inputs[0]+" : course type & access mode mismatch");
}
else if(inputs[1].equals("选修")&&!(inputs[2].equals("考试")||inputs[2].equals("考察"))){
System.out.println(inputs[0]+" : course type & access mode mismatch");
}
else if(inputs[1].equals("实验")&&!(inputs[2].equals("实验"))){
System.out.println(inputs[0]+" : course type & access mode mismatch");
}
else courses.add(new Course(inputs[0],inputs[1],inputs[2]));
}
}
else if(Imatch.minput(input)==2){
Course findcourse=checkC(inputs[2]);
if(inputs.length>5&&(Integer.parseInt(inputs[3])<4||Integer.parseInt(inputs[3])>9)) {
System.out.println("wrong format");
return;
}
Student newStudent = new Student(inputs[0],inputs[1]);
if(!checkStudent(newStudent.getNum()))students.add(newStudent);
if(!checkClass(inputs[0].substring(0,6))){
Class.add(inputs[0].substring(0,6));
}
if(cs(inputs[0],inputs[2]))return;
if(findcourse==null){

System.out.println(inputs[2]+" does not exist");
return;
}
else if(findcourse.getMethod().equals("考试")&&inputs.length!=5){
System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
}
else if(findcourse.getMethod().equals("考察")&&inputs.length!=4){
System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
}
else if(findcourse.getMethod().equals("实验")&&(inputs.length-4!=Integer.parseInt(inputs[3]))){
System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
}
else{
SelectCourse newSelectCourse=new SelectCourse();
newSelectCourse.setCourse(findcourse);
gd gd=null;
if(findcourse.getMethod().equals("考试")){
Examgd examgd=new Examgd();
examgd.setUsualgd(Integer.parseInt(inputs[3]));
examgd.setFinalgd(Integer.parseInt(inputs[4]));
gd=examgd;
}
else if(findcourse.getMethod().equals("实验")){
NoExamgd noExamgd=new NoExamgd();
double sumScore=0;
for (int i=4;i<inputs.length;i++)sumScore+=Integer.parseInt(inputs[i]);
noExamgd.setFinalgd((int)(sumScore/Integer.parseInt(inputs[3])));
gd=noExamgd;
}
else {
NoExamgd noExamgd=new NoExamgd();
noExamgd.setFinalgd(Integer.parseInt(inputs[3]));
gd=noExamgd;
}
newSelectCourse.setgd(gd);
newSelectCourse.setStudent(newStudent);
selectCourses.add(newSelectCourse);
}
}
else System.out.println("wrong format");
}

private Course checkC(String courseName){
for (Course course:courses){
if(course.getName().equals(courseName))return course;
}
return null;
}

private Boolean checkStudent(String num){
for (Student student:students){
if(student.getNum().equals(num))return true;
}
return false;
}
private Boolean checkClass(String classnum){
for (String cname:Class){
if(cname.equals(classnum))return true;
}
return false;
}

private Boolean cs(String stunum,String cname){
for (SelectCourse selectCourse:selectCourses){
if(selectCourse.getStudent().getNum().equals(stunum)&&selectCourse.getCourse().getName().equals(cname))return true;
}
return false;
}

public void getnum(){

for (Student student:students){
double sum=0;
int count=0;
for (SelectCourse selectCourse:selectCourses){
if (selectCourse.getStudent().getNum().equals(student.getNum()))
{
sum+=selectCourse.getgd().getTotalgd();
count++;
}
}
if(count==0) System.out.println(student.getNum()+' '+student.getName()+' '+"did not take any exams");
else System.out.println(student.getNum()+' '+student.getName()+' '+(int)(sum/count));
}
}
public void getcourse(){
for (Course course:courses){
double sumUsualScore=0;
double sumFinalScore=0;
double sumTotalScore=0;
int count=0;
for(SelectCourse selectCourse:selectCourses){
if(selectCourse.getCourse().getName().equals(course.getName())){
count++;
sumTotalScore+=selectCourse.getgd().getTotalgd();
sumFinalScore+=selectCourse.getgd().getFinalgd();
if(selectCourse.getCourse().getMethod().equals("考试")){
sumUsualScore+=selectCourse.getgd().getUsualgd();
}
}
}
if (count==0) System.out.println(course.getName()+' '+"has no grades yet");
else if(course.getMethod().equals("考试"))System.out.println(course.getName()+' '+(int)(sumUsualScore/count)+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
else if(course.getMethod().equals("考察"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
else if(course.getMethod().equals("实验"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count));
}
}
public void getclass(){
for (String classnum:Class){
double sum=0;
int count=0;
for (SelectCourse selectCourse:selectCourses){
if(selectCourse.getStudent().getNum().substring(0,6).equals(classnum)){
sum+=selectCourse.getgd().getTotalgd();
count++;
}
}
if(count==0) System.out.println(classnum+' '+"has no grades yet");
else System.out.println(classnum+' '+(int)(sum/count));
}
}
public void Sort(){
students.sort(Comparator.comparing(Student::getNum));
courses.sort((x,y)->{
Collator instance = Collator.getInstance(Locale.CHINA);
return instance.compare(x.getName(), y.getName());
} );
Collections.sort(Class);
}
}

class Imatch {
static String stuNumMatching = "[0-9]{8}";
static String stuNameMatching = "\\S{1,10}";
static String scoreMatching = "(\\d|[1-9]\\d|100)";
static String courseNameMatching = "\\S{1,10}";
static String courseTypeMatching = "(选修|必修|实验)";
static String checkcourseTypeMatching = "(考试|考察|实验)";
static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
scoreMatching + "(\\s"+scoreMatching+")*";
public static int minput(String s) {
if (matchingCourse(s)) {
return 1;
}
if (matchingScore(s)) {
return 2;
}
return 0;
}
private static boolean matchingCourse(String s) {
return s.matches(courseInput);
}
private static boolean matchingScore(String s) {
return s.matches(scoreInput);
}

}
7-4 动物发声模拟器(多态)
这一题难度相对简单,而且都已经给了大部分的框架代码,只需要再添加补充功能代码,我的代码复杂度为1,比较简单。考察抽象类,细心一点很快就可以写完。

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

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

请在下面的【】处添加代码。

 
//动物发生模拟器.  请在下面的【】处添加代码。
public class AnimalShoutTest2 {
    public static void main(String[] args) {        
         Cat cat = new Cat();
         Dog dog = new Dog();        
        Goat goat = new Goat();
         speak(cat);
         speak(dog);
         speak(goat);
    }
    //定义静态方法speak()
    【】

}

//定义抽象类Animal
【】class Animal{
    【】
}
//基于Animal类,定义猫类Cat,并重写两个抽象方法
class Cat 【】{
    【】    
    【】
}
//基于Animal类,定义狗类Dog,并重写两个抽象方法
class Dog 【】{
    【】
    【】
}
//基于Animal类,定义山羊类Goat,并重写两个抽象方法
class Goat 【】{
    【】
    【】
}
类图:

 结果截图:

 代码:

public class Main {
public static void main(String[] args) {
Animal cat = new Cat();
Animal dog = new Dog();
Animal goat = new Goat();
speak(cat);//由于这里的speak方法并没有返回值,所以是void类型
speak(dog);
speak(goat);
}

//定义静态方法speak(),这里直接按题目要求即可
//Animal animal这里的意思是创建一个动物的对象,将上面传入的动物类别与子类对应后输出
public static void speak(Animal animal) {
System.out.println(animal.getAnimalClass() + "的叫声:" + animal.shout());
}
}

//定义父类Animal
abstract class Animal {
//按要求写抽象方法,以下就是标准的写发(不用加大括号)
abstract public String getAnimalClass();
abstract public String shout();
}


//定义猫类,并重写方法实现多态(既方法的多态)
class Cat extends Animal {

//@Override是在重写方法是很重要的一个语法,必须写
@Override
public String getAnimalClass()
{
return "猫";
}
@Override
public String shout()
{
return "喵喵";
}

}

//定义一个狗类,和猫类一样
class Dog extends Animal {

@Override
public String getAnimalClass()
{
return "狗";
}
@Override
public String shout()
{
return "汪汪";
}
}

//定义一个山羊类,和上面一样
class Goat extends Animal{

@Override
public String getAnimalClass()
{
return "山羊";
}
@Override
public String shout()
{
return "咩咩";
}
}

7-3 jmu-Java-02基本语法-03-身份证排序

1、输入n,然后连续输入n个身份证号。

2、然后根据输入的是sort1还是sort2,执行不同的功能。输入的不是sort1或sort2,则输出exit并退出。

输入sort1,将每个身份证的年月日抽取出来,按年-月-日格式组装,然后对组装后的年-月-日升序输出。
输入sort2,将所有身份证按照里面的年月日升序输出。

这一道题实现了对所输入的身份证好嘛进行排序的功能。程序会先读取客户端输入的身份证数量和对应的信息,然后分别输入两个指令,当输入sort1是,会对身份证按照年化月日进行排序,并且输出;当输入sort2是,会对身份证的年月日进行排序,并且输入;如果输入其他指令,则程序会输出exit并且退出

类图就不放了,看一看耦合度和圈复杂度:

结果截图

 

 源代码:

import java.util.*;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("");
int n = Integer.parseInt(scanner.nextLine());

ArrayList<String> idNumbers = new ArrayList<>();

System.out.print("");
for (int i = 0; i < n; i++) {
String idNumber = scanner.nextLine();
idNumbers.add(idNumber);
}
while (true) {
System.out.print("");
String sortType = scanner.nextLine();

if (sortType.equals("sort1")) {
ArrayList<String> sortedDates = new ArrayList<>();
for (String id : idNumbers) {
String date = id.substring(6, 14); // 假设身份证号中日期的格式为yyyyMMdd,位置从6到14
String formattedDate = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8);
sortedDates.add(formattedDate);
}
Collections.sort(sortedDates);
for (String date : sortedDates) {
System.out.println(date);
}
} else if (sortType.equals("sort2")) {
TreeMap<String, String> sortedIdNumbers = new TreeMap<>();
for (String id : idNumbers) {
String date = id.substring(6, 14); // 假设身份证号中日期的格式为yyyyMMdd,位置从6到14
String formattedDate = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8);
sortedIdNumbers.put(formattedDate, id);
}
for (String id : sortedIdNumbers.values()) {
System.out.println(id);
}
} else if (sortType.equals("e")) {
System.out.println("exit");
break;
} else {
System.out.println("Invalid input. Please enter sort1, sort2, or e");
}
}

scanner.close();
}
}
7-2 课程成绩统计程序-3

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

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

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

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

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

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

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

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

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

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

1、输入:

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

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

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

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

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

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

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

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

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

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

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

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

这道题在上一道7-2课程成绩统计程序-2的基础上新增加了权重,实验课和考试课都要按照题目给定的权重来计算最终成绩,而最终的整个类结构不变,类图参照上面已给出课程成绩统计程序-2的类图。

以下是各个类的简单介绍:

有主要的三个类:Course、Student和Choose

Course类表示课程,包含课程的名称、性质、考核方式和实验课成绩数量等属性。
Student类表示学生,包含学号和姓名属性,并实现了Comparable接口,以便对学生对象进行排序。
Choose类表示学生选择的课程,包含学生、课程和成绩等属性。

Classroom类:班级类,包括班号和学生列表,实现了Comparable接口,可以进行排序操作。
Grade类:成绩类,包括总成绩字段。
Examgrade、Inspectgrade和Experiment类
Jugde类:工具类,包含了各种判断、查询、排序等方法,用于辅助实现程序功能。

由于个人水平有限代码只能编写出部分,未能实现完整功能
结果截图:

 7-5 jmu-Java-03面向对象基础-05-覆盖

Java每个对象都继承自Object,都有equals、toString等方法。
现在需要定义PersonOverride类并覆盖其toStringequals方法。

1. 新建PersonOverride类

a. 属性:String nameint ageboolean gender,所有的变量必须为私有(private)。

b. 有参构造方法,参数为name, age, gender

c. 无参构造方法,使用this(name, age,gender)调用有参构造方法。参数值分别为"default",1,true

d.toString()方法返回格式为:name-age-gender

e. equals方法需比较name、age、gender,这三者内容都相同,才返回true.

2. main方法

2.1 输入n1,使用无参构造方法创建n1个对象,放入数组persons1。
2.2 输入n2,然后指定name age gender。每创建一个对象都使用equals方法比较该对象是否已经在数组中存在,如果不存在,才将该对象放入数组persons2。
2.3 输出persons1数组中的所有对象
2.4 输出persons2数组中的所有对象
2.5 输出persons2中实际包含的对象的数量
2.5 使用System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));输出PersonOverride的所有构造方法。

提示:使用ArrayList代替数组大幅复简化代码,请尝试重构你的代码。

这道题定义了一个PersonOverride类,包含有一个无参构造函数和一个有参构造函数。还包含了一个Main类,有main方法,而在main方法中,通过Scanner先读取了我们输入的信息,创建两个ArrayList对象,分别存储了PO对象。

类图:

 结果截图:

 代码:

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n1 = in.nextInt();
int i;
PersonOverride person1[] = new PersonOverride[n1];
for (i = 0; i < n1; i++) {
person1[i] = new PersonOverride();
}
int n2 = in.nextInt();
PersonOverride person2[] = new PersonOverride[n2];
int count=0;
PersonOverride p = null;
for (i = 0; i < n2; i++) {
p = new PersonOverride(in.next(), in.nextInt(), in.nextBoolean());
int j = 0;
while (j < count) {
if (p.equals(person2[j]))
break;
j++;
}
if (j >= count) {
person2[count] = p;
count++;
}
}
in.close();
for(i=0;i<n1;i++)
{
System.out.println(person1[i].toString());
}
for (i = 0; i < count; i++) {
System.out.println(person2[i].toString());
}
System.out.println(count);
System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));
}
}

class PersonOverride {
private String name;
private int age;
private boolean gender;

public PersonOverride() {
this("default", 1, true);
}

public PersonOverride(String name, int age, boolean gender) {
this.name=name;
this.age=age;
this.gender=gender;
}

@Override
public String toString() {
return name + "-" + age + "-"+ gender;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + (gender ? 1231 : 1237);
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PersonOverride other = (PersonOverride) obj;
if (age != other.age)
return false;
if (gender != other.gender)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

}

期末考试题目集:

7-1 立体图形问题

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

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

 

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

 
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)

进行小数位数控制。

这是期末考试的第一道编程题,总的来说难度适中,重点考察了继承和多态性的考法,我在最后算三角锥的体积当中总是出问题,后来才发现是自己的相关代码实现部分上面出了问题,求三角锥体积公式的代码写错了。后来修改后顺利求得。

结果截图:

 在上述代码中,我定义了一个抽象类Solid作为父类,包含了边长side成员变量和计算表面积和体积的抽象方法。然后分别创建了CubeRegularPyramid子类,继承Solid类,并实现抽象方法。在Main类中,我通过调用display方法实现了多态性的体现。

代码:

import java.util.Scanner;

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

class Cube extends Solid {
private double side;

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

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

@Override
public double getVolume() {
return Math.pow(side, 3);
}
}

class RegularPyramid extends Solid {
private double side;
private double height;
public RegularPyramid(double side) {
this.side = side;
this.height = Math.sqrt(3) / 2 * side;
}

@Override
public double getSurfaceArea() {
double baseArea = (side * side * Math.sqrt(3))/4;
double lateralArea = 3 * side * height / 2;

return baseArea+lateralArea;
}

@Override
public double getVolume() {
return (Math.sqrt(2) / 12) * side * side * side;
}
}

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) {
System.out.println("" + String.format("%.2f", solid.getSurfaceArea()));
System.out.println("" + String.format("%.2f", solid.getVolume()));

}
}

7-2 魔方问题

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

 

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

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

 

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

 

 
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类中定义的静态方法,用户输出魔方的信息,用于体现多态性。

输入格式:

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

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

输出格式:

正方体魔方颜色

正方体魔方表面积

正方体魔方体积

正三棱锥魔方颜色

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

注:小数点保留两位

由于时间问题,在前面的题目当中花费了太多时间,所以最后几题没有顺利完成。这道题也是还差就在三角锥模仿的表面积上面出了问题,输入值没能求出正确的体积。

代码:

import java.util.Scanner;

abstract class Solid {
protected String color;
protected int layer;

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

abstract double getSurfaceArea();

abstract double getVolume();
}

class Cube extends Solid {
protected double side;

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

@Override
public double getSurfaceArea() {
return 6 * Math.pow(layer * side, 2);
}

@Override
public double getVolume() {
return Math.pow(layer * side, 3);
}
}

class RegularPyramid extends Solid {
protected double side;

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

@Override
public double getSurfaceArea() {
double baseArea = Math.pow(layer * side, 2);
double lateralArea = (Math.sqrt(3) / 4) * Math.pow(side, 2);
return baseArea + layer * lateralArea;
}

@Override
public double getVolume() {
return (Math.sqrt(2) / 12) * Math.pow(layer * side, 3);
}
}

class RubikCube {
private Solid solid;

public RubikCube(Solid solid) {
this.solid = solid;
}

public String getColor() {
return solid.color;
}

public double getSurfaceArea() {
return solid.getSurfaceArea();
}

public double getVolume() {
return solid.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();

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

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

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

display(cube1);
display(cube2);
}

public static void display(RubikCube cube) {
System.out.println("Color: " + cube.getColor());
System.out.println("Surface Area: " + String.format("%.2f", cube.getSurfaceArea()));
System.out.println("Volume: " + String.format("%.2f", cube.getVolume()));
System.out.println();
}
}

结果截图:

 三、踩坑心得

踩坑:
1 当程序中需要读取用户输入的成绩信息时,题目要求按照相应的格式输入时。在读取用户的输入信息后,要注意格式的正确,一面出现错误导致异常。
2 当读取用户输入后,题目需要数据类型的转换,将字符串转换为数字,以便进行计算和存储。要注意数据的范围和精度,以免发生数据溢出或精度丢失的情况。
3 在统计成绩时,需要进行一系列的计算,包括平均成绩、最高分、最低分等。在进行计算时,要注意算法的正确性和效率,以确保程序能够正确地处理大量数据。
心得:
1在编写程序时,要将任务拆分成逻辑清晰、功能独立的模块,便于调试和维护。可以使用函数、类、模块等方式实现模块化编程。
2在处理用户输入、数据计算等过程中,难免会出现错误和异常。在编写程序时,要考虑到这些可能出现的问题,并进行相应的错误处理和异常处理,以避免程序崩溃或出现不可预知的错误。
3编写清晰、易读的代码是非常重要的。在编写程序时,要注意代码风格和注释规范,以便于他人理解和修改代码。可以采用一些编码规范和注释规范,例如Google编码规范和JavaDoc注释规范等。

四、改进建议

还是设计类不够准确和熟练。

1学习好Java的基础知识和概念:在开始编写Java代码之前,要先学习好Java的基础知识和概念,例如语法、面向对象编程、数据结构和算法等,这有助于更好的理解和掌握Java编程。

2遵守Java的编码规范和风格:在编写Java代码时,应该遵守Java的编码规范和风格,例如命名规范、缩进、注释等,这有助于提高代码的可读性和可维护性。

3 熟悉Java的类库和API:Java拥有庞大的类库和API,熟悉其中的常用类和方法可以提高编写Java代码的效率和质量。可以预先学习一下Java中常用的类和方法,或者在编写代码时查询相关资料。

五、总结
总的来说这两次题目集还是相当好的,在保证量的同时也适当维持了难度,对于提升学生的继承多态方法的能力有很大的进步,通过这几次的作业以及期末考试,我更加掌握熟悉了继承。接口,多态,类与类结构等等的
概念和应用,对java的理解和使用又熟悉了许多,美中不足的是期末考试未能发挥好,但是相信之后的学习可以再好一点。