大作业分析-3

前言:

本次将会分析第六次大作业,第七次大作业和第八次大作业的部分题目。这三期大作业主要题目从餐馆变成了课程成绩统计程序,难度较之前来说还行,可能是因为我学得更通透了。接下来会主要分析一下三次大作业中的课程成绩统计程序题目。

 

第六次大作业:

本次大作业作为第一次的课程成绩统计程序题目。初次见这种题目,所以里面判定的问题很大。mapset我初次使用起来还是用的相对满意的,不枉我到处找资料补。本次作业主要是考察课程,学生,成绩,班级的储存计算和排序,主要需要HashSetHashMap的使用。

第七次大作业:

本次大作业主要难度还是集中在课程统计程序题目。其他题目主要是考察HashMap的使用及多态;而本次课程成绩统计程序题目相较上次题目新增了实验课的选项,及新的计分方式,总体框架并无大改。

第八次大作业:

本次大作业难度照样集中在课程统计程序题目。其他题目主要是考察ArrayList的使用,排序及覆写;而课程成绩统计程序题目则小改了一波,将按固定权值计算成绩改成了权值由用户输入。整体框架小改了一波,难度也提升了一波。

 

接下来会着重分析几道我认为重点的题目。

 

设计与分析:

课程成绩统计程序-1

代码:

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


public class Main {
    public static void main(String[] args)
    {
        Scanner in=new Scanner(System.in);
        int c=0;//判断是否开始输入成绩,0为输入课程,1为输入成绩
        int d=0;
        HashMap<String,Course> allcourse=new HashMap<String,Course>();
        HashMap<String,Student> allstudent=new HashMap<String,Student>();
        HashSet<Control> selection=new HashSet<Control>();
        HashMap<String,Class> allclass=new HashMap<String,Class>();
        while(true)
        {
            String a=in.nextLine();
            if(a.equals("end"))//结束
                break;
            String[] b=a.split(" ");
            if(b.length!=3&&b.length!=2)
                c=1;
            //输入课程
            if(c==0)
            {
                if(b[0].length()>10)//课程名称超过十个
                    System.out.println("wrong format");
                else if((!b[1].equals("必修")&&!b[1].equals("选修")))
                    System.out.println("wrong format");
                else if(b.length==3&&(!b[2].equals("考试")&&!b[2].equals("考察")))
                    System.out.println("wrong format");
                else if(b.length==3&&b[1].equals("必修")&&b[2].equals("考察"))//输入的课程性质和课程的考核方式不匹配
                    System.out.println(b[0]+" : course type & access mode mismatch");
                
                else if(allcourse.get(b[0])!=null)//课程重复忽略
                    continue;
                else if(b[1].equals("必修"))//必修课
                {
                    Course course=new RequiredCourse(b[0]);
                    allcourse.put(b[0],course);
                }
                else if(b[1].equals("选修"))//选修课
                {
                    Course course=new OptionalCourse(b[0],b[2]);
                    allcourse.put(b[0],course);
                }
                else
                    System.out.println("wrong format");
            }
            //输入学生成绩
            else
            {
                if(b[0].length()!=8||b[1].length()>10)//学号不为八位或者名字大于十
                    System.out.println("wrong format");
                else if(allcourse.get(b[2])==null)//课程名称不在已输入的课程列表中
                {
                    System.out.println(b[2]+" does not exist");
                    if(allstudent.get(b[0])==null)
                    {
                        Student student=new Student(b[1],b[0]);
                        allstudent.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6),cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                }
                else if(b.length==4)
                {
                    if(!b[3].matches("[0-9]||[1-9][0-9]||100"))//超出成绩取值范围
                        System.out.println("wrong format");
                    else if(allcourse.get(b[2]).assess().equals("考试"))//只输入了期末成绩,但是是考试课
                    {
                        System.out.println(b[0]+" "+b[1]+" : access mode mismatch");
                        if(allstudent.get(b[0])==null)
                        {
                            Student student=new Student(b[1],b[0]);
                            allstudent.put(b[0],student);
                            if(allclass.get(b[0].substring(0,6))==null)
                            {
                                Class cla=new Class();
                                cla.addnum(b[0].substring(0,6));
                                allclass.put(b[0].substring(0,6),cla);
                            }
                            allclass.get(b[0].substring(0,6)).addstu(student);
                        }
                    }
                else if(judge(selection,allstudent.get(b[0]),allcourse.get(b[2])))
                    continue;
                    else//输入考察学生成绩
                    {
                        Achievement achievement=new Examine(Integer.parseInt(b[3]));
                        Control control=new Control();
                        if(allstudent.get(b[0])==null)
                        {
                            Student student=new Student(b[1],b[0]);
                            allstudent.put(b[0],student);
                            control.addmessage(student,allcourse.get(b[2]),achievement);
                            if(allclass.get(b[0].substring(0,6))==null)
                            {
                                Class cla=new Class();
                                cla.addnum(b[0].substring(0,6));
                                allclass.put(b[0].substring(0,6),cla);
                            }
                            allclass.get(b[0].substring(0,6)).addstu(student);
                        }
                        else
                            control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement);
                        selection.add(control);
                    }
                }
                else if(b.length==5)
                {
                    if(!b[3].matches("[0-9]||[1-9][0-9]||100")||!b[4].matches("[0-9]||[1-9][0-9]||100"))//超出成绩取值范围
                        System.out.println("wrong format");
                    else if(allcourse.get(b[2]).assess().equals("考察"))//输入了平时和期末成绩,但是是考察课
                    {
                        System.out.println(b[0]+" "+b[1]+" : access mode mismatch");
                        if(allstudent.get(b[0])==null)
                        {
                            Student student=new Student(b[1],b[0]);
                            allstudent.put(b[0],student);
                            if(allclass.get(b[0].substring(0,6))==null)
                            {
                                Class cla=new Class();
                                cla.addnum(b[0].substring(0,6));
                                allclass.put(b[0].substring(0,6),cla);
                            }
                            allclass.get(b[0].substring(0,6)).addstu(student);
                        }
                    }
                else if(judge(selection,allstudent.get(b[0]),allcourse.get(b[2])))
                    continue;
                    else//输入考试学生成绩
                    {
                        Achievement achievement=new Text(Integer.parseInt(b[3]),Integer.parseInt(b[4]));
                        Control control=new Control();
                        if(allstudent.get(b[0])==null)
                        {
                            Student student=new Student(b[1],b[0]);
                            allstudent.put(b[0],student);
                            if(allclass.get(b[0].substring(0,6))==null)
                            {
                                Class cla=new Class();
                                cla.addnum(b[0].substring(0,6));
                                allclass.put(b[0].substring(0,6),cla);
                            }
                            allclass.get(b[0].substring(0,6)).addstu(student);
                            control.addmessage(student,allcourse.get(b[2]),achievement);
                        }
                        else
                            control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement);
                        selection.add(control);
                    }
                }
                else//未输入成绩或其他
                {
                    System.out.println("wrong format");
                    if(allstudent.get(b[0])==null)
                    {
                        Student student=new Student(b[1],b[0]);
                        allstudent.put(b[0],student);
                    }
                }
            }
        }
        List<Student> mapValues = new ArrayList<>(allstudent.values()); 
        Collections.sort(mapValues);
        for(Student i:mapValues)
        {
            int s=0;
            int n=0;
            for(Control j:selection)
                if(i==j.student())
                {
                    s+=j.gettotalscore();
                    n++;
                }
            if(n==0)
                System.out.println(i.number()+" "+i.name()+" did not take any exams");
            else
            {
                s/=n;
                System.out.println(i.number()+" "+i.name()+" "+s);
            }
        }
        List<Course> courseValues = new ArrayList<>(allcourse.values()); 
        Collections.sort(courseValues,new SortName());
        for(Course i:courseValues)
        {
            int u=0;//平时
            int f=0;//期末
            int s=0;//
            int n=0;
            for(Control j:selection)
                if(i==j.course())
                {
                    if(i.assess().equals("考试"))
                        u+=j.score().usualperformance();
                    f+=j.score().finalgrade();
                    s+=j.gettotalscore();
                    n++;
                }
            if(n==0)
                System.out.println(i.name()+" has no grades yet");
            else
            {
                System.out.print(i.name());
                if(i.assess().equals("考试"))
                {
                    u/=n;
                    System.out.print(" "+u);
                }
                f/=n;
                s/=n;
                System.out.println(" "+f+" "+s);
            }
        }
        for(Class i:allclass.values())
            i.gettotalscore(selection);
        List<Class> classValues = new ArrayList<>(allclass.values()); 
        Collections.sort(classValues);
        for(Class i:classValues)
        {
            if(!i.clascr(selection))
                System.out.println(i.num()+" has no grades yet");
            else
                System.out.println(i.num()+" "+i.gettotalscore(selection));
        }
    }
    public static boolean judge(HashSet<Control> o,Student s,Course c)
    {
        for(Control i:o)
            if(i.student()==s&&i.course()==c)
                return true;
        return false;
    }
}

