目录

前言

这学期才接触Java,以前只学过C语言。所以Java的面向对象对我来说非常神奇,也非常难。经过这三次的大作业可以确定Java真的很高级。Java的通用性很好,可以跨平台直接移植,只要安装Java虚拟机就可以了。开发的效率高。生成的机器码效率没有汇编和C的高。在嵌入式系统中,C语言是使用最广泛的语言。

Java的语法我现在才开始适应。下面就简单总结一下这三次题目集的知识点和难度情况吧!

第一次作业:作业的知识点是学习C语言的时候学过的内容主要就是一些简单的计算、求和、字符串的处理等。另外涉及到了Java的基础语法,但是还没有涉及到面向对象的设计。题量相较于第二、三次作业较大,但是难度不大,比较好完成。最最糟心的是:总会有一两个题的一两个测试点过不去.......说明我的程序还有漏洞,要加以改进。

第二次作业:题目只有四个,但是对当时的我来说难度比上次的难度大了不止一个档次。第一、二题开始使用面向对象的一些思想(刚开始从C语言的对过程转向Java的面向对象思想可想而知是多么痛苦)。第三题是判断合法日期、计算两个日期之间相差了多少天数、月数和年数,这里主要用到了Java里面的Calendar、LocalDate和Date类(Java真智能)。第四题小明走格子,这个题目的计算方法有很多,但是最难的是如何做到不运行超时,这就要用到Java里面的StreamTokenizer读取输入方式,而不是Scanner。前者是在数据量输入特别大时使用,后者是日常少量数据情况下使用。前者的读取数据的速度比后者更快。

第三次作业:第一题还是菜单系列的题目,增加了桌号和带点的功能(好多测试点没过,圈复杂度太大,耦合度太高,太痛了)。后面第二、三、四题是对重复数据和字符串的处理,这里要用到Java里面的:

①HashSet集合(哈希集):元素无序,不可重复;

②List集合:元素有序,可重复;

③Arraylist类:一个可以动态修改的数组,没有固定大小的限制;

④LinkedHashSet:HashSet的有序版本;

⑤Collections.sort():是对List对象进行排序的工具方法。

第五题运用到了Java里面的封装性。第六题运用到了类型转换。第七题是日期判断,主要用到LocalDate类中of()、ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。

 

设计与分析:

第一次作业:

第一题:7-1 身体质量指数(BMI)测算

类图:

耦合度、圈复杂度:

 

Statments(有效语句):21行

Percent Branch Statements(分支语句比例):28.6

Maximum Complexity(该类中最复杂函数的复杂度):12

由Kiviat Graph图可知:最大复杂度和平均复杂度超过绿色范围,复杂度过大,代码不合格,需要改进。

if(high>2.72||weight>727||high<=0||weight<=0)
            System.out.println("input out of range");
        else
        {
            if(bmi<18.5)
                System.out.println("thin");
            if(bmi>=18.5&&bmi<24)
                System.out.println("fit");
            if(bmi>=24&&bmi<28)
                System.out.println("overweight");
            if(bmi>=28)
                System.out.println("fat");
        }

该代码用了五个if,复杂度太大。

优化:

if(bmi<18.5)
{
    System.out.println("thin");
    return;
}
else if(bmi<24)
{
    System.out.println("fit");
    return;
}
else if(bmi<28)
{
    System.out.println("overweight");
    return;
}
else if(bmi>=28)
{
    System.out.println("fat");
    return;
}
System.out.println("input out of range");

 

第二题:7-2 长度质量计量单位换算

类图:

 

 耦合度、圈复杂度:

 

Statments(有效语句):12行

Percent Branch Statements(分支语句比例):0.0

Maximum Complexity(该类中最复杂函数的复杂度):1

由Kiviat Graph图可知:该代码的平均复杂度、最大复杂度、最大函数深度都在绿色范围内,表示良好。该代码不需要进行判断,没有分支,只需注意换算的要求,进行类型转换,注意格式即可。

 

第三题:7-3 奇数求和

类图:

 

耦合度、圈复杂度:

 

 

Statments(有效语句):13行

Percent Branch Statements(分支语句比例):15.4

Maximum Complexity(该类中最复杂函数的复杂度):3

