面向对象程序编程PTA题目集4、5以及期中考试的总结性Blog

1.对之前发布的PTA题目集4、5以及期中考试的总结性Blog

(1)前言:总结之前所涉及到的知识点、题量、难度等情况

期中考试作业:

知识点:主要就是考了对类的使用,和不同类间的相互配合使用,还有对于一个程序的不断循环使用(相比之前更加灵活,可以自定义输入的个数),正则表达(可用可不用,这里可以用正则表达式来区别对正方形和圆型的输入,但是没必要,没有什么合法性判断,直接用If就可以平替)

题量与难度:这次期中考试的题量就三题,算是较少了,而且难度相对于之前写的菜单作业真的是一个天上一个地下,相比之下,真的是非常简单了,而且一下子就可以写完,熟练一点,估计也就30分钟作业的题量

PTA第四次题目集作业:

知识点:也就是正则表达式了,主要就算对正则表达式的更改,但是正则表达式的匹配是真的写起来难受,所以思路是有,但是还是得多次调试正则表达式才能达到目的。除此之外,还要改一些其他的阿部分。

难度与题量:更麻烦。因为多了个考点,对代码运行时间的把控,对代码占内存的把控。难了很多,花了很多时间,两天时间一天到晚都在写,最后只拿了个64分。最难点的地方就在对代码运行时间和内存的把控(这个坑,我放到踩坑心得细讲),我前几次提交基本所有测试点都超时了,写是写对了,但是超时了,一分也没有,难就难在不仅要更新,还需要把此前的代码每个地方都要换成运行更快的代码,比如加强循环改成迭代器,少用循环等等

PTA第五次题目集作业:

知识点:此次PTA题目仅只有这一个题目,在菜单三的基础上新增了口味选项,特色菜的相关选项,主要考的内容就是对类的使用(类似现实,对有关联的各个数据合并在一起,便于一起使用),运用正则表达式(比较苦难使用,要记住那些符号对应那些匹配,而且匹配的机制非常严格,常常想要达到预期的匹配效果需要经过很多次的调试,常用于对输入数据的合法性判断,难用,但是也非常实用),数组列表,对数组列表的接口类Comparable(在对数组列表中的内容的排序非常方便,而且内部的CompareTo可以自行定义升序降序或者其他的排序方法,常用好用),还有对字符串的分割(sqilt),对字符串的部分截取(subString),对输入的数据 的解析(根据输入的一行数据,来判断这行数据大体要干嘛,然后调用特定的方法来对这串字符串进行解析),比较字符串(equals,这个与==的比较方法就完全不同,==可以用来比较基本类型的值,也可以用来比较引用类型的地址值;equals则不能用来比较基本类型的值,可以比较引用类型的地址值,相对的可以在需要的类中重写equals方法,使得可以比较对象中的特定内容,例如String类就可以比较不同类中的字符串内容了),控制输出的格式(String.format("%d",12345);和与c语言格式化输出大同小异的system.out.printf(""),这个主要是用于控制一些小数的精确程度),对实际问题的合法性判断(在PTA里这个要先判断,不行要立即return,不能用if-else放到后边else里判断,不然测试点是通过不了的,其他的放到踩坑心得里说)

难度与题量:对代码运行时间的把控,对代码占内存的把控。难度还是挺大的,相对于题目四。题量也就只有一题,但是比较难。

(2)设计与分析:

第四次PTA题目:

7-1 菜单计价程序-4:

设计与解释:大体的思路

分析:根据需求,与菜单三的相似但不完全相同,除了Main类外还设计4个类:Dish(菜)类:保存菜信息,Menu(菜单)类:用于保存多个菜谱信息和查找有无此菜,Record(点菜记录)类:记录一次点菜中的菜信息和份额和个数和序号,Order(点单)类;保存此客户的所有订单信息并算出总价。Dish类有:name 姓名,unit_price单价,getPrice(int portion)计算此份额的价格。Menu类有:dishes多个菜品, searchDish(String dishName)查找菜单中有无此菜,addDish(String dishName, int unit_price)添加菜到菜单。Record类有:dish记录这个菜,portion记录这个菜的份额,ordernum记录订单序号,getPrice()计算此菜的价格。Order类有:records 保存用户的所有点菜记录,addARecord(String dishName, int portion)添加订单,getTotalPrice()计算总价格,find(int ordernum) 根据序号查找一条记录,delet(int ordernum) 根据序号删除一条记录,在以上框架写完后,再补充进去此次菜单四需要的更多异常数据的判断

 

 