//每门课程
abstract class Course
{
    private String name;//课程名称
    private String assess;
    void name(String name)
    {
        this.name=name;
    }
    void addassess(String b)
    {
        assess=b;
    }
    String name()
    {
        return name;
    }
    String assess()
    {
        return assess;
    }
}
//必修课
class RequiredCourse extends Course
{
    RequiredCourse(String name)
    {
        name(name);
        addassess("考试");
    }

}
//选修课
class OptionalCourse extends Course
{
    OptionalCourse(String name,String b)
    {
        name(name);
        addassess(b);
    }
}
//学生
class Student implements Comparable<Student>
{
    private String name;//名字
    private String number;//学号
    Student(String name,String number)
    {
        this.name=name;
        this.number=number;
    }
    String name()
    {
        return name;
    }
    String number()
    {
        return number;
    }
    @Override
    public    int compareTo(Student o)
    {
         return this.number.compareTo(o.number());
    }
}
//选课中心
class Control
{
    private Student student;//学生信息
    private Course course;//课程信息
    private Achievement score;//成绩信息
    int gettotalscore()//计算该成绩
    {
        return score.gettotalscore();
    }
    Student student()
    {
        return this.student;
    }
    Course course()
    {
        return this.course;
    }
    Achievement score()
    {
        return score;
    }
    void addmessage(Student s,Course c,Achievement a)
    {
        this.student=s;
        this.course=c;
        this.score=a;
    }
}
//成绩
abstract class Achievement
{
    private int finalgrade;//期末成绩
    private int usualperformance;//平时成绩
    int finalgrade()
    {
        return this.finalgrade;
    }
    int usualperformance()
    {
        return this.usualperformance;
    }
    void addfinal(int fina)//添加期末成绩
    {
        this.finalgrade=fina;
    }
    void addusual(int usual)//添加平时成绩
    {
        this.usualperformance=usual;
    }
    abstract int gettotalscore();//计算总成绩
}
//考试成绩
class Text extends Achievement
{
    Text(int usual,int fina)//添加成绩
    {
        this.addfinal(fina);
        this.addusual(usual);
    }
    int gettotalscore()
    {
        return (int)(usualperformance()*0.3+finalgrade()*0.7);
    }
}
//考察成绩
class Examine extends Achievement
{
    Examine(int finalgrade)//添加成绩
    {
        this.addfinal(finalgrade);
    }
    int gettotalscore()
    {
        return finalgrade();
    }
}
//班级
class Class implements Comparable<Class>
{
    private String num;//班级序号
    private HashSet<Student> students=new HashSet<Student>();//学生
    void addnum(String num)
    {
        this.num=num;
    }
    String num()
    {
        return num;
    }
    void addstu(Student student)
    {
        students.add(student);
    }
    boolean clascr(HashSet<Control> o)//判断该班是否有成绩
    {
        int n=0;
        for(Student a:this.students)
            for(Control b:o)
            {
                if(b.student()==a)
                    n++;
            }
        if(n==0)
            return false;
        return true;
    }
    int gettotalscore(HashSet<Control> o)
    {
        int s=0;
        int n=0;
        int m=0;
        for(Student a:this.students)
        {
            m=0;
            n=0;
            for(Control b:o)
            {
                if(b.student()==a)
                {
                    n+=b.gettotalscore();
                    m++;
                }
            }
            if(m!=0)
                n/=m;
            s+=n;
        }
        return s/=students.size();
    }
    @Override
    public int compareTo(Class o)
    {
        return this.num.compareTo(o.num());
    }
}
class SortName implements Comparator<Course> 
{
     @Override
      public int compare(Course o,Course o1) 
     {
        Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
        return compare.compare(o.name(),o1.name());
      }
}

 

 

