PTA前三周作业总结

  • 前言(作业题目总结)

前三次作业都是对Java学习情况的一个检查。就个人而言,前两次作业考察的内容与之前学的C语言有相似之处,因此做起来可能没有特别大的难度。是加强Java基本语句熟练度的两次作业,虽然题目数量比第三次作业多,但还是比较轻松。第三次的作业确实是对我的一个很大的挑战。第三次作业主要是考察正则表达式的学习情况,虽然只有三题,但是花费了很多时间在学习正则表达式的恰当运用上。做第一题的时候甚至没有想到用正则表达式,导致花了很多时间。

  • 设计与分析

  1. 第二次大作业 --- 串口字符解析

这次作业我觉得主要就是字符串的处理问题,合理运用Java工具类函数就能把串口字符按题目要求截取,然后单独判断输出结果。

类图:

因为只需要相应切割逐个判断,就没有过多的函数,一Main到底了。

附主功能代码

public class Main {

    public static void main(String[] args) {

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

        String a = in.nextLine();
        int no = -1;
        int cnt = 1;//第几个输出
        int cnt1= 0;//统计1的个数
        no = a.indexOf('0');
        if(no == -1||a.length()<11)
            System.out.println("null data");
        else
        {
            while(no!=-1)
            {
                
                if(no+11>a.length())
                    {break;}
                else 
                {
                    char isch2;//判断位应该为啥
                    String b = a.substring(no,no+11);
                    
                    for(int i=1;i<9;i++)
                    {
                        char ch = b.charAt(i);
                        if(ch == '1')
                            cnt1 ++;
                    }
                    if(cnt1 %2 == 0)
                        isch2 = '1';
                    else isch2 = '0';
                    cnt1=0;
                    char ch1 = b.charAt(10);//结束
                    char ch2 = b.charAt(9);//判断位
                    if(ch1 !='1')
                        {System.out.println(cnt + ":" + "validate error");cnt++;}
                    else if(ch2 != isch2)
                        {System.out.println(cnt + ":" + "parity check error");cnt++;}
                    else 
                    {
                        System.out.println(cnt + ":" + b.subSequence(1, 9));
                        cnt++;
                    }
                    
                    no = a.indexOf('0', no+11);
                    
                }
                
            }
        }
        
    }

}
  1. 判断合法输入
  2. 向后取11位并判断1的个数,确定奇偶校验位数字。

 

分析图:

 

这个题就用Java的String类中的函数,遇到判定的数字就往后切割八位进行判断。记录1出现的次数作为奇偶校验位。

这道题我选择直接用切割出指定长度的字符串进行判断,使用indexof函数寻找下一个符合的字符串并使之成为子串。虽然代码不是特别长,但是如果能使用函数的方法分开功能,应该会更好一点。


 

  •  第三次大作业 --- 点线形系列1-计算两点之间的距离

主要考察的是正则表达式的使用,但是我没了解过正则表达式,就没有使用,而是选择一板一眼的用if语句和for循环判断条件,浪费了很多时间,并且代码的质量也不够好,虽然能通过所有的测试点,但是可能对于更多的数据,还是存在些许bug。

类图:

这道题还是一Main到底(无效写题),代码利用率特别低,重复代码很多。

switch(don) 
                   {
                   case 0:x1 = Double.parseDouble(b);don++;k+=b.length()+1;
                   break;
                   case 1:y1 = Double.parseDouble(b);don++;k+=b.length()+1;
                   break;
                   case 2:x2 = Double.parseDouble(b);don++;k+=b.length()+1;
                   break;
                   case 3:y2 = Double.parseDouble(b);don++;k+=b.length()+1;
                   break;
                   }

类似这种。

并且这种方法特别容易考虑不全,导致错判漏判,以后还是得加以改进,使用更加全面的方法解决问题。

分析图:

 


  • 第三次大作业 --- 点线形系列2-线的计算

在经过第一题的折磨后,开始学习正则表达式的使用了。第一题还能用for和if语句强行判断下来,但是第二题开始,正则表达式的优势就完全显现出来了。首先就是输入格式的判断,正则表达式可以很直观的检测出输入的字符串是否符合规范,不符合规范的字符串可以直接输出错误提示并结束程序,相较于第一题的艰难寻找来说,省事了特别多。并且学习了正则表达式的相关内容,使用

import java.util.regex.Pattern;
import java.util.regex.Matcher;

正则表达式中Pattern类和Matcher类,可以直接计算出输入点的数量,方便直接判断点数是否符合规范。