分析与心得:相比于菜单三,这次题目就心添加了几个异常处理,主要就算对正则表达式的更改,但是正则表达式的匹配是真的写起来难受,所以思路是有,但是还是得多次调试正则表达式才能达到目的。除此之外,还要改一些其他的阿部分。

 

第五次PTA题目集:

设计与解释:大体的思路

根据需求,本题和菜单计价程序-4同属菜单计价程序-3的两个不同迭代分支。菜单三的基础上新增了口味选项,特色菜的相关选项

 

 分析:与菜单四的相似但不完全相同,除了Main类外还设计4个类:Dish(菜)类:保存菜信息,Menu(菜单)类:用于保存多个菜谱信息和查找有无此菜,Record(点菜记录)类:记录一次点菜中的菜信息和份额和个数和序号,Order(点单)类;保存此客户的所有订单信息并算出总价。Dish类有:name 姓名,unit_price单价,getPrice(int portion)计算此份额的价格。Menu类有:dishes多个菜品, searchDish(String dishName)查找菜单中有无此菜,addDish(String dishName, int unit_price)添加菜到菜单。Record类有:dish记录这个菜,portion记录这个菜的份额,ordernum记录订单序号,getPrice()计算此菜的价格。Order类有:records 保存用户的所有点菜记录,addARecord(String dishName, int portion)添加订单,getTotalPrice()计算总价格,find(int ordernum) 根据序号查找一条记录,delet(int ordernum) 根据序号删除一条记录,在以上框架写完后,再补充进去在菜单三的基础上新增了口味选项,特色菜的相关选项

心得:相比于菜单三,这次题目就心添加了新增了口味选项,特色菜的相关选项

期中考试题目集:

此次题目集较为简单,就不过多赘述,大体的说一下就行

设计与解释:大体的思路

题目一:圆形的设计

设计与解释:大概就是创建一个关于圆形的类就行,在当中加入圆形的半径和面积的数据就行,

然后再加上一个计算面积的方法,getArea

 题目二:对正方形的设计  

设计与解释: 大概就是创建个父类,然后加上图像特有的坐标作为数据,根据坐标做一个Getarea方法就行,

题目三:7-3 测验3-继承与多态

设计与解释:大体的思路对圆形,正方形,的面积计算的多次循环

 

分析:多态的好处在于可以提高代码的灵活性和扩展性。通过使用父类引用,我们可以写出更通用的,当需要增加新的子类时,无需修改已有的代码,只需要向现有的继承体系中添加新的子类即可。继承(Inheritance)是指一个类(子类)可以从另一个类(父类)继承其属性和方法。子类可以通过继承来复用父类的代码,并且可以在其中添加新的功能或修改现有功能。在Java中,使用关键字"extends"来表示继承关系

心得:继承和多态是Java程序设计的重要特性,它们能够有效地组织和管理复杂的代码结构,并使代码具有更高的可重用性和可扩展性

分析与心得:没啥分析,就算个While的循环,然后按情况分别调用正方形和圆形

题目四:7-4 测验4-抽象类与接口

 设计与解释:实现Comparable接口,然后重写比较的方法,再代码中就可以使用Collections.sort的方法快速排序了

 

(3)采坑心得:

1.对于实际问题的合法性判断:这个是我在PTA遇到的第一个百思不得其解的坑,也是偶然中发现的,先单纯说在作业上:对于有关于合法性判断的测试点,必须得将合法性判断置于代码的最上边位置,不合格则立即return退出程序或者跳过一段程序。如果将合法判断置于后面,比如if-else放在else后面,即使最后运行结果一样,但是这个测试点就是不通过。总结就是在运行某段代码前,先判断是否合法,合法则执行这段代码,不合法则不执行这段代码直接跳过。然后在代码上的理解:我认为这样的好处是可以使代码运行的更快,因为当不合格时便不会读取其他多余的代码。

2.对代码运行时间和内存的把控:在PTA里面写这种系列更新题目的后期最大难题,你会是会写,但是你不会要会写,你还要智写,不能随便叠代码来完成,得用一些更高级的代码来替代那些简单代码以来减少运行时间。不仅是这次成绩管理系统,包括上次的菜单系统,越更新到后面,就越容易测试点超时。不能总是用循环来干事,得多换成迭代器,多用继承和组合加强代码复用