因为老师在课上讲过相关类图设计,所以相对的,这道题目在设计上并没有让我苦恼太久。主要问题还是在HashMapHashSet的使用和选择上。

这道题目的整体框架是有问题的,不过这部分我会放在踩坑心得里细讲。先讲一下我写题目时的分析。

在一开始老师便提示我们这道题要用Map来做,但是因为我完全没听过所以完全不能理解为什么,和ListSet的区别在哪里。在查阅部分资料后我理解了。MapListSet最大的区别就是它拥有“键值对”(key-value)。键便类似于一个人的身份证号,我知道了你的身份证号,我就能知道你是谁;而值就是这个身份证号对应的一个人的信息。相比起只能使用i或遍历查询内容的ListSet中,Map能使用key来直接查询内容,这便是它的最大优点。所以我们可以用map来储存学生信息(key-学号,value-学生类),课程信息(key-课程名称,value-课程类)及班级信息(key-班级号,value-班级类)。至于选课系统类,我选用了Set(后面也用了List,我感觉没有很大差别?)。

至于后面的按学号课程名称等等排序,我发现无论是Map还是Set都无法直接排序,必须先将他们转化为List才能排序。当然我也不确定是不是我搜索的不全,如果有直接用Map或者Set排序的方法请务必告诉我……

说起来写这个的时候有件好笑的事。我写的比较晚,所以我还没开始写的时候某不愿透露姓名的班长同学已经写完了。然后他跟我吐槽他超过400行就交不上去了,我当时人都傻了。导致后面写到超过400行的时候心里就很悬生怕交不上去,然后发现我的能交欸,乐.jpg。所以这是为什么呢?

 

课程成绩统计程序-2

 代码:

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


