第一次博客作业

第一次博客作业

一、   前言

对于初次接触到Java这门课程的我来说,许多知识点一开始是很难理解的。但是,随着学习的逐渐深入,我对Java产生了浓厚的兴趣,时常沉浸在编程中好几个小时。

尽管因为一个测试点没通过而屡次修改代码,最后还是没通过的这种感觉很难受,但是我还是通过不断尝试,不断请教,不断改进完成了这三次的题目集。在完成作业的过程中,我最深的感受就是要细心并且持之以恒。这三次作业的情况如下:

 

  1. 题目集01

  知识点基本来自于教材的前八章,例如循环,方法,一维数组等。对于本题目集而言,大多数看看教材就能完成,实在不会百度一下就可以了。虽然题目量比较大,但是都是基础。

   2.题目集02

  这次题目集的题量很少,但是每道题目都花了我不少时间来完成。可以说,对于当时的我来说,难度很大。这次题目集的知识点基本都是关于字符串的,其中字符串的分割和提取是百度上了解到的。

   3.题目集03

  这次题目集的题量和上次一样少,只有四题,但是难度也和上次一样,甚至更难。前两道题目的知识点是关于使用类的,后两道题目是在使用类的前提下运用类的两种聚合。在我看来,第二题是这次题目集的核心,后两道题目都是在其基础上进行改进来完成的。

二、   设计与分析

下面我将要对这三次的题目集进行详细分析,重点是对源码的分析,解释和完成题目后的心得。分析如下:(以下均是我个人的理解,可能与标准说法不同,请见谅)

  1. 题目集01

这次题目集的题目都比较基础,对我来说难度相对较高的只有第六题和第九题。另外值得注意的有:double类型存在误差,使用时需要注意精确度。还有就是float类型的数进行乘除运算后,其结果是double类型,需要强制转换才能变为float类型。例如:

float m,l;

               float mE,lE;

              m=in.nextFloat();

              l=in.nextFloat();

              mE=(float)(m/0.45359237);

              lE=(float)(l/0.0254);

        下面对第六题和第九题的源码进行分析和解释:

        第六题:

        import java.util.Scanner;

public class Main{

              public static void main(String[] args) {

              Scanner in = new Scanner(System.in);

              String s=in.nextLine();

              char[] f=new char[10];

              int c=s.length();

              for(int i=0;i<c;i++) {

                     f[i]=s.charAt(i);                   //将输入的字符串的每个字符存入字符数组f中

              }

              if(c==8) {                                   //判断输入的学号是否是8位

                     if(f[2]=='0') {

                            switch(f[3]) {               //判断学院

                            case '1':{

                    System.out.println("入学年份:20"+f[0]+f[1]+"年");

                    System.out.println("学院:材料学院");

                    System.out.println("班级:"+f[4]+f[5]);

                                System.out.println("学号:"+f[6]+f[7]);

                }break;

                            case '2':{

                    System.out.println("入学年份:20"+f[0]+f[1]+"年");

                    System.out.println("学院:机械学院");

                    System.out.println("班级:"+f[4]+f[5]);

                                System.out.println("学号:"+f[6]+f[7]);

                }break;

                            case '3':{

                    System.out.println("入学年份:20"+f[0]+f[1]+"年");

                    System.out.println("学院:外语学院");

                    System.out.println("班级:"+f[4]+f[5]);

                                System.out.println("学号:"+f[6]+f[7]);

                }break;

                default:System.out.println("Wrong Format");

                            }

                     }

                     else if(f[2]=='2'&&f[3]=='0') {

                                   System.out.println("入学年份:20"+f[0]+f[1]+"年");

                                   System.out.println("学院:软件学院");

                                   System.out.println("班级:"+f[4]+f[5]);

                                   System.out.println("学号:"+f[6]+f[7]);

                     }

            else

                            System.out.println("Wrong Format");          //非法输入

              }

        else

                     System.out.println("Wrong Format");

         }

}

心得:将字符串拆分后,方便对每个字符进行判定,从而可以完成本题。

第九题:

import java.util.Scanner;

public class Main{