3.排序:先对长度排序,再在同长里面调用compareToIgnoreCase()方法。因为compareToIgnoreCase()函数在队不同长度的单词进行排序时会出现排不准的情况。还有也不能用compareTo()方法,这个方法会考虑单词的大小写,让排序不准确,题目准确写了忽略大小写,故用compareToIgnoreCase()才是最优解,可以忽略单词的大小写进行比较。

4.快读快写:用快读快写时,一定要记得在方法标签后面+throws IOException,不然是运行不了的。而且在创建对象时的代码是很长的,不好记而且容易打错,所以建议把创建对象的代码复制到一个常用代码文档里,要用的时候就不用再打一遍了。

 

(4)改进建议:

1.写代码的时的细节问题和全局思想问题:写代码时总是会遗漏;{}等小细节问题,导致很多时候一运行报错了,到处找错误找不到,费了一番功夫才发现原来是某个小细节问题,同时也归咎于没有养成在报错的时候仔细看Idea给的报错可能,因为是英文所以老是懒得看。全局思想是常常遇到题目就开始写,并没有构思一下

 2.数据的重复与排序:有关重复数据和排序的,当时还不知道哈希表,就只能一股脑的用循环嵌套去解决,十分的麻烦,而且经常会测试点超时。比如的数据就可以直接全部add入哈希表中,然后再将删除重复数据的哈希表内个数与原个数比较就行。同理,最后遍历输出就行,可以极大的简化代码。

 

(5)总结:

知识上:学到了队类的使用,封装,String类,日期类,包装类中的一些方法,哈希表,数组列表,equals与==的不同等

思路上:学到了基本的解题步骤,需求分析,不断分解成子问题,由下向上逐步解决,阶段性调试测试,先构建出基本框架,写出基本功能,检查Bug,最后再来对整体的优化(比如让界面更简洁啊,简化一些代码啊等等)

当然还有很多没有弄明白的方面,还在学习正则表达式和javaFX动画驱动的内容

 

 

 

 (6)菜单四的代码附录

import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Collections;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Analyse analyse = new Analyse();
        String string1 = in.nextLine();
        while (!string1.equals("end"))
        {
            analyse.stringAnalyse(string1);
            string1= in.nextLine();
        }
        analyse.showError();
        analyse.showStu();
        analyse.showCourse();
        analyse.showCla();
    }
}
class Student implements Comparable<Student>{
    String name;
    String num;
    int average;
    ArrayList<Select> selects = new ArrayList<Select>();

    Student(String name,String num)
    {
        this.name = name;
        this.num=num;
    }
    public Select addSelect(Select select)
    {
        selects.add(select);
        return select;
    }
    public void sumAverage()
    {
        int total = 0;
        for(Select temp:selects)
        {
            total = total+temp.score.totalScore;
        }
        if(selects.size()==0)
            return;
        this.average=total/(selects.size());
    }

    @Override
    public int compareTo(Student o) {
        return this.num.compareTo(o.num);
    }
}
class Cla implements Comparable<Cla>{
     String num;
     ArrayList<Student> students = new ArrayList<Student>();
     int classAverage;

    Cla(String num)
    {
        this.num=num;
    }
    public Student addStudent(Student student)
    {
        students.add(student);
        return student;
    }
    public void sumAverage()
    {
        int total = 0;
        for(Student temp:students)
        {
            total = total+temp.average;
        }
        if(students.size()==0)
            return;
        this.classAverage=total/(students.size());    }

    @Override
    public int compareTo(Cla o) {
        return this.num.compareTo(o.num);
    }
}
class Course implements Comparable<Course>{
     String name;
     String type;
     String method;
    int courseAverage;
    int finalaverage;
    int usualaverage;
    ArrayList<Select> selects = new ArrayList<Select>();