public class Main {
    public static void main(String[] args)
    {
        Scanner in=new Scanner(System.in);
        int d=0;
        int g=0;
        HashMap<String,Course> allcourse=new HashMap<String,Course>();//总课程,String存课程名称
        HashMap<String,Student> allstudent=new HashMap<String,Student>();//总学生,String存学号
        HashSet<Control> selection=new HashSet<Control>();//总选课系统
        HashMap<String,Class> allclass=new HashMap<String,Class>();//总班级,String存班号
        while(true)
        {
            String a=in.nextLine();
            if(a.equals("end"))//结束
                break;
            String[] b=a.split(" ");
            //输入课程信息
            if(a.matches("(\\S{1,10})( )(必修|选修|实验)(( )(考试|考察|实验))?"))
            {
                if(b.length==2)
                {
                    if(b[1].equals("选修")||b[1].equals("实验"))//输入的课程性质和课程的考核方式不匹配
                        System.out.println(b[0]+" : course type & access mode mismatch");
                    else if(allcourse.get(b[0])!=null)//重复输入忽略本条
                        continue;
                    else if(b[1].equals("必修"))//正常输入必修课
                    {
                        Course course=new RequiredCourse(b[0]);
                        allcourse.put(b[0],course);
                    }
                    else//正常输入实验课
                    {
                        Course course=new Experimentallesson(b[0]);
                        allcourse.put(b[0],course);
                    }
                        
                }
                else
                {
                    if((b[1].equals("必修")&&!b[2].equals("考试"))||(b[1].equals("实验")&&!b[2].equals("实验"))||(b[1].equals("选修")&&b[2].equals("实验")))//输入的课程性质和课程的考核方式不匹配
                        System.out.println(b[0]+" : course type & access mode mismatch");
                    else if(allcourse.get(b[0])!=null)//重复输入课程
                        continue;
                    else if(b[1].equals("必修"))//正常输入必修课
                    {
                        Course course=new RequiredCourse(b[0]);
                        allcourse.put(b[0],course);
                    }
                    else if(b[1].equals("选修"))//正常输入选修课
                    {
                        Course course=new OptionalCourse(b[0],b[2]);
                        allcourse.put(b[0],course);
                    }
                    else//正常输入实验课
                    {
                        Course course=new Experimentallesson(b[0]);
                        allcourse.put(b[0],course);
                    }
                }
            }
            //输入考试/考察成绩信息
            else if(a.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})( )(\\d{1,2}|(100))(( )(\\d{1,2}|(100)))?"))
            {
                if(allcourse.get(b[2])==null)//课程名称不在已输入的课程列表中
                {
                    System.out.println(b[2]+" does not exist");
                    if(allstudent.get(b[0])==null)
                    {
                        Student student=new Student(b[1],b[0]);
                        allstudent.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6),cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                }
                else if((allcourse.get(b[2]).assess().equals("考试")&&b.length==4)||(allcourse.get(b[2]).assess().equals("考察")&&b.length==5))//输入的成绩数量和课程的考核方式不匹配
                {
                    System.out.println(b[0]+" "+b[1]+" : access mode mismatch");
                    if(allstudent.get(b[0])==null)
                    {
                        Student student=new Student(b[1],b[0]);
                        allstudent.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6),cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                }
                else if(judge(selection,allstudent.get(b[0]),allcourse.get(b[2])))//重复的成绩信息
                    continue;
                else if(allcourse.get(b[2]).assess().equals("考试"))//输入考试课成绩信息
                {
                    Achievement achievement=new Text(Integer.parseInt(b[3]),Integer.parseInt(b[4]));
                    Control control=new Control();
                    if(allstudent.get(b[0])==null)
                    {
                        Student student=new Student(b[1],b[0]);
                        allstudent.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6),cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                    control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement);
                    selection.add(control);
                }
                else//输入考察课成绩信息
                {
                    Achievement achievement=new Examine(Integer.parseInt(b[3]));
                    Control control=new Control();
                    if(allstudent.get(b[0])==null)
                    {
                        Student student=new Student(b[1],b[0]);
                        allstudent.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6),cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                    control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement);
                    selection.add(control);
                }
            }
            //输入实验成绩
            else if(a.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})( )([4-9])( )((\\d{1,2}|(100))( ))*(\\d{1,2}|(100)*)"))
            {
                if(allcourse.get(b[2])==null)//课程名称不在已输入的课程列表中
                {
                    System.out.println(b[2]+" does not exist");
                    if(allstudent.get(b[0])==null)
                    {
                        Student student=new Student(b[1],b[0]);
                        allstudent.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6),cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                }
                else if((b.length-4)!=Integer.parseInt(b[3]))//输入的课程性质和课程的考核方式不匹配
                {
                    System.out.println(b[0]+" "+b[1]+" : access mode mismatch");
                    if(allstudent.get(b[0])==null)
                    {
                        Student student=new Student(b[1],b[0]);
                        allstudent.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6),cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                }
                else if(judge(selection,allstudent.get(b[0]),allcourse.get(b[2])))//重复的成绩信息
                    continue;
                else//输入实验成绩信息
                {
                    int[] e=new int[Integer.parseInt(b[3])];
                    for(int i=0;i<Integer.parseInt(b[3]);i++)
                        e[i]=Integer.parseInt(b[i+4]);
                    Achievement achievement=new Experimental(Integer.parseInt(b[3]),e);
                    Control control=new Control();
                    if(allstudent.get(b[0])==null)
                    {
                        Student student=new Student(b[1],b[0]);
                        allstudent.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6),cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                    control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement);
                    selection.add(control);
                }
            }
            else
                System.out.println("wrong format");
        }
        List<Student> mapValues = new ArrayList<>(allstudent.values()); 
        Collections.sort(mapValues);
        for(Student i:mapValues)
        {
            int s=0;
            int n=0;
            for(Control j:selection)
                if(i==j.student())
                {
                    s+=j.gettotalscore();
                    n++;
                }
            if(n==0)
                System.out.println(i.number()+" "+i.name()+" did not take any exams");
            else
            {
                s/=n;
                System.out.println(i.number()+" "+i.name()+" "+s);
            }
        }
        List<Course> courseValues = new ArrayList<>(allcourse.values()); 
        Collections.sort(courseValues,new SortName());
        for(Course i:courseValues)
        {
            int u=0;//平时
            int f=0;//期末
            int s=0;//
            int n=0;
            for(Control j:selection)
                if(i==j.course())
                {
                    if(i.assess().equals("考试"))
                    {
                        u+=j.score().usual();
                        f+=j.score().fina();
                    }
                    else if(i.assess().equals("考察"))
                        f+=j.score().fina();
                    s+=j.score().gettotalscore();
                    n++;
                }
            if(n==0)
                System.out.println(i.name()+" has no grades yet");
            else
            {
                System.out.print(i.name());
                s/=n;
                if(i.assess().equals("考试"))
                {
                    u/=n;
                    f/=n;
                    System.out.println(" "+u+" "+f+" "+s);
                }
                else if(i.assess().equals("考察"))
                {
                    f/=n;
                    System.out.println(" "+f+" "+s);
                }
                else
                    System.out.println(" "+s);
            }
        }
//        for(Class i:allclass.values())
    //        i.gettotalscore(selection);
        List<Class> classValues = new ArrayList<>(allclass.values()); 
        Collections.sort(classValues);
        for(Class i:classValues)
        {
            if(!i.clascr(selection))
                System.out.println(i.num()+" has no grades yet");
            else
                System.out.println(i.num()+" "+i.gettotalscore(selection));
        }
    }
    public static boolean judge(HashSet<Control> o,Student s,Course c)
    {
        for(Control i:o)
            if(i.student()==s&&i.course()==c)
                return true;
        return false;
    }
}