由Kiviat Graph图可知:该代码的平均复杂度、最大复杂度、最大函数深度都在绿色范围内,表示良好。唯一缺点是:还是面向过程的思想,应该尝试转换为 面向过程的思想。

for(i=0;i<10;i++)
        {
            a[i]=sc.nextInt();
            if(a[i]%2!=0)
                sum+=a[i];
        }

 

优化:用面向对象的思想:

类的属性:自然数

类的方法:

①判断是否为奇数 Boolean panduan(int a);

②相加求和 int add(int[ ] a);

 

第四题:7-4 房产税费计算2022

类图:

耦合度、圈复杂度:

 

 

Statments(有效语句):23行

Percent Branch Statements(分支语句比例):21.7

Maximum Complexity(该类中最复杂函数的复杂度):7

由Kiviat Graph图可知:该代码的Avg Complexity(平均复杂度)和Avg Stmts/Method(平均一个函数包括的语句数目)超过范围。

int n=sc.nextInt();
        int m=sc.nextInt();
        int m1=sc.nextInt();
        float s=sc.nextFloat();
        double q=0.0;//需初始化
        if(n==1)
        {
            if(s<=90)
                q=m1*10000*0.01;
            else if(s>90&&s<=144)
                q=m1*10000*0.015;
            else if(s>144)
                q=m1*10000*0.03;//注意单位是万元,要乘以10000
        }
        else
            q=m1*10000*0.03;
        double y=m*0.0005*10000;
        double j=3.0*s;
        float c=1.36f*s;//?
        System.out.print(q+" "+y+" "+j+" "+c);

 

 

该代码用了三个else,两个if,一个else 复杂度有点大。

平均一个函数包括的语句数目较多,应将判断部分和计算部分单独做一个方法

 

第六题:7-6 学号识别

类图:

 

耦合度、圈复杂度:

 

Statments(有效语句):27行

Percent Branch Statements(分支语句比例):29.6

Maximum Complexity(该类中最复杂函数的复杂度):9

由Kiviat Graph图可知:该代码的Avg Complexity(平均复杂度)和Avg Stmts/Method(平均一个函数包括的语句数目)超过范围