    Course(String name,String type,String method)
    {
        this.name=name;
        this.type=type;
        this.method=method;
    }
    public Select addSelect(Select select)
    {
        selects.add(select);
        return select;
    }
    public void sumAverage()
    {
        int total = 0;
        for(Select temp:selects)
        {
            total = total+temp.score.totalScore;
        }
        if(selects.size()==0)
            return;
        this.courseAverage=total/(selects.size());
    }
    public void finalaverage()
    {
        int total = 0;
        for(Select temp:selects)
        {
            total = total+temp.score.finalScore;
        }
        if(selects.size()==0)
            return;
        this.finalaverage=total/(selects.size());
    }
    public void usualaverage()
    {
        int total = 0;
        for(Select temp:selects)
        {
            total = total+temp.score.usualScore;
        }
        if(selects.size()==0)
            return;
        this.usualaverage=total/(selects.size());
    }

    public int compareTo(Course o) {
        Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
        return compare.compare(name,o.name);
    }

}
class Select {
    Course course;
    Student student;
    Score score;
    Select(Course course,Student student,Score score)
    {
        this.course=course;
        this.student=student;
        this.score=score;
    }
}
abstract class Score {
    int totalScore;
    int finalScore;
    int usualScore;
}
class ExamScore extends Score{

    ExamScore(int usualScore,int finalScore)
    {
        this.usualScore=usualScore;
        this.finalScore=finalScore;
        this.totalScore=(int)(finalScore*0.7f+usualScore*0.3f);
    }

}
class ExploreScore extends Score{
    ExploreScore(int finalScore)
    {
        this.finalScore=finalScore;
        this.totalScore=finalScore;
    }

}
class Analyse {
    ArrayList<Student> students = new ArrayList<>();
    ArrayList<Course> courses= new ArrayList<>();
    ArrayList<Cla> clas = new ArrayList<>();
    ArrayList<Select> selects = new ArrayList<>();
    ArrayList<String> errors = new ArrayList<>();