//每门课程
abstract class Course
{
    private String name;//课程名称
    private String assess;
    void name(String name)
    {
        this.name=name;
    }
    void addassess(String b)
    {
        assess=b;
    }
    String name()
    {
        return name;
    }
    String assess()
    {
        return assess;
    }
}
//必修课
class RequiredCourse extends Course
{
    RequiredCourse(String name)
    {
        name(name);
        addassess("考试");
    }

}
//选修课
class OptionalCourse extends Course
{
    OptionalCourse(String name,String b)
    {
        name(name);
        addassess(b);
    }
}
//实验课
class Experimentallesson extends Course
{
    Experimentallesson(String name)
    {
        name(name);
        addassess("实验");
    }
}
//学生
class Student implements Comparable<Student>
{
    private String name;//名字
    private String number;//学号
    Student(String name,String number)
    {
        this.name=name;
        this.number=number;
    }
    String name()
    {
        return name;
    }
    String number()
    {
        return number;
    }
    @Override
    public    int compareTo(Student o)
    {
        return this.number.compareTo(o.number());
    }
}
//选课中心
class Control
{
    private Student student;//学生信息
    private Course course;//课程信息
    private Achievement score;//成绩信息
    int gettotalscore()//计算该成绩
    {
        return score.gettotalscore();
    }
    Student student()
    {
        return this.student;
    }
    Course course()
    {
        return this.course;
    }
    Achievement score()
    {
        return score;
    }
    void addmessage(Student s,Course c,Achievement a)
    {
        this.student=s;
        this.course=c;
        this.score=a;
    }
}
//成绩
abstract class Achievement
{
    private int finalgrade;//期末成绩
    private int usualperformance;//平时成绩
    void addfinal(int fina)
    {
        this.finalgrade=fina;
    }
    void addusual(int usual)
    {
        this.usualperformance=usual;
    }
    int fina()
    {
        return this.finalgrade;
    }
    int usual()
    {
        return this.usualperformance;
    }
    abstract int gettotalscore();//计算总成绩
}
//考试成绩
class Text extends Achievement
{
    Text(int usual,int fina)//添加成绩
    {
        addfinal(fina);
        addusual(usual);
    }
    int gettotalscore()
    {
        return (int)(usual()*0.3+fina()*0.7);
    }
}
//考察成绩
class Examine extends Achievement
{
    Examine(int finalgrade)//添加成绩
    {
        addfinal(finalgrade);
    }
    int gettotalscore()
    {
        return fina();
    }
}
class Experimental extends Achievement
{
    private int time;//实验次数
    private int[] score;//每次实验成绩
    Experimental(int time,int[] score)
    {
        this.score=new int[time];
        this.time=time;
        this.score=score;
    }
    @Override
    int gettotalscore() {
        int s=0;
        for(int i=0;i<this.time;i++)
            s+=score[i];
        return s/time;
    }
    
}
//班级
class Class implements Comparable<Class>
{
    private String num;//班级序号
    private HashSet<Student> students=new HashSet<Student>();//学生
    void addnum(String num)
    {
        this.num=num;
    }
    String num()
    {
        return num;
    }
    void addstu(Student student)
    {
        students.add(student);
    }
    boolean clascr(HashSet<Control> o)//判断该班是否有成绩
    {
        int n=0;
        for(Student a:this.students)
            for(Control b:o)
            {
                if(b.student()==a)
                    n++;
            }
        if(n==0)
            return false;
        return true;
    }
    int gettotalscore(HashSet<Control> o)
    {
        int s=0;
        int n=0;
        int m=0;
  int p=0;
        for(Student a:this.students)
        {
            m=0;
            n=0;
            for(Control b:o)
            {
                if(b.student()==a)
                {
                    n+=b.gettotalscore();
                    m++;
                }
            }
            if(m!=0)
                {
    n/=m;
    p++;
    }
            s+=n;
        }
  if(p!=0)
        return s/=p;
  return 0;
    }
    @Override
    public int compareTo(Class o)
    {
        return this.num.compareTo(o.num());
    }
}
class SortName implements Comparator<Course> 
{
     @Override
      public int compare(Course o,Course o1) 
     {
        Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
        return compare.compare(o.name(),o1.name());
      }
}

 

 

首先要感谢某不愿透露姓名的班长同学很努力的把我捞到了满分。他指出了我没注意到的错误并教我怎么改了,非常感谢能带懂憨憨。

说起来这个代码复杂度是不是低的吓人了软件真的没问题吗……我这么厉害我怎么不知道。

总之这道题目仅仅是相较上次增加了实验课,整体类图倒是无需大改,省了我很多时间。主要的问题在于我的判定情况出了很大问题导致样例过不去,同时也让我一下子意识到了我上道题目为什么没有满分。这点当然后面再说。

其实这道题要讲设计也没什么好讲的,和上道题目差不多。所以我们先跳下一道题。

(这道题某人依旧超400行交不上去,乐,这是被针对了吗)

 

课程成绩统计程序-3

 代码:

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