Scanner sc=new Scanner(System.in);
        String num=sc.nextLine();//输入一串数组
        String nian,yuan,ban,xue;
        //输入一串字符
        /*输入:是什么
        *处理:算法或数据处理过程
        *输出:在什么情况下输出什么
        */
        int i=0;
        while(i<num.length())
            i++;
        if(i!=8)
        {
            System.out.print("Wrong Format");
        }
        else
        {
            nian=num.substring(0,2);
            yuan=num.substring(2,4);
            ban=num.substring(4,6);
            xue=num.substring(6,8);
            if(yuan.equals("01"))
            {
                System.out.print("入学年份:20"+nian+"年\n"+"学院:材料学院\n"+"班级:"+ban+"\n"+"学号:"+xue+"\n");
            }
            else if(yuan.equals("02"))
            {
                System.out.print("入学年份:20"+nian+"年\n"+"学院:机械学院\n"+"班级:"+ban+"\n"+"学号:"+xue+"\n");
            }
            else if(yuan.equals("03"))
            {
                System.out.print("入学年份:20"+nian+"年\n"+"学院:外国语学院\n"+"班级:"+ban+"\n"+"学号:"+xue+"\n");
            }
            else if(yuan.equals("20"))
            {
                System.out.print("入学年份:20"+nian+"年\n"+"学院:软件学院\n"+"班级:"+ban+"\n"+"学号:"+xue+"\n");
            }
            else
                System.out.print("Wrong Format");

 

这题的代码if 、else if用了太多。测试点:正常值测试 还完全没过,代码有漏洞(不知道在哪呜呜呜)。估计是复杂度太大了,代码很容易出错,有Bug。

 

第二次作业:

第一题:7-1 菜单计价程序-1

类图:

 

 

耦合度、圈复杂度:

  

Statments(有效语句):169行

Percent Branch Statements(分支语句比例):21.7

Maximum Complexity(该类中最复杂函数的复杂度):7

由Kiviat Graph图可知:该代码平均复杂度和最复杂函数的复杂度都在绿色范围内,表述良好。

 

简述:

由Kiviat Graph图知:Dish.getPrice()、Main.main()、Menu.searthDush()、Order.addRecord()、Order.getTotalPrice()、Record.getPrice()的复杂度分别是4、2、3、5、2、1。复杂度都不大。各项指标都在绿色范围内。

但是这个题真的搞了太久,搞了两天才搞好,当时真是想死的心都有了。。。

按照老师提供的类、类的属性和方法。这个题目分为:Main类、Dish类(菜品类)、Menu类(菜谱类)、Record类(点菜记录类)、Order类(订单类)。

该题需要先对Dish类中的name、unit_price赋初值。点菜时输入菜名和份额,调用searchDish()方法进行判断是否有该菜,若没有该菜,则输出菜名+does not exist。若有,则调用addRecord()方法添加点菜记录。最后以end结束,并调用Order类里面的getTotalPrice()方法计算出订单的总费用。

这个题目写好久主要是因为刚开始用面向对象的思想,创建了几个类,和类的属性和方法。不知道怎么传参,包括类的传参、this、构造方法怎么用。

当时有一个问题就是在menu的DIsh对象里面赋了初值,但是在Order类里面点菜时调用Order类里面的getTotalPrice()方法、Record类里面的getPrice()方法和Dish里面的getPrice(int portion)方法进行计算价格,发现Record数组里面的Dish对象内的unit_price(单价)总是为0。因为我没有把new的menu对象传到Order里面的getTotalPrice()方法中。当时还不知道怎么改,导致我直接在addRecord(String dishName,int portion)中用if来进行判断record里面的Dish对象的unit_price该是多少。

针对这个问题进行优化:

int getTotalPrice(Order order,Menu menu,int dn[]){//计算订单的总价
           int j=0,sum=0;
           Dish d;
            while(order.records[j]!=null)
            {
                d=menu.searthDish(order.records[j].d.name);
                if(d!=null)
                    order.records[j].d=d;
                if(dn[j]!=1)
                    sum+=order.records[j].getPrice();
                j++;
            }
            return sum;
       }

 

如果没有用if else来判断unit_price该为多少,而是直接传Menu对象,代码的复杂度肯定更低。

 

第二题:7-2 菜单计价程序-2

类图:

 

 

 

耦合度、圈复杂度:

 

 

Statments(有效语句):136行

Percent Branch Statements(分支语句比例):19.1

Maximum Complexity(该类中最复杂函数的复杂度):15

由Kiviat Graph图可知:Average Complexity为4,表示良好。但是Maximum Complexity(该类中最复杂函数的复杂度)为15,超过了范围。

 

简述:

这个系列第二题的类和第一题的一样,还是Main类、Dish类(菜品类)、Menu类(菜谱类)、Record类(点菜记录类)、Order类(订单类)。

但是在点菜的基础上新加了一个添加菜品信息的方法:Dish addDish(String dishName,int unit_price)//添加一道菜品信息,和删除点菜记录的方法delARecordByOrderNum(int orderNum)//根据序号删除一条记录 、findRecordByNum(int orderNum)//根据序号查找一条记录。

在第一题的基础上,需要输入你所添加的菜品信息,然后进行点菜、删除。所以,这里需要在主方法里面判断到底什么时候判断时进行添加菜品信息,还是开始点菜、删除。这个题的最复杂函数为Main,复杂度为15.主要就是因为要判断什么时候开始调用不同的功能。我的判断方法就是通过判断该行字符串的这个字符串是否为“1”。如果为1,那么就开始了点菜,如果end就结束。如果又有一个“1”,那么就代表开始进行删除,如果end就结束。而且当时还没有用split(分割的方法),这样判断肯定有bug。(可能就是因为这个判断的方法导致我有几个测试点没过啊啊啊!!后面的多条订单的测试点都没过)。更好的方法就是使用split()方法将空格分割出去,其他的内容直接加在定义的数组里面,然后判断第几个是否为字符‘1’,‘delete’。

针对这个问题进行优化:

   data=sc.nextLine()       
arr=data.split(" ");

while(true) { if(data.equals("end")) break; if(arr.length==2&&!arr[1].equals("delete"))//如果长度等于二,则添加菜品 { while(arr.length==2&&!arr[1].equals("delete")) { ...... data=sc.nextLine(); if(data.equals("end")) break; // brr=data.split(" "); // if(brr.length==2&&brr[1].equals("delete")) // break; arr=data.split(" "); } } if(data.equals("end")) break; else//如果不等于二,则开始点菜 { ....... data=sc.nextLine(); if(data.equals("end")) break; arr=data.split(" "); } if(arr.length==4&&!arr[0].equals("table"))//如果第一个不是table,则为点菜记录 {
......
} data=sc.nextLine(); if(data.equals("end")) break; // brr=data.split(" "); // if(b) // break; arr=data.split(" "); } } if(data.equals("end")) break; if(arr[1].equals("delete")) { int y=0; while(arr[1].equals("delete")) { ...... } } if(data.equals("end")) break; }

 

除了实现第一题所要的功能,还要再增加删除功能,还要计录所点的每个菜的点菜号、菜名和份数,计算每个菜的价钱并输出。删除的菜也要计算,如果存在所删的对象,则订单总价减去该菜的价钱,如果没有,则输出delete error;。还有一个麻烦的点就是,应该在判断是否存在该菜、是否有该删除对象和计算每个菜的菜价之后就直接输出相应的“菜名+does not exist”、“delete error”和“序号+菜名+费用”。而不是如果存在不存在删除对象就返回0,存在就返回1.这样很玛烦。

 

第三题:7-3 jmu-java-日期类的基本使用

类图:

 

 

耦合度、圈复杂度:

 

 

Statments(有效语句):283行

Percent Branch Statements(分支语句比例):26.9

Maximum Complexity(该类中最复杂函数的复杂度):59(救命!!,Main里面用了太多if else )

由Kiviat Graph图可知:Average Complexity为10,Max Complexity是59,(太高了吧,唉)。除了这两个,Avg Depth(平均函数深度),Avg Stmts/Merhod(平均每个方法中的语句)也都超标了。(我太难了。。。。)

简述:

这个题目的Main复杂度太高了,主要是因为用了太多的if else来判断,这题要判定是否为合法日期、判断该年是否闰年、判定日期是否合法且结束日期是否早于起始日期。再判断是否合法时,还得先判断是否为闰年,因为闰年二月份有29天,平年只有8天。没想到的是,判断日期还要判断输入的格式是否为"YYYY-MM-dd"(这个是属是没注意到。。。)还是要学习如何降低复杂度(均有效且合法,且不是闰年、均有效且合法,第一行包含闰年的测试点没过),每个方法中的语句也太多了,差不多快到五六十行了,因为要用到switch语句判断该月份是30天还是31天。但是应该把这个功能单独拿出来,避免重复写。

这个题我用到了Java里面的Calendar、ParseException、SimpleDateFormat、LocalDate、temporal.ChronoUnit和Date类。(要继续探索Java的奥义,真好用)。

 

第三次作业:

第一题:7-1 菜单计价程序-3

类图:

 

 

 

 

耦合度、圈复杂度:

 

 

Statments(有效语句):266行

Percent Branch Statements(分支语句比例):22.9

Maximum Complexity(该类中最复杂函数的复杂度):44(太难过了)

由Kiviat Graph图可知:Average Complexity为7.18(也比较高了),Max Complexity是44,(比那个判断日期的稍微低一点点哈哈哈)。Tablesearchrq()复杂度为11。Avg Depth(平均函数深度),Avg Stmts/Merhod(平均每个方法中的语句)都严重超标啊!绷不住了。

简述:

这个题目在前两个题目的基础上又加上了桌号,和一个桌给另一个桌点菜的功能。增加了一个Table类,Table类中又包含了Order。由于一个餐馆不止一个桌,所以先new一个Table类的数组,记录每桌的信息。这次老师并没有给我们提供Table类,而是要我们自己设计类。在able类当中,还要判断是否点菜时间再营业时间范围内,所以Table类当中加上了一个searchrq()的方法。用于判断是否在营业时间范围内,是否是周末点菜。如果是在营业范围内,则返回discount的值

为8或6或10。如果不是则返回0。DIsh类:String name;//菜品名称int unit_price; //单价int getPrice(int portion,int num)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)如果portion=1,unit_price*num;如果portion=2返回1.5*unit_price*num;如果都不是,unit_price*2*num;Menu类:Dish[] dishs//菜品数组,保存所有菜品信息Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。使用循环,在DIsh数组里面查找是否有该菜,如果有,那么返回找到的Dish对象,如果没有,则返回空。Dish addDish(String dishName,int unit_price)//添加一道菜品信息,返回添加的Dish对象。Record 类i:orderNum;//序号\Dish d//菜品\num;//份数portion;//份额(1/2/3代表小/中/大份)\int getPrice(){//计价,计算本条记录的价格\创建一个变量接受d调用getPrice方法返回的值。Order类Record[] records//保存订单上每一道的记录,discount//折口,int getTotalPrice(Order order,Menu menu,int dn[]){使用遍历对record数组进行判断是否有该菜,如果有,则赋上record里面的dish对象,如果dn[i]等于1,则为删除的菜,不计入总价,否则计入总价。Record addRecord(int orderNum,String dishName,int portion,int num) :创建Record对象,接受相应信息。int delARecordByOrderNum(int orderNum){//根据序号删除一条记录,对record数组进行遍历,如果有该点菜序号,则返回1,否则返回0,int数组dn接受。void findRecordByNum(int orderNum,Menu menu){//根据序号查找一条记录,对record数组进行遍历,如果有该菜,则赋上record数组里面的dish对象,如果找到了该点菜信息的序号,则调用record类的getPrice方法,输出序号+菜名+该菜价格。Table类:Order order//每个桌都有一个订单,tnum;//桌序号,int[] dn//记录要删除的,dn1//记录要删除的个数,String[] hbook=new String[20];//记录代点的对想和被带点的对象。rq//日期,sj//时间,int[] r=new int[20];double searchrq()//判断是否在营业范围内,以及discount该为多少。返回discount。

Main类:用split方法对输入的信息进行分割,加上循环进行输入,判断是哪个阶段(不过这个流程if else语句用了太多,需要改进)。然后在遍历所有的桌类,对每桌的信息进行输出。

但这其实很麻烦,不必对每桌判断或计算出的信息进行存储后在输出,一个改为直接按题目要求的信息进行判断和计算,然后按顺序输出即可。

其次就是有很多地方都用到了如果存在该菜,那么d就为空,这个应该单独写成一个方法就可以直接调用,不必重复写。

在判断日期,时间的时候,分为先判断是星期几,再判断在不在营业时间范围内,这两个方法可以分开写,这样就避免方法中语句太多,实用性不强。

 

后面的题目:7-2 有重复的数据、7-3 去掉重复的数据、7-4 单词统计与排序、7-5 面向对象编程(封装性)、7-6 GPS测绘中度分秒转换、7-7 判断两个日期的先后,计算间隔天数、周数

前两个题目差不多,都用到了Java里面的List、ArrayList、HasSet、LinkedHashSet类,以及replace方法。

第四题单词统计与排序:Collections.sort(list1,String.CASE_INSENSITIVE_ORDER);//首字母排序忽略大小写,list1.sort(new Sort_length());//长度排序。

第五题使用了Java的封装性,即set、get。

第六题分秒转换:注意Java里面double不用%lf,而是%f(真的会谢)。

第七题判断日期:LocalDate类中of()、isAfter()、isBefore()方法,ChronoUnit类中DAYS、WEEKS、MONTHS等方法。

在这里才觉得Java是真的牛!!!

 

踩坑与心得:

①第三个菜单系列的题目,格式错误了好久啊,最后一天才改过来的。原来不需要用鼠标双击看后面有多少个空格,只需要复制过去照着输出样例的改就可以了。(蠢死了啊蠢死了)

②next()和nextLine()是真的用明白了啊,之前输入的内容和数组里面存储的总是不一样,终于改好了。

next():它会自动地消除有效字符之前的空格,只返回输入的字符,不会得到带空格的字符串。\n\n也就是说如果输入了一串字符,到了有空格的时候就会停止录入,只录入空格前面的东西,空格后面的东西(包括分隔的空格都会保留在缓存区域)\n\n除了空格以外,Tab键和Enter键都被视为分隔符(结束符)。

nextLine():它返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的。\n\n也就是说输入一串字符,它就可以接受所有字符包括空格,但是遇到回车Enter就会停止录入,只录入前面的东西。

还有一个注意的点就是nextLine这个L要大写而不是小写!!!

③7-4房产税费计算2022这个题特别注意数据的单位:房款(整数/单位万元)、评估价(整数/单位万元)、房屋面积(浮点数/单位平方米)。在计算价格的时候记得乘上10000。

if(n==1)
        {
            if(s<=90)
                q=m1*0.01;
            else if(s>90&&s<=144)
                q=m1*0.015;
            else if(s>144)
                q=m1*0.03;//注意单位是万元,要乘以10000
        }
        else
            q=m1*0.03;
        double y=m*0.0005;

 

改正后:

if(n==1)
        {
            if(s<=90)
                q=m1*10000*0.01;
            else if(s>90&&s<=144)
                q=m1*10000*0.015;
            else if(s>144)
                q=m1*10000*0.03;//注意单位是万元,要乘以10000
        }
        else
            q=m1*10000*0.03;
        double y=m*0.0005*10000;

 

在使用substring(int a,int b)方法的时候,注意是前开后闭,下标为a的取到,下标为b的不会取到。

⑤7-7判断三角形类型的时候如果是

if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a)
System.out.print("Right-angled triangle");

