哈工大软件构件Lab1个人总结

这一篇博客是为了记录个人在Lab1遇到的几个知识点觉得很不错值得记录。

目录

这一篇博客是为了记录个人在Lab1遇到的几个知识点觉得很不错值得记录。

1.小心红包算法,如何编写convexHull()

2.getDistance()的编写

3.Personal art()的编写

5.在最后的结尾还是得吹一手Java和IDEA实在是相比于C++和Eclipse太好使


1.小心红包算法,如何编写convexHull()

1.1convexHull要求:

给定平面上一堆点集,输出位于凸包上的点。采用Gift-Wrapping算法。

1.2convexHull的主要思路:

特殊情况:如果size小于等于3可以直接返回

  1. 找到最左下角的点,这个点一定在凸包上
  2. 以最开始找到的点,去寻找下一个点,旋转角度最小,如果同一个最小旋转角度有多个点则选择最远的那个点
    1. 计算从curpoint当前点到其他非该点的点的最小角度mindegree,然后去寻找mindegree上的最远距离,这里的最远距离额外写了一个函数calculateDistance()来计算距离
    2. 获得了下一个点nextpoint将它存入Set res中,然后将curpoint = nextpoint继续执行for循环,继续寻找下一个点
    3. 循环结束直到nextpoint发现等于最开始的最左下角的点

1.2.1关于size<=3直接返回的原因:

        size=1,2的时候无法成为一个圈,两个点也只能成为一条线

    public static Set<Point> convexHull(Set<Point> points) {
        //可以直接返回
        if(points.size()<=3)
            return points;
        HashSet<Point> res = new HashSet<>();
        Point start=points.iterator().next();
        Point curpoint,nextpoint;
        double curdegree=0.0,mindegree,tempdegree;
        for(Point point:points)
        {
            if(point.x()<start.x() || (point.x()==start.x() && point.y()< start.y()))//以左下为起点
                start = point;
        }//找到第一个一定在凸包的点
        res.add(start);
        curpoint = start;
        nextpoint=curpoint;
        while(true)
        {
            mindegree=Double.MAX_VALUE;
            for (Point point : points) {
                if(point==curpoint)
                    continue;
                else
                {
                    tempdegree = calculateBearingToPoint(curdegree,(int)curpoint.x(),(int)curpoint.y(),(int)point.x(),(int)point.y());
                    if(tempdegree < mindegree)
                    {
                        mindegree = tempdegree;
                        nextpoint = point;
                    }
                    else if(tempdegree == mindegree &&  nextpoint!=curpoint)
                    {
                        double pointDistance =calculateDistance(curpoint.x(),curpoint.y(),point.x(),point.y());
                        double curPointDistance =calculateDistance(curpoint.x(),curpoint.y(),nextpoint.x(),nextpoint.y());
                        if(pointDistance>curPointDistance)
                            nextpoint=point;
                    }
                }
            }
            //寻找到下一个nextpoint,旋转角最小->mindegree,且这个方向线上最远的点
            if(nextpoint==start)
                break;
            res.add(nextpoint);
            curpoint=nextpoint;
            curdegree = (curdegree+mindegree)%360.0;
        }
        return res;
    }

2.getDistance()的编写

2.1getDistance中要求:

主要是通过BFS计算person1到person2的最短距离, * 如果person1=person2则返回0, * 如果person1和person2不连通返回-1

2.1getDistance中大致思路:

  1. getDIstance()实现通过BFS计算person1到person2的最短距离
    1. 判断是否是自己到自己,最短距离为0
    2. 初始化visited均为false
    3. 正式开始非递归BFS搜索,person1入队
      • While直到queue为空
        1. 记录当前这一圈size,保持distance同步
        2. for(int i=0;i<size;i++)扫描当前这一圈
          1. 如果从来没有访问过这个person
            1. 在该person内判断是否与person2相连,如果是则return distance
            2. 如果不是,则将这个person对应的friend加入外面一圈

2.1ps:给定一个BFS一圈一圈加入queue的示意图:

2.3具体代码:

 public int getDistance(Person person1, Person person2) {
        int distance = 0;
        if(person1 == person2) //对于到自己的距离为0
            return distance;
        for(int i=0; i<personList.size(); i++)
        {
            personList.get(i).setVisited(false);
        }
        //进行BFS搜索前初始化
        //找到最短距离p1->p2
        Queue<Person> queue = new LinkedList<>();
        queue.offer(person1);
        while(!queue.isEmpty()) {
            //扫描这一圈
            //将外围一圈加入
            int size = queue.size();//当前这一圈size
            distance++;
            for (int i = 0; i < size; i++) {
                Person currentPerson = queue.poll();
                if (!currentPerson.getVisited()) {
                    currentPerson.setVisited(true);
                    if (currentPerson.getFriend().contains(person2))
                        return distance;
                    //对应的部分外围一圈加上
                    for (Person p : currentPerson.getFriend()) {
                        if (!p.getVisited())
                            queue.add(p);
                    }
                }
            }
        }
        return -1;
    }

3.Personal art()的编写

3.1要求:立体三角管道,以周围三色螺线为界

3.2主要思路:

  1. 定义Size螺旋大小,Step每一步长度,Densi螺旋密度,ColorNum设置为3种颜色
  2. For循环中,通过不断增加步长同时修改角度来做到螺旋线

3.3最终代码:

public static void drawPersonalArt(Turtle turtle) {

        int Size = 200;
        int Step = 1;
        int Densi = 1;
        int ColorNum = 3;
        for (int i = 1; i <= Size; i++) {
            switch (i % ColorNum) {
                case 0:
                    turtle.color(PenColor.RED);
                    break;
                case 1:
                    turtle.color(PenColor.BLUE);
                    break;
                case 2:
                    turtle.color(PenColor.YELLOW);
                    break;
            }
            turtle.forward(Step * i);
            turtle.turn(360/ColorNum + Densi);
        }
    }

3.4结果:

 4.isLegalMagicSquare()的编写

4.1实现的主要思路:

  1. 接受fileName,将其改为绝对路径,通过new File(fileName)创建局部变量输入流。
    1. 利用第一行in.hasNextLine来判断文件是否内容为空
  2. magic作为读入的幻方二维数组,rowSum[i]代表index=i 行的行之和,colSum[i]代表index=i列的和,line表示文件内容的一行,list表示line,spit(“\t”)转换后的string数组
  3. 利用for循环逐步计算判断
    1. 每次判断当前行的length是否等于第一行的length,若不等于则并非矩阵return false
    2. 通过foreach迭代
      • 利用Integer.paraseInt(num)将string转为integer,判断是否为正,然后赋值给对应位置的magic,colsum,rowsum
  4. 再次foreach处理最后一行
  5. 判断i==length-1?来判断行数是否等于列数
  6. 利用trycatch来根据Exception类型执行报错提示信息并且返回false
  7. 然后用for循环计算正对角线之和sum1,负对角线之和sum2,然后与rowSum[0] 对比来判断对角线之和是否满足条件

4.2代码:

public boolean isLegalMagicSquare(String fileName) throws IOException {
        fileName = "src/P1/txt/" + fileName;
        File file = new File(fileName);
        Scanner in = new Scanner(file);//准备输入
        String line;
        String[] list;
        //利用第一行hasNextLine判断是否为空文件
        if(in.hasNextLine()) {
            line= in.nextLine();
            list = line.split("\t");
        }
        else {
            System.out.println("文件为空\t");
            in.close();
            return false;
        }
        int length = list.length;
        int[][] magic = new int[length][length];
        int[] rowSum = new int[length];//每行的sum
        int[] colSum = new int[length];
        int i, j;
        try {
            for (i = 0, j = 0; in.hasNextLine(); i++, j = 0)
            {
                if(length != list.length)//接下来这一行是不是和第一行length一样
                {
                    System.out.print("原因:(各行的列数并不完全相等)并非矩阵\t");
                    return false;
                }
                for (String num : list) {
                    if(Integer.parseInt(num)<0)
                    {
                        System.out.print("原因:矩阵某些数字非正整数");
                        return false;
                    }
                    magic[i][j] = Integer.parseInt(num);
                    colSum[j] += magic[i][j];
                    rowSum[i] += magic[i][j++];
                }
                line = in.nextLine();
                list = line.split("\t");
            }
            //in.nextline==null
            in.close();
            //处理最后一行
            for (String u : list) {
                magic[i][j] = Integer.parseInt(u);
                colSum[j] += magic[i][j];
                rowSum[i] += magic[i][j++];
            }
            //
            if(i != length-1) {
                System.out.print("原因:(行数不等于列数)行列数不相等\t");
                return false;
            }
        } catch (NumberFormatException ex) {
            System.out.print("原因:整数形式不规范(矩阵某些数字非正整数)或未用\"\\t\"分割\t");
            return false;
        } catch(ArrayIndexOutOfBoundsException ex) {
            System.out.print("原因:(列数小于函数导致数组越界)行列数不相等\t");
            return false;
        }
        int sum = rowSum[0];//累加和计为sum
        for(i=0;i<length;i++)
        {
            if(rowSum[i]!=sum || colSum[i]!=sum)
            {
                System.out.print("原因:行列数字和不相等\t");
                return false;
            }
        }
        int sum1=0;
        int sum2=0;
        for (i = 0; i < length; i++) {
            sum1 = sum1+magic[i][i];
            j=length-1-i;
            sum2 = sum2+magic[i][j];
        }
        if (sum1!=sum||sum2!=sum) {
            System.out.print("原因:对角线的数字和不相等\t");
            return false;
        }
        return true;
    }

5.在最后的结尾还是得吹一手Java和IDEA实在是相比于C++和Eclipse太好使

  1. 在之前寒假自学时候发现Java非常适合自己,我觉得Java这门语言热门不是没有道理的
    • 优势1:成熟容易上手的IDE:IDEA太智能啦太好用了,很多功能都集成好了,git/数据库mysql/tomcat。
    • 优势2:有众多的API还可以附带看规约注释,个人感觉比之前学过的C更适合编程序
    • 优势3:Java学习路线特别清晰明了也是自己的兴趣所在,前后端,javaweb,jdbc关于Eclipse或IntelliJ IDEA,它们作为IDE的优势和不足;
      • Eclipse劣势3:JDBC和JavaWeb阶段学习用Eclipse太繁琐
      • Eclipse劣势2:自动补全不如IDEA
      • Eclipse劣势1:UI感觉很落后。
      • IDEA优势1:UI很帅很酷
        • IDEA优势2:自动补全代码功能强大智能,还有Plugin插件很方便自己下载第三方插件使用
        • IDEA优势3:继承了很多功能,在JavaWeb学习上很方便
        • IDEA劣势:刚拿到IDEA时候,操作要记的细节太多,快捷键也太多了,刚入门摸不着头脑
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fars

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值