public class Main {
    public static void main(String[] args)
    {
        Scanner in=new Scanner(System.in);
        HashMap<String,Course> allcourse=new HashMap<String,Course>();
        HashMap<String,Student> allstu=new HashMap<String,Student>();
        ArrayList<Control> selection=new ArrayList<Control>();
        HashMap<String,Class> allclass=new HashMap<String,Class>();
        while(true)
        {
            String a=in.nextLine();
            if(a.equals("end"))
                break;
            String[] b=a.split(" ");
            //输入课程信息
            if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]))( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]))"))//输入考试课
            {
                if(b[1].equals("实验")||!b[2].equals("考试"))//输入的课程性质和课程的考核方式不匹配
                    System.out.println(b[0]+" : course type & access mode mismatch");
                else if((Float.parseFloat(b[3])+Float.parseFloat(b[4]))>1.01||(Float.parseFloat(b[3])+Float.parseFloat(b[4]))<0.99)//分项成绩权重值的总和不等于1
                    System.out.println(b[0]+" : weight value error");
                else if(allcourse.get(b[0])!=null)//重复课程信息
                    continue;
                else if(b[1].equals("必修"))//正常输入必修课
                {
                    float[] c=new float[2];
                    for(int i=0;i<2;i++)
                        c[i]=Float.parseFloat(b[i+3]);
                    Course course=new RequiredCourse(b[0],c);
                    allcourse.put(b[0],course);
                }
                else//正常输入选修课
                {
                    float[] c=new float[2];
                    for(int i=0;i<2;i++)
                        c[i]=Float.parseFloat(b[i+3]);
                    Course course=new OptionalCourse(b[0],c);
                    allcourse.put(b[0],course);
                }
            }
            else if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)"))//输入考察课
            {
                if(!b[1].equals("选修")||!b[2].equals("考察"))//输入的课程性质和课程的考核方式不匹配
                    System.out.println(b[0]+" : course type & access mode mismatch");
                else if(allcourse.get(b[0])!=null)//重复课程信息
                    continue;
                else//正常输入选修课
                {
                    Course course=new OptionalCourse(b[0]);
                    allcourse.put(b[0],course);
                }
            }
            else if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )([4-9])(( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])))*"))//输入实验课
            {
                float d=0;
                float[] c=new float[b.length-4];
                for(int i=0;i<(b.length-4);i++)
                {
                    c[i]=Float.parseFloat(b[i+4]);
                    d+=c[i];
                }
                if(!b[1].equals("实验")||!b[2].equals("实验"))//输入的课程性质和课程的考核方式不匹配
                    System.out.println(b[0]+" : course type & access mode mismatch");
                else if(Integer.parseInt(b[3])!=(b.length-4))//分项成绩数量值和分项成绩权重的个数不匹配
                    System.out.println(b[0]+" : number of scores does not match");
                else if(d>1.01||d<0.99)//分项成绩权重值的总和不等于1
                    System.out.println(b[0]+" : weight value error");
                else if(allcourse.get(b[0])!=null)//重复课程信息
                    continue;
                else//正常输入实验课
                {
                    Course course=new Experimentallesson(b[0],c);
                    allcourse.put(b[0],course);
                }    
            }
            else if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]))( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]))"))//输入考试课
            {
                if(!b[1].equals("必修"))//输入的课程性质和课程的考核方式不匹配
                    System.out.println(b[0]+" : course type & access mode mismatch");
                else if((Float.parseFloat(b[3])+Float.parseFloat(b[2]))>1.01||(Float.parseFloat(b[3])+Float.parseFloat(b[2]))<0.99)//分项成绩权重值的总和不等于1
                    System.out.println(b[0]+" : weight value error");
                else if(allcourse.get(b[0])!=null)//重复课程信息
                    continue;
                else//正常输入必修课
                {
                    float[] c=new float[2];
                    for(int i=0;i<2;i++)
                        c[i]=Float.parseFloat(b[i+2]);
                    Course course=new RequiredCourse(b[0],c);
                    allcourse.put(b[0],course);
                }
            }
            else if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )([4-9])(( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])))*"))//输入实验课
            {
                float d=0;
                float[] c=new float[b.length-3];
                for(int i=0;i<(b.length-3);i++)
                {
                    c[i]=Float.parseFloat(b[i+3]);
                    d+=c[i];
                }
                if(!b[1].equals("实验"))//输入的课程性质和课程的考核方式不匹配
                    System.out.println(b[0]+" : course type & access mode mismatch");
                else if(Integer.parseInt(b[2])!=(b.length-3))//分项成绩数量值和分项成绩权重的个数不匹配
                    System.out.println(b[0]+" : number of scores does not match");
                else if(d>1.01||d<0.99)//分项成绩权重值的总和不等于1
                    System.out.println(b[0]+" : weight value error");
                else if(allcourse.get(b[0])!=null)//重复课程信息
                    continue;
                else//正常输入实验课
                {
                    Course course=new Experimentallesson(b[0],c);
                    allcourse.put(b[0],course);
                }    
            }
            //输入成绩信息
            else if(a.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})(( )(\\d{1,2}|(100)))*"))
            {
                if(allcourse.get(b[2])==null)//课程不存在
                {
                    System.out.println(b[2]+" does not exist");
                    if(allstu.get(b[0])==null)//学生不存在
                    {
                        Student student=new Student(b[1],b[0]);
                        allstu.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)//班级不存在
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6), cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                }
                else if((allcourse.get(b[2]).assess().equals("考试")&&b.length!=5)||(allcourse.get(b[2]).assess().equals("考察")&&b.length!=3)||(allcourse.get(b[2]).assess().equals("实验")&&b.length!=(allcourse.get(b[2]).weight().length+3)))//输入的成绩数量和课程的考核方式不匹配
                {
                    System.out.println(b[0]+" "+b[1]+" : access mode mismatch");
                    if(allstu.get(b[0])==null)//学生不存在
                    {
                        Student student=new Student(b[1],b[0]);
                        allstu.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)//班级不存在
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6), cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                }
                else if(judge(allstu.get(b[0]),allcourse.get(b[2]),selection))//重复输入学生信息
                    continue;
                else//输入成绩信息
                {
                    if(allstu.get(b[0])==null)//学生不存在
                    {
                        Student student=new Student(b[1],b[0]);
                        allstu.put(b[0],student);
                        if(allclass.get(b[0].substring(0,6))==null)//班级不存在
                        {
                            Class cla=new Class();
                            cla.addnum(b[0].substring(0,6));
                            allclass.put(b[0].substring(0,6), cla);
                        }
                        allclass.get(b[0].substring(0,6)).addstu(student);
                    }
                    ArrayList<Eachscore> s=new ArrayList<Eachscore>();
                    for(int i=3;i<b.length;i++)
                    {
                        Eachscore e=new Eachscore();
                        e.add(Integer.parseInt(b[i]),allcourse.get(b[2]).weight()[i-3]);
                        s.add(e);
                    }
                    Achievement achievement=new Achievement();
                    achievement.add(s);
                    Control control=new Control();
                    control.addmessage(allstu.get(b[0]),allcourse.get(b[2]),achievement);
                    selection.add(control);
                }
            }
            else//格式错误
                System.out.println("wrong format");
        }
        List<Student> mapValues = new ArrayList<>(allstu.values()); 
        Collections.sort(mapValues);
        for(Student i:mapValues)
        {
            int s=0;
            int n=0;
            for(Control j:selection)
                if(i==j.student())
                {
                    s+=j.gettotalscore();
                    n++;
                }
            if(n==0)
                System.out.println(i.number()+" "+i.name()+" did not take any exams");
            else
            {
                s/=n;
                System.out.println(i.number()+" "+i.name()+" "+s);
            }
        }
        List<Course> courseValues = new ArrayList<>(allcourse.values()); 
        Collections.sort(courseValues,new SortName());
        for(Course i:courseValues)
        {
            int m=0;//计算成绩
            int n=0;//计算成绩份数
            for(Control j:selection)
                if(j.course()==i)
                {
                    m+=j.gettotalscore();
                    n++;
                }
            if(n==0)
                System.out.println(i.name()+" has no grades yet");
            else
            {
                m/=n;
                System.out.println(i.name()+" "+m);
            }
        }
        List<Class> classValues = new ArrayList<>(allclass.values()); 
        Collections.sort(classValues);
        for(Class i:classValues)
        {
            if(!i.clascr(selection))//该班级没有成绩
                System.out.println(i.num()+" has no grades yet");
            else
                System.out.println(i.num()+" "+i.gettotalscore(selection));
        }
    }
    public static boolean judge(Student s,Course c,ArrayList<Control> o)
    {
        for(Control i:o)
            if(i.student()==s&&i.course()==c)
                return true;
        return false;
    }
}
//每门课程
abstract class Course
{
    private float[] weight;//权重
    private String name;//课程名称
    private String assess;//考核方式
    void name(String name)
    {
        this.name=name;
    }
    void addassess(String b)
    {
        assess=b;
    }
    void addweight(float[] w)
    {
        this.weight=w;
    }
    String name()
    {
        return name;
    }
    String assess()
    {
        return assess;
    }
    float[] weight()
    {
        return this.weight;
    }
}
//必修课
class RequiredCourse extends Course
{
    RequiredCourse(String name,float[] w)
    {
        name(name);
        addassess("考试");
        addweight(w);
    }

}
//选修课
class OptionalCourse extends Course
{
    OptionalCourse(String name,float[] w)//考试课输入
    {
        name(name);
        addassess("考试");
        addweight(w);
    }
    OptionalCourse(String name)//考察课输入
    {
        name(name);
        addassess("考察");
        float[] w=new float[1];
        w[0]=1;
        addweight(w);
    }
}
//实验课
class Experimentallesson extends Course
{
    Experimentallesson(String name,float[] w)
    {
        name(name);
        addassess("实验");
        addweight(w);
    }
}
//学生
class Student implements Comparable<Student>
{
    private String name;//名字
    private String number;//学号
    Student(String name,String number)
    {
        this.name=name;
        this.number=number;
    }
    String name()
    {
        return name;
    }
    String number()
    {
        return number;
    }
    @Override
    public    int compareTo(Student o)
    {
        return this.number.compareTo(o.number());
    }
}
//选课中心
class Control
{
    private Student student;//学生信息
    private Course course;//课程信息
    private Achievement score;//成绩信息
    int gettotalscore()//计算该成绩
    {
        return score.gettotalscore();
    }
    Student student()
    {
        return this.student;
    }
    Course course()
    {
        return this.course;
    }
    Achievement score()
    {
        return score;
    }
    void addmessage(Student s,Course c,Achievement a)
    {
        this.student=s;
        this.course=c;
        this.score=a;
    }
}
//课程成绩类
class Achievement
{
    private ArrayList<Eachscore> allscore=new ArrayList<Eachscore>();
    int gettotalscore()
    {
        float n=0;
        for(Eachscore i:allscore)
            n+=i.score()*i.weight();
        return (int)n;
    }
    void add(ArrayList<Eachscore> e)
    {
        this.allscore=e;
    }
}
//分项成绩类
class Eachscore
{
    private int score;//成绩分值
    private float weight;//权重
    int score()
    {
        return score;
    }
    float weight()
    {
        return weight;
    }
    void add(int score,float weight)
    {
        this.score=score;
        this.weight=weight;
    }
}
//班级
class Class implements Comparable<Class>
{
    private String num;//班级序号
    private HashSet<Student> students=new HashSet<Student>();//学生
    void addnum(String num)
    {
        this.num=num;
    }
    String num()
    {
        return num;
    }
    void addstu(Student student)
    {
        students.add(student);
    }
    boolean clascr(ArrayList<Control> o)//判断该班是否有成绩
    {
        for(Student a:this.students)
            for(Control b:o)
                if(b.student()==a)
                    return true;
        return false;
    }
    int gettotalscore(ArrayList<Control> o)
    {
        int s=0;
        int n=0;
        int m=0;
        int p=0;
        for(Student a:this.students)
        {
            m=0;
            n=0;
            for(Control b:o)
                if(b.student()==a)
                {
                    n+=b.gettotalscore();
                    m++;
                }
            if(m!=0)
            {
                n/=m;
                p++;
            }
            s+=n;
        }
        return s/p;
    }
    @Override
    public int compareTo(Class o)
    {
        return this.num.compareTo(o.num());
    }
}
class SortName implements Comparator<Course> 
{
     @Override
      public int compare(Course o,Course o1) 
     {
        Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
        return compare.compare(o.name(),o1.name());
      }
}

 

 