测试点等腰直角三角形就会过不了,应该为if((a*a+b*b-c*c<0.1)||(a*a+c*c-b*b<0.1)||(b*b+c*c-a*a<0.1)),虽然不知道为啥。。。

 

 

else if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a)
            System.out.print("Right-angled triangle");

改进后:

if((a*a+b*b-c*c<0.1)||(a*a+c*c-b*b<0.1)||(b*b+c*c-a*a<0.1))
            System.out.print("Right-angled triangle");

 

 

注意题目要求三条边的取值范围均为[1,200],而我写的是if(a<1||b<1||c<1||a>200||b>200||c>200),少了等号啊啊!难怪非三角形测试点一直过不了,居然刚刚才发现,绷不住了。

if(a<1||b<1||c<1||a>200||b>200||c>200)
{
System.out.print("Wrong Format");
return;
}

 

改正后:

if(a<=1||b<=1||c<=1||a>=200||b>=200||c>=200)
        {
            System.out.print("Wrong Format");
            return;
        }

 

⑥7-1 菜单计价程序-1,没有传Menu menu,吃大亏。

优化后:

int getTotalPrice(Order order,Menu menu,int dn[]){//计算订单的总价
           int j=0,sum=0;
           Dish d;
            while(order.records[j]!=null)
            {
                d=menu.searthDish(order.records[j].d.name);
                if(d!=null)
                    order.records[j].d=d;
                if(dn[j]!=1)
                    sum+=order.records[j].getPrice();
                j++;
            }
            return sum;
       }

 