    public static void main(String[] args){

        double a,b,c;

        Scanner in = new Scanner(System.in);

        a = in.nextDouble();

        b = in.nextDouble();

        c = in.nextDouble();

     if(a>=1&&a<=200&&b>=1&&b<=200&&c>=1&&c<=200){//判断边长是否合法

          if(a + b > c&&b + c > a&&a + c > b){  //是否能构成三角形

            if(a == b&&b == c)                        //等边

            System.out.println("Equilateral triangle");

            else{

                if(a==b||b==c||a==c){

        if(a*a+b*b-c*c<0.1||b*b+c*c-a*a<0.1||a*a+c*c-b*b<0.1)//等腰直角,存在误差

                System.out.println("Isosceles right-angled triangle");

                else

                System.out.println("Isosceles triangle");   //等腰

                 }

                else{

                 if(a*a+b*b-c*c<0.1||b*b+c*c-a*a<0.1||a*a+c*c-b*b<0.1)//存在误差

                 System.out.println("Right-angled triangle");

                 else

                 System.out.println("General triangle");

                }

            }

          }

          else

            System.out.println("Not a triangle");

        }

        else

          System.out.println("Wrong Format");

    }

}

心得:因为a,b,c是double类型,存在误差,因此判断直角三角形时不能使用勾股定理。先判断等腰直角三角形,再是等腰,最后是直角。

   2.题目集02

这次的题目难度较大,但是只要了解了字符串的相关知识点,经过尝试后还是可以做出来的。重点在于第二题,源码如下:

public class Main {

 

       public static void main(String[] args) {

              java.util.Scanner in = new java.util.Scanner(System.in);

              String s=in.nextLine();

              String[] str=new String[100];       //用于储存分割后的字符串

              int i,j,c=0,n=0;

              for(i=0;i<s.length();i++)

                     if(s.charAt(i)=='0')               //起始位

                            c++;

              if(s.length()<11||c==0)                 //长度不足11位或全为1,无起始位

                     System.out.println("null data");

              else {

                     for(i=0;i<s.length();i++) {

                            if(s.charAt(i)=='0') {      //找到起始位

                                   if(i+11<=s.length()) {

                                   str[n]=s.substring(i+1,i+11);  //将起始位后十位分割

                                   n++;

                                   i=i+10;                               //开始寻找下一个起始位

                                   }

                                   else

                                          break;

                            }

                     }

                     for(i=0;i<n;i++) {

                            System.out.printf("%d:",i+1);  //输出序号

                            output(str[i]);                        //输出结果

                     }

              }

       }

       public static void output(String str) {

              int l=str.length(),c=0;

              for(int i=0;i<str.length()-1;i++) {

//计算起始位后九位共有多少个1,赋值给c,用c来检验奇偶检验位

                     if(str.charAt(i)=='1')                   

                            c++;

              }

              if(str.charAt(l-1)=='0'&&c%2==1)       //结束符错误,奇偶检验位正确

              System.out.println("validate error");

              else if(str.charAt(l-1)=='1'&&c%2==0)

              System.out.println("parity check error");//结束符正确,奇偶检验位错误

              else if(str.charAt(l-1)=='0'&&c%2==0)

              System.out.println("validate error");//结束符错误,奇偶检验位错误

              else

              System.out.println(str.substring(0,8)); //结束符正确,奇偶检验位正确

       }

}

心得:一开始没理解奇偶检验位的含义,导致一些正常输入错误,后面知道奇偶校验是需要包括奇偶检验位的。做出第二题后,后面的题目花的时间就少了很多。

      

  3.题目集03

这次题目的难度明显上升,几乎每一题都花了我好几个小时,下面进行详细分析:

7-1:这一题轻松解决,结构比较简单。在QuadraticEquation()中给a,b,c赋值,getDiscriminant()返回方程解的判别式,getRoot1(),getRoot2()返回方程的根。

 

 

    7-2:这一题我尝试了近二十次才完成,曾一度想放弃,好在我还是坚持下来了。难度主要在三个主功能上:求下n天,求前n天,求两个日期相差的天数。求下n天时,如果n很大的话则需要逐年增加,否则会运行超时,但是这种方法需要判定这一年和下一年是否为闰年;n小于365时,可以通过for循环来解决。求前n天与求下n天方法差不多,不过是增加天数变成减少天数而已。求两个日期相差的天数就要稍微复杂一些,先要判断两个日期的先后,然后从较小的日期开始逐天增加到较大的日期,增加方式与求下n天相同。

 

 

    7-3:虽然这题是在第二题的基础上进行改进,但是我还是测试了很多次才完成。难度在于类的这种嵌套关系,怎么给类的对象赋值让我思考了很久,最后我的解决方法是:给DateUtil类增加三个私有属性y,m,d分别对应年,月,日。Day类同样,Month类增加了y,m,Year类增加了y。这样可以做到DateUtil类的对象完成赋值的同时,Day类,Month类,Year类的对象也完成了赋值。

 

 