    public void stringAnalyse(String string)
    {
        String[] item = string.split(" ");
        if(item.length==3)
        {
            String name = item[0];
            String type = item[1];
            String method= item[2];//重复课程的输入混乱,排序重复,未改-对应5异常

            Course againCourse = findCourse(name);
            if(againCourse!=null)
            {
                return;
            }

            if(type.equals("必修"))
            {
                if(method.equals("考察"))
                {
                    String error = name+" "+": course type & access mode mismatch";
                    errors.add(error);
                    //System.out.println(name+": course type & access mode mismatch");
                    return;
                }
                Course course = new Course(name,type,method);
                courses.add(course);
            }
            if(type.equals("选修"))
            {
                Course course = new Course(name,type,method);
                courses.add(course);
            }
        }



        if(item.length==4||item.length==5)
        {
            if(InputMatching.matchingInput(string)==0)//对应异常三,似乎还要一些测试点未达标
            {
                String error = "wrong format";
                errors.add(error);
                return;
            }
            String classNum = item[0].substring(0,6);
            String id = item[0];
            String stuName = item[1];


            Cla cla1= findCla(classNum);
            if(cla1==null)
            {
                cla1 = new Cla(classNum);
                clas.add(cla1);
            }


            Student student1 = findStudent(stuName,id);
            if(student1==null)
            {
                student1= new Student(stuName,id);
                students.add(student1);
                cla1.addStudent(student1);
            }
            else                  //重复学生成绩信息导致同一科目双倍选课,双倍课,双倍人,未改——对应5异常
            {
                for(Select againselect:student1.selects)
                {
                    if(item[2].equals(againselect.course.name))
                    {
                        return;
                    }
                }
            }

            //int errorSelect = 0;//两处错误报告的优先级,未改;重要-对应2异常
            String courseName = item[2];
            Course stuCourse = findCourse(courseName);
            if(stuCourse==null)
            {
                String error = courseName+" "+"does not exist";
                errors.add(error);
                //errorSelect = 1;
                return;//次两处错误已经不可能同时出现,但是不排除题目意思是说,即使是不同科目出现两个错误也要选择-待验证-未改
            }

            if(stuCourse.method.equals("考试"))
            {

                if(item.length==4)
                {
                    String error = id+" "+stuName+" "+": access mode mismatch";
                    errors.add(error);
                    return;
                }
                int usualScore = Integer.parseInt(item[3]);
                int finalScore = Integer.parseInt(item[4]);
                Score score = new ExamScore(usualScore,finalScore);
                Select select1 = new Select(stuCourse,student1,score);
                selects.add(select1);
                student1.addSelect(select1);
                stuCourse.addSelect(select1);
                student1.sumAverage();
                stuCourse.sumAverage();
                stuCourse.finalaverage();
                stuCourse.usualaverage();
                cla1.sumAverage();
            }
            if(stuCourse.method.equals("考察"))
            {
                if(item.length==5)
                {
                    String error = id+" "+stuName+" "+": access mode mismatch";
                    errors.add(error);
                    //System.out.println(id+" "+stuName+" "+": access mode mismatch");
                    return;
                }
                int finalScore = Integer.parseInt(item[3]);
                Score score = new ExploreScore(finalScore);
                Select select1 = new Select(stuCourse,student1,score);
                selects.add(select1);
                student1.addSelect(select1);
                stuCourse.addSelect(select1);
                student1.sumAverage();
                stuCourse.sumAverage();
                stuCourse.finalaverage();
                cla1.sumAverage();
            }
        }
    }
    public void showError()
    {
        for (String err:errors)
        {
            System.out.println(err);
        }
    }
    public void showStu()
    {
        Collections.sort(students);
        for(Student stu:students)
        {
            if(stu.selects.size()==0)
            {
                System.out.println(stu.num+" "+stu.name+" "+"did not take any exams");
            }
            else {
                System.out.println(stu.num + " " + stu.name + " " + stu.average);
            }
        }
    }
    public void showCourse()
    {
        Collections.sort(courses);
        for(Course cou:courses)
        {
            if(cou.selects.size()==0)
            {
                System.out.println(cou.name+" "+"has no grades yet");
            }
            else {
                if (cou.method.equals("考试")) {
                    System.out.println(cou.name + " " + cou.usualaverage + " " + cou.finalaverage + " " + cou.courseAverage);
                }
                if (cou.method.equals("考察")) {
                    System.out.println(cou.name + " " + cou.finalaverage + " " + cou.courseAverage);
                }
            }
        }
    }
    public void showCla()
    {
        Collections.sort(clas);
        for(Cla cla:clas)
        {
            if(cla.classAverage==0)
            {
                System.out.println(cla.num+" "+"has no grades yet");
            }
            else {
                System.out.println(cla.num + " " + cla.classAverage);
            }
        }
    }
    public boolean haveCla(String classNum)
    {
        if(clas.size()==0)
        {
            return false;
        }
        for(Cla temp:clas)
        {
            if(temp.num.equals(classNum))
            {
                return true;
            }
        }
        return false;
    }
    public Course findCourse(String courseName)
    {
        if(courses.size()==0)
        {
            return null;
        }
        for(Course temp:courses)
        {
            if(temp.name.equals(courseName))
            {
                return temp;
            }
        }
        return null;
    }
    public Student findStudent(String stuName,String stuNum)
    {
        if(students.size()==0)
        {
            return null;
        }
        for(Student temp:students)
        {
            if(temp.name.equals(stuName)&&temp.num.equals(stuNum))
            {
                return temp;
            }
        }
        return null;
    }
    public Cla findCla(String claNum)
    {
        if(clas.size()==0)
        {
            return null;
        }
        for(Cla temp:clas)
        {
            if(temp.num.equals(claNum))
            {
                return temp;
            }
        }
        return null;
    }
}


class InputMatching {
    static String stuNumMatching = "[0-9]{8}";//8个0-9的数字
    static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符
    static String scoreMatching = "([1-9]?[0-9]|100)";
    static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符
    static String courseTypeMatching = "(选修|必修)";
    static String checkcourseTypeMatching = "(考试|考察)";
    //cousrInput用于定义课程信息模式(正则表达式)
    static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
    //scoreInput用于定义成绩信息模式(正则表达式)
    static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
            scoreMatching;
    static String secondScoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
            scoreMatching + " " + scoreMatching;
    public static int matchingInput(String s) {
        if (matchingCourse(s)) {
            return 1;
        }
        if (matchingScore(s)||matchSecondScore(s)) {
            return 2;
        }
        return 0;
    }

    private static boolean matchingCourse(String s) {
        return s.matches(courseInput);
    }

    private static boolean matchingScore(String s) {
        //System.out.println(match);
        return s.matches(scoreInput);
    }
    private static boolean matchSecondScore(String s)
    {
        return s.matches(secondScoreInput);
    }
}

  

 

posted @ 2023-06-29 15:47  magically  阅读(110)  评论(0)    收藏  举报