在运行时,有好多menu.dish[i].d为null,Order.record[j].record为null,Record里面的record也new了,Dish里面的dish也new了,明明new了menu和order但还是为null。这是因为虽然new了menu和order和Dish、Order里面的也都new了,但是数组没有new。应该加上new Dish[100],new Record[100]。

 

Dish[] dishs;//菜品数组,保存所有菜品信息
Record[] records;//保存订单上每一道的记录

改正后:

Dish[] dishs=new Dish[10];//菜品数组,保存所有菜品信息
Record[] records=new Record[100];//保存订单上每一道的记录

 

⑦7-2 菜单计价程序-2,没有用split方法进行分割,吃大亏。

不需要先判断点的菜是否存在,删除的是否存在,再标记为返回0则存在,返回1则不存在。最后再遍历order里面的record里面的int型数组是0,还是1来判断是否输出delete error,does not exist。直接按照样例给出判断后输出相应的结果即可。

 

⑧7-3 jmu-java-日期类的基本使用,计算相差了多少个月的时候,要算上年份相差了多少,而不是只看月份的数值相差了多少。

还有要注意的是,题目明确提出:第一行输入一个日期字符串,格式为"YYYY-MM-dd"。所以还要判断输入的格式是否正确,这里就要使用substring(int a,int b);方法和equals(" ")方法。