我的分析到此结束,但是可能还有很多地方值得分析,在此就不做补充了。

三、   采坑心得

在完成这3次题目集的过程中,我遇到了许多的问题,下面将对我遇到一些的问题分享一下我的心得(有些问题上面已经提到,这里就不重复了):

  首先,第一个问题是边界值测试:

  在题目集01的第一题,如下图:

 

在测试时,给出的用例测试结果都是对的,但是提交时总有两个边界测试错误。在询问过后,知道double类型存在误差,所以应将原有的边界加上0.05,减小误差。这可以说是一个小小的启发吧。之后在进行边界值测试时,应当考虑周全。

        下一个问题是非法输入测试:

        这个问题在很多题目中我都遇到过,最具代表性的我认为应该是题目集02的第二题,这题有很多测试点,需要考虑的非法输入形式较多:

 

当时为了做这道题目也是绞尽脑汁,总会有那么几个非法输入错误,在近5个小时的思考后才终于搞定。其实在进行非法输入测试时,只要足够细心,考虑可能的情况就可以了。。。吧?当然,我们也可以和同伴适当讨论一下,一个人的心思有限嘛。。。

    然后就是类的使用问题:

    在题目集03的第三题中,我遇到了这样一个问题:DateUtil类的对象可以赋值,但是Day,Month,Year这三个类的对象都无法进行赋值。之后采用了如下结构才解决:

class DateUtil{

       private int y;

       private int m;

       private int d;

       private Day day=new Day(y,m,d);

       public DateUtil(int y, int m, int d) {

              this.y=y;

              this.m=m;

              this.d=d;

              day.setVal(d);

              day.month.setVal(m);

              day.month.year.setVal(y);

       }

       …

       class Day{

              private int y;

              private int m;

              private int d;

              private Month month=new Month(y,m);

              public Day(int y,int m,int d) {

                     this.y=y;

                     this.m=m;

                     this.d=d;

                     month.year.setVal(y);

                     month.setVal(m);

              }

              …

              class Month{

                     private int y;

                     private int m;

                     private Year year=new Year(y);

                     public Month(int y,int m) {

                            this.y=y;

                            this.m=m;

                            year.setVal(y);

                     }

                     …

                     class Year{

                            private int y;

                            …

                     }

              }

       }

}

问题关键在于setVal()上,我只能用这个才能让Day类给Month类赋值,Month类给Year类赋值,说法可能不标准,但是事实如此。之后我明白一个类最好有getter()和setter()这样的方法。

       这些是我遇到的最大的问题,当然还有些小问题,因为很容易解决,这里就不赘述了。

四、   改进建议

  在编写代码之前,最好理清思路和逻辑,再着手尝试。

  不需要用到类的,要考虑需要构建什么样的方法才能实现功能,每个方法的耦合性要尽量最低。需要用到类的,则需要考虑类间关系,比如题目集03的第二,三,四题;其次是成员变量的类型,属性什么的。

五、   总结

  在完成这三次题目集的过程中,我遇到了很多困难,也收获了很多知识点。尽管我总是被难题虐到心累,我还是愿意继续不断的尝试,直到正确。也正是因为我总是死磕难题,才正在渐渐培养着一种更缜密的设计思维方式。自从我选择这个专业起,我一直不了解今后的去路,现在它是如此吸引我,让我好像有了目标。遇到难题不用怕,微笑面对它,能想到的办法总比困难多。之后,我需要学习和改进的地方还有很多,但是我会尽量使自己变得更优秀。靠自己的努力得到的满分,才是满满的成就感!

posted @   此时·此刻  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示