String b = new String("[+-]?\\d+(\\.\\d+)?\\,[+-]?\\d+(\\.\\d+)?");
            Pattern pattern = Pattern.compile(b);
            Matcher mat = pattern.matcher(a);
            int cnt = 0;                 //点的个数
            while(mat.find()){
                cnt++;

在判断正确格式的同时,按点分割,计算输入的点数。

 

类图:

这题开始定义了一个点类,方便储存输入的点的坐标。

class Dian
{
    double x,y;
}

定义了一个点类

private static int geidian(String jian,int cnt) {
        cai = jian.split(",|\\s");
        boolean istrue = true;
        for(int j=0;j<cai.length;j++)
        {
            if(cai[j].length()>1)
            if(cai[j].charAt(0)=='0'&&cai[j].charAt(1)!='.')
                {istrue = false;break;}
        }
        if(istrue)
        {
            for(int j=0,i=0;j<cai.length;j+=2,i++)
            {
                    s[i] = new Dian();
                    s[i].x = Double.parseDouble(cai[j]);
                    s[i].y = Double.parseDouble(cai[j+1]);
            }
            return 1;
        }

输入点的坐标并储存

并且改变了一Main到底的格式,将每个功能分成函数,提高了代码利用率,并且减少了代码重复,提高质量。

分析图:

 

还有待提高代码利用率


 

  • 第三次大作业 --- 点线形系列3-三角形的计算

这道题是这三次作业中唯一一道没有完成的题目,这道题前半部分的内容与第二题大致一样,主要的难点就在选项四和选项五上。

4:输入五个点坐标,输出前两个点所在的直线与三个点所构成的三角形相交的交点数量,如果交点有两个,则按面积大小依次输出三角形被直线分割成两部分的面积。若直线与三角形一条线重合,输出"The point is on the edge of the triangle"
5:输入四个点坐标,输出第一个是否在后三个点所构成的三角形的内部(输出in the triangle/outof triangle)。
必须使用射线法,原理:由第一个点往任一方向做一射线,射线与三角形的边的交点(不含点本身)数量如果为1,则在三角形内部。如果交点有两个或0个,则在三角形之外。若点在三角形的某条边上,输出"on the triangle"

选项四因为函数没有泛用性,导致很多相似功能性函数得重写,没完成好。

类图:

  1. 判断合法输入
  2. 将输入的坐标存进点类
  3. 根据选项进入相应函数

 

分析图:

 

前三个选项和错误输入方面都已经尽力完善了,但是后面的代码还是有待提高。


  • 踩坑心得

  1. 在第三次作业的第一题提交的时候,总是有几个测试点过不去,仔细检查才发现是输出“Wrong Format”的时候拼写错误导致答案错误,这种低级的错误属实不该犯!!
  2. 在第三次作业的第二题和第三题中,出现了大量计算,但是爆double了,出现了精度错误。

    换成了差值小于1e-5解决了精度问题,通过了测试点。

  3. 第三次作业的第三题出现了保留位数的问题。
    注意:输出的数据若小数点后超过6位,只保留小数点后6位,多余部分采用四舍五入规则进到最低位。小数点后若不足6位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333333,1.0按格式输出为1.0
    按照if语句判断的话,代码很复杂,看起来也很不舒服,后面了解到了Java的另一个工具类函数。
    import java.text.DecimalFormat;
    利用函数的格式判断,
    String m1 = new DecimalFormat("#0.0#####").format(zhou);
            String m2 = new DecimalFormat("#0.0#####").format(mian);
            String m3 = new DecimalFormat("#0.0#####").format(xn);
            String m4 = new DecimalFormat("#0.0#####").format(yn);
    可以直接按照题目要求的格式输出,通过测试点。但是从代码重复来看,还有待提升,但是学到了新的知识还是很不错的。
  4. 在第三次作业的第三题中,我写了一个储存交点的类,并且写了一个功能函数来找交点,
    private static int findjiao(Dian a, Dian b, Dian c, Dian d) {
            
            boolean inside = false;         
            double a1 = a.y-b.y;
            double b1 = a.x-b.x;
            double c1 = a1*a.x+b1*a.y;
            
            double a2 = c.y-d.y;
            double b2 = c.x-d.x;
            double c2 = a2*c.x + b2*c.y;
            
            double xn = -(c2*b1-c1*b2)/(a1*b2-a2*b1);
            double yn = (c1*a2-c2*a1)/(a1*b2-a2*b1);
            
            if(xn>=Math.min(c.x, d.x)&&xn<=Math.max(c.x, d.x))
            {
                inside = true;
                if(jia==0)
                {
                    ss[0] = new Dian();
                    ss[0].x = xn;
                    ss[0].y = yn;
                    jia++;
                    return 1;
                }
                else
                {
                    if(xn!=ss[jia-1].x&&yn!=ss[jia-1].y)
                    {
                        ss[jia] = new Dian();
                        ss[jia].x = xn;s[jia].y = yn;
                        jia++;
                        return 1;
                    }
                    
                }
            }
            return -1;
            
            
        }
    因为考虑不周全,所以导致这个又臭又长函数只能做一个是否有交点的判断,显得比较鸡肋。
  • 改进建议

  1. 首先在写代码前要有整体的构思,要明确要写多少个功能函数,并且要考虑到功能函数的泛用性,不能仅限于为某一段代码服务,要能够被整个代码利用,要具有通用性。
  2. 遇到精度问题的时候,用math函数解决问题,直接的数学判断容易出现差错。
  3. 输出注意格式,要仔细审题,不要犯马虎的错,拼错单词打错字母这种事,最好不要再犯。
  • 总结

  1. 总的来看,这三次大作业我更加熟悉了Java的基本语句的使用,包括字符串判断,传参,定义类和对象,通过网上查询资料,询问周围同学(大佬),学到了很多Java的工具类函数,提高了代码的质量和效率,感谢我身边帮助我的人,谢谢谢谢。
  2. 这几次作业让我学习到了很多新的知识,但是我对这些函数都只是知道一点皮毛,看资料后依葫芦画瓢加入自己的代码中进行运用,并没有透彻了解,需要进一步深入,将知识融会贯通,真正掌握才是学到了。在网上查询资料的同时,我也发现了很多有趣而且功能强大的函数,以及一些提高算力的算法,虽然这几次作业可能并没有用上,但是这激发了我深入学习的兴趣,我觉得这是我三次作业以来最大的一个收获。

 

 

 

posted @ 2022-04-10 01:48  "凉苒。  阅读(102)  评论(0)    收藏  举报