优化后:

 

else if(riqi.y.length()==10)
        {
            String f2=riqi.y.substring(0,1);
            String f3=riqi.y.substring(1,2);
            String f4=riqi.y.substring(2,3);
            String f5=riqi.y.substring(3,4);
            String f=riqi.y.substring(4,5);
            String f6=riqi.y.substring(5,6);
            String f7=riqi.y.substring(6,7);
            String f1=riqi.y.substring(7,8);
            String f8=riqi.y.substring(8,9);
            String f9=riqi.y.substring(9,10);
            if(!f.equals("-")||!f1.equals("-"))
                x=0;
            if(f2.equals("-")||f3.equals("-")||f4.equals("-")||f5.equals("-")||f6.equals("-")||f7.equals("-")||f8.equals("-")||f9.equals("-"))
                x1=0;
          ......
        }

 

⑨7-4 小明走格子,这个题目是真的,我不理解。。。必须要用StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));这个类会让数据读取的更快。

 

优化后:

StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        sc.nextToken(); 
        int t = (int)sc.nval;
        int i,j,g=0;
......
for(i=0;i<t;i++) { sc.nextToken(); b[i] = (int)sc.nval; if(g < b[i]) g = b[i]; }

 

 

主要困难以及改进建议:

主要困难:就是写菜单系列的题目的时候,不确定类的设计是否正确,合不合适,还有就是有的测试点总是过不了,方法太复杂,有点乱,思路不清晰。