本道题目从要求上就有大改。权值由固定变成了用户输入,同时将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。

实不相瞒,我一开始看晕了。

其实本道题主要还是要在更改上面类的同时,在课程中增加权值的属性。还有,输入判断条件要大改。所以其实我也不是很明白是不是因为我考虑不全面,在输入判定就错了才导致几个测试点一直没过……

 

踩坑心得:

课程成绩统计程序-1

1.最大的问题就是输入判定问题,我一开始用的是沿用菜单题目的想法,用if-else来从左往右输入判定情况,但是知道做课程成绩统计程序2才意识到,格式错误的判定情况是最优先级,也就是说无论如何都要先判定格式是否错误。那么原先的判定规则我全部都要大改了。后来经班长提点才明白可以用正则表达式来写,才真正意识到这个的用处有多么的大。(之前都只用来判定是不是数字或者整数……是我大材小用了……)

等等,我之前餐馆题目一直没有满分不会也是因为这个吧。

2.课程名称包含中文字符,没办法和英文字符一起按名字来排序。所以这个我去网上找了下方法,这么写就解决了。

 

 3.这其实主要是我眼瞎的问题:我把班级按班级号排序看成了按班级平均分排序,所以我说为什么做起来那么困难(因为按平均分排序我要重新写算分方法……)直到我开始测测试点才知道我是多么的眼瞎……

 