改进建议:

①每个类之间的耦合度太强,要尝试着降低耦合度。

②方法里面的语句太多,没有将功能分开,实用性不强。复杂度也太强,需要改进,例如if else,可以进行优化表达式:针对if、else判断的处理,如果之后没有处理,则在if中直接返回,else无需使用;提炼函数:将可以组织独立起来的代码放进一个独立函数中,并使用可以解释函数用法的函数名。简化代码[合并条件式、使用更简洁的表达]:将当前算法重构成更简洁清晰的算法。减少认知复杂度:如果大量使用if-else语句可以考虑用switch代替;考虑使用return和break替换标记变量,提高可读性。工具类替换逻辑判断:使用已有的工具类判断。判空等操作可以使用工具类,减少&&和||的判断使用。

复杂度太大,导致代码漏洞太多,很多测试点过不了。代码也写得太乱。

③有时候就是想到还有什么功能没写就加上什么。应该提前设计好思路,看好所有的题目要求,先设计大概,再设计方法。

④还有就是代码没有照着老师给的注释格式进行注释。应该按照老师的要求来。

 

总结:

这三次题目主要分为三类。

第一类就是菜单系列:该系列是真正用到了Java面向对象的思想,用到了Dish类、Record类、Order类、Table类、Menu类。这个系列的题目

第二类就是日期判断系列:这个系列都是要使用Date、LocalDate中的计算相差多少天,多少月,多少年、和split分割符判断是否格式相同。

第三个系列就是数据计算:这里就要注意类型转换和数据输出要求是小数点后几位,掌握Math类里面的部分方法,注意Java里面double是%f。

第四个系列就是字符串的处理:用到了List、ArrayList、LinkedHashSet、Collections.sort();//首字母排序、list1.sort(new Sort_length());//长度排序,和replace方法。

学到了:面向对象的基础思想,类与类之间的关系和用法,构造方法的用法,Java里面各种类的用法,如何再类的方法上传参。学到了封装,即把彼此相关数据和操作包围起来,抽象成为一个对象,变量和函数就有了归属,想要访问对象的数据只能通过已定义的接口。

学习及研究的地方:如何降低圈复杂度,如何降低耦合度,如何增加代码的实用性,然后将方法的语句变少,学会使用面向对象的思想。

对教师、课程、作业、实验、课上课下组织方式的改进建议:课程上每次都布置课堂任务及时练习很好,但是希望可以讲解一下下一次大作业的思路(菜单系列),也可以把同学问的较多的问题再课堂上讲解一下,也可以分享在群上。

posted on 2023-04-01 23:48  猜卟鋀  阅读(78)  评论(0)    收藏  举报