课程成绩统计程序-2

  1. 如上所述的输入判定问题,用正则表达式后方便了许多。
  2. 关于班级成绩计算。我之前问过某不愿透露姓名的班长,班级成绩的输入要不要算上没有成绩的人,他十分确定地告诉我要算。然后我提交后就错一个测试点。没办法了我就试下不算呗,结果过了……然后这个憨憨告诉我他记错了……

 

课程成绩统计程序-3

1.这里绝对是题目的问题……题目描述和样例输入不符。在一开始,题目的描述是:

 

然后我这么输入后,提交上去测试点除了那几个样例全错。我一想不对劲啊,拿着上次的检查发现只需要输出课程名称+英文空格+does not exist”就够了。

……等一下,我发现我第一题也是这个输出(第二题输出被带着改回来了),不会吧……我的第一题……

2.权值属性的字符类型。我一开始比较憨,脑子一抽就写了int上去,后面输出才感觉不对劲……然后改成了double类型,样例成功过了但是其他测试点是没过。然后某看着我受苦的班长才提醒我这道题一定要用float,并且判定权值之和为1不能用“==1”,而是得用“>0.99 && <1.01”,这题目……哈哈……

3.至于测试点14我是真找不到错哪里了……并且我还多错了一个测试点16……为什么……

 

主要困难及改进建议:

  1. 眼瞎。眼瞎这问题还真不好治……得多读几遍题目了。
  2. 对题目的分析理解还不够深刻。例如我一直没有意识到格式错误是最优先判定级……
  3. 对语法等方法运用不熟练。Matches完全没想到能这么用就算了,还不会用……再次感谢愿意不厌其烦教会我这个憨憨的班长。非常感谢。
  4. 坑,很坑。不过也有我题目做的不够多的原因吧。我是完全没想到会有精度这种问题。仔细想想开学的java题目有一道就是和精度相关,但是我完全没把它放在心上。太坑了……估计以后也会出很多这种题目,我要多注意注意。
  5. 猜测试点……真的很麻烦……而且很多测试点是从一开始程序结构上就出了问题,如果顺着原结构想很难想出到底问题在哪里。在没有人指点的情况下真的很难靠自己拿到满分。当然那几个一开始就满分了的佬不算,他们是真的天才,而我是真的纯菜……

6.多预习,多复习,多花时间在了解语法上面,争取不要在用的时候不会,甚至完全不知道。

 

总结:

  1. 教师与课程方面:老师这次愿意讲解一下这道题真是太好了……节约了我大量的时间以及指点了正确的方向。要我自己写肯定是差的离谱……万分感谢。但是讲javafx的时候讲的有点快qwq我还在琢磨怎么装软件他就开始讲起来了,没软件干巴巴地听也很难记住,导致后面的课都基本跟不上,只能自学,而且没有题目练习,实在是有点容易忘了……
  2. 作业方面:愿意出点maplist题目是极好的……我太需要这种相关练习来帮助我记忆这些方法用法了。
  3. 实验方面:有点难但确实很有用。但是靠自己也不知道成绩,不知道自己做的如何,也不知道有些问题该怎么解决……有点孤立无援的感觉。
  4. 课上方面:希望能边讲边让我们尝试怎么做。毕竟这东西还挺难记住的……
posted @ 2023-06-19 19:47  欣月凌儿  阅读(44)  评论(0)    收藏  举报