算法导论第四版学习——习题三Collinear Points

2023-10-16 07:30

本文主要是介绍算法导论第四版学习——习题三Collinear Points,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目正文:

http://coursera.cs.princeton.edu/algs4/assignments/collinear.html

作业难点:

1、仔细思考会感觉有很多实现方法,但是如果没有适当使用排序,算法时间复杂度就会轻易超过要求。(包括暴力算法)

2、隐含需要实现自己的数据结构用来组织“线”的集合,当然也可以用Stack或者Queue或者LinkedList,但是我个人是自己实现的。

3、由于一条线段只能出现一次,所以有一个去重的问题。(最难)

作业技巧:

1、基本按照题目的先后顺序实现,结合视频学习中的一些知识点就可以把任务串起来,不会无从下手。

2、SlopTo的计算结果和点数组的排列顺序有关吗?A.SlopeTo(B)和B.SlopeTo(A)其实是一样的,合理利用cache防止多次计算。

3、在暴力方法中,引入排序可以解决去重问题。

4、如果去重是通过在结果集合中查找是否存在,就铁定会超过复杂度要求,所以必须在添加结果集之前就能判断。

这里就有一个重要推论:a-b-c-d线段,无论从a开始查找还是从b开始查找,线段最大和最小点都不变为a和d,所以我们只需要找到起始点为线段最小点的线段就可以了,其他线段均抛弃即可

代码参考:

(这是我自己亲测100分的答案,不代表写得最好,请在自己实在完成不了的时候再看,不然的话做这个题目的意义一点都没有)

  1 import edu.princeton.cs.algs4.StdDraw;
  2 
  3 /******************************************************************************
  4  *  Compilation:  javac Point.java
  5  *  Execution:    java Point
  6  *  Dependencies: none
  7  *
  8  *  An immutable data type for points in the plane.
  9  *  For use on Coursera, Algorithms Part I programming assignment.
 10  *
 11  ******************************************************************************/
 12 import java.util.Comparator;
 13 
 14 
 15 public class Point implements Comparable<Point> {
 16     private final int x; // x-coordinate of this point
 17     private final int y; // y-coordinate of this point
 18 
 19     /**
 20      * Initializes a new point.
 21      *
 22      * @param  x the <em>x</em>-coordinate of the point
 23      * @param  y the <em>y</em>-coordinate of the point
 24      */
 25     public Point(int x, int y) {
 26         /* DO NOT MODIFY */
 27         this.x = x;
 28         this.y = y;
 29     }
 30 
 31     /**
 32      * Draws this point to standard draw.
 33      */
 34     public void draw() {
 35         /* DO NOT MODIFY */
 36         StdDraw.point(x, y);
 37     }
 38 
 39     /**
 40      * Draws the line segment between this point and the specified point
 41      * to standard draw.
 42      *
 43      * @param that the other point
 44      */
 45     public void drawTo(Point that) {
 46         /* DO NOT MODIFY */
 47         StdDraw.line(this.x, this.y, that.x, that.y);
 48     }
 49 
 50     /**
 51      * Returns the slope between this point and the specified point.
 52      * Formally, if the two points are (x0, y0) and (x1, y1), then the slope
 53      * is (y1 - y0) / (x1 - x0). For completeness, the slope is defined to be
 54      * +0.0 if the line segment connecting the two points is horizontal;
 55      * Double.POSITIVE_INFINITY if the line segment is vertical;
 56      * and Double.NEGATIVE_INFINITY if (x0, y0) and (x1, y1) are equal.
 57      *
 58      * @param  that the other point
 59      * @return the slope between this point and the specified point
 60      */
 61     public double slopeTo(Point that) {
 62         if ((this.x == that.x) && (this.y == that.y)) {
 63             return Double.NEGATIVE_INFINITY;
 64         } else if (this.x == that.x) {
 65             return Double.POSITIVE_INFINITY;
 66         } else if (this.y == that.y) {
 67             return 0;
 68         } else {
 69             return (that.y - this.y) / (double) (that.x - this.x);
 70         }
 71     }
 72 
 73     /**
 74      * Compares two points by y-coordinate, breaking ties by x-coordinate.
 75      * Formally, the invoking point (x0, y0) is less than the argument point
 76      * (x1, y1) if and only if either y0 < y1 or if y0 = y1 and x0 < x1.
 77      *
 78      * @param  that the other point
 79      * @return the value <tt>0</tt> if this point is equal to the argument
 80      *         point (x0 = x1 and y0 = y1);
 81      *         a negative integer if this point is less than the argument
 82      *         point; and a positive integer if this point is greater than the
 83      *         argument point
 84      */
 85     public int compareTo(Point that) {
 86         if ((this.x == that.x) && (this.y == that.y)) {
 87             return 0;
 88         } else if ((that.y > this.y) ||
 89                 ((that.y == this.y) && (that.x > this.x))) {
 90             return -1;
 91         } else {
 92             return 1;
 93         }
 94     }
 95 
 96     /**
 97      * Compares two points by the slope they make with this point.
 98      * The slope is defined as in the slopeTo() method.
 99      *
100      * @return the Comparator that defines this ordering on points
101      */
102     public Comparator<Point> slopeOrder() {
103         return new SlopeOrder(this);
104     }
105 
106     /**
107      * Returns a string representation of this point.
108      * This method is provide for debugging;
109      * your program should not rely on the format of the string representation.
110      *
111      * @return a string representation of this point
112      */
113     public String toString() {
114         /* DO NOT MODIFY */
115         return "(" + x + ", " + y + ")";
116     }
117 
118     /**
119      * Unit tests the Point data type.
120      */
121     public static void main(String[] args) {
122         /* YOUR CODE HERE */
123     }
124 
125     private class SlopeOrder implements Comparator<Point> {
126         private Point p0;
127 
128         public SlopeOrder(Point invokePoint) {
129             p0 = invokePoint;
130         }
131 
132         public int compare(Point p1, Point p2) {
133             double d01 = p0.slopeTo(p1);
134             double d02 = p0.slopeTo(p2);
135 
136             if (d01 < d02) {
137                 return -1;
138             } else if (d01 > d02) {
139                 return 1;
140             } else {
141                 return 0;
142             }
143         }
144     }
145 }
Point
  1 import edu.princeton.cs.algs4.In;
  2 import edu.princeton.cs.algs4.StdDraw;
  3 import edu.princeton.cs.algs4.StdOut;
  4 import java.util.Arrays;
  5 
  6 public class BruteCollinearPoints {
  7     private int lineNumber;
  8     private Node last;
  9 
 10     public BruteCollinearPoints(Point[] points) // finds all line segments containing 4 points
 11      {
 12       
 13         if (points == null) {
 14             throw new NullPointerException();
 15         }
 16 
 17         lineNumber = 0;
 18 
 19         int num = points.length;
 20 
 21         Point[] clone = new Point[num];
 22         
 23         for (int i = 0; i < num; i++) {
 24             if (points[i] == null) {
 25                 throw new NullPointerException();
 26             }
 27 
 28             for (int j = i + 1; j < num; j++) {
 29                 if (points[i].compareTo(points[j]) == 0) {
 30                     throw new IllegalArgumentException();
 31                 }
 32             }
 33             clone[i] = points[i];
 34         }
 35         Arrays.sort(clone);
 36         for (int i = 0; i < num; i++) {
 37             for (int j = i+1; j < num; j++) {
 38                 for (int m = j+1; m < num; m++) {
 39                     for (int n = m+1; n < num; n++) {
 40                         double d01 = clone[i].slopeTo(clone[j]);
 41                         double d02 = clone[j].slopeTo(clone[m]);
 42                         double d03 = clone[m].slopeTo(clone[n]);
 43 
 44                         if (d01 == d02 && d02 == d03)  {
 45                             if (last != null) {
 46                                 Node newNode = new Node();
 47                                 newNode.prev = last;
 48                                 newNode.value = new LineSegment(clone[i],
 49                                         clone[n]);
 50                                 last = newNode;
 51                             } else {
 52                                 last = new Node();
 53                                 last.value = new LineSegment(clone[i],
 54                                         clone[n]);
 55                             }
 56 
 57                             lineNumber++;
 58                         }
 59                     }
 60                 }
 61             }
 62         }
 63     }
 64 
 65     public int numberOfSegments() // the number of line segments
 66      {
 67         return lineNumber;
 68     }
 69 
 70     public LineSegment[] segments() // the line segments
 71      {
 72         LineSegment[] lines = new LineSegment[lineNumber];
 73         Node current = last;
 74 
 75         for (int i = 0; i < lineNumber; i++) {
 76             lines[i] = current.value;
 77             current = current.prev;
 78         }
 79 
 80         return lines;
 81     }
 82 
 83     public static void main(String[] args) {
 84         // read the n points from a file
 85         In in = new In(args[0]);
 86         int n = in.readInt();
 87         Point[] points = new Point[n];
 88 
 89         for (int i = 0; i < n; i++) {
 90             int x = in.readInt();
 91             int y = in.readInt();
 92             points[i] = new Point(x, y);
 93         }
 94 
 95         // draw the points
 96         StdDraw.enableDoubleBuffering();
 97         StdDraw.setXscale(0, 32768);
 98         StdDraw.setYscale(0, 32768);
 99 
100         for (Point p : points) {
101             p.draw();
102         }
103 
104         StdDraw.show();
105 
106         // print and draw the line segments
107         BruteCollinearPoints collinear = new BruteCollinearPoints(points);
108 
109         for (LineSegment segment : collinear.segments()) {
110             StdOut.println(segment);
111             segment.draw();
112         }
113 
114         StdDraw.show();
115     }
116 
117     private class Node {
118         private LineSegment value;
119         private Node prev;
120     }
121 }
BruteCollinearPoints
  1 import edu.princeton.cs.algs4.In;
  2 import edu.princeton.cs.algs4.StdDraw;
  3 import edu.princeton.cs.algs4.StdOut;
  4 
  5 import java.util.Arrays;
  6 
  7 public class FastCollinearPoints {
  8     private int lineNumber;
  9     private Node last;
 10 
 11     public FastCollinearPoints(Point[] points) // finds all line segments containing 4 or more points
 12      {
 13         if (points == null) {
 14             throw new NullPointerException();
 15         }
 16 
 17         lineNumber = 0;
 18 
 19         int num = points.length;
 20         Point[] clone = new Point[num];
 21 
 22         for (int i = 0; i < num; i++) {
 23             if (points[i] == null) {
 24                 throw new NullPointerException();
 25             }
 26 
 27             for (int j = i + 1; j < num; j++) {
 28                 if (points[i].compareTo(points[j]) == 0) {
 29                     throw new IllegalArgumentException();
 30                 }
 31             }
 32             clone[i] = points[i];
 33         }
 34         Arrays.sort(clone);
 35         
 36         if (num < 4) {
 37             return;
 38         }
 39 
 40         for (int i = 0; i < num - 1; i++) {
 41             int tempPointsNum = 0;
 42             Point[] tempPoints = new Point[num - 1];
 43 
 44             for (int j = 0; j < num; j++) {
 45                 if (i != j) tempPoints[tempPointsNum++] = clone[j];
 46             }
 47 
 48             Arrays.sort(tempPoints, clone[i].slopeOrder());
 49 
 50             int count = 0;
 51             Point min = null;
 52             Point max = null;
 53             
 54             for (int j = 0; j < (tempPointsNum - 1); j++) {
 55                 if (clone[i].slopeTo(tempPoints[j]) == clone[i].slopeTo(
 56                             tempPoints[j + 1])) {
 57                     if (min == null) {
 58                         if (clone[i].compareTo(tempPoints[j]) > 0) {
 59                             max = clone[i];
 60                             min = tempPoints[j];
 61                         } else {
 62                             max = tempPoints[j];
 63                             min = clone[i];
 64                         }
 65                     }
 66 
 67                     if (min.compareTo(tempPoints[j + 1]) > 0) {
 68                         min = tempPoints[j + 1];
 69                     }
 70 
 71                     if (max.compareTo(tempPoints[j + 1]) < 0) {
 72                         max = tempPoints[j + 1];
 73                     }
 74 
 75                     count++;
 76 
 77                     if (j == (tempPointsNum - 2)) {
 78                         if (count >= 2 && clone[i].compareTo(min) == 0) {
 79                             addLine(min, max);
 80                         }
 81 
 82                         count = 0;
 83                         min = null;
 84                         max = null;
 85                     }
 86                 } else {
 87                     if (count >= 2 && clone[i].compareTo(min) == 0) {
 88                         addLine(min, max);
 89                     }
 90 
 91                     count = 0;
 92                     min = null;
 93                     max = null;
 94                 }
 95             }
 96         }
 97     }
 98 
 99     private void addLine(Point a, Point b) {
100         if (last != null) {
101             Node newNode = new Node();
102             newNode.prev = last;
103             newNode.value = new LineSegment(a, b);
104             last = newNode;
105         } else {
106             last = new Node();
107             last.value = new LineSegment(a, b);
108         }
109         lineNumber++;
110     }
111 
112     public int numberOfSegments() // the number of line segments
113      {
114         return lineNumber;
115     }
116 
117     public LineSegment[] segments() // the line segments
118      {
119         LineSegment[] lines = new LineSegment[lineNumber];
120         Node current = last;
121 
122         for (int i = 0; i < lineNumber; i++) {
123             lines[i] = current.value;
124             current = current.prev;
125         }
126 
127         return lines;
128     }
129 
130     public static void main(String[] args) {
131         // read the n points from a file
132         In in = new In(args[0]);
133         int n = in.readInt();
134         Point[] points = new Point[n];
135 
136         for (int i = 0; i < n; i++) {
137             int x = in.readInt();
138             int y = in.readInt();
139             points[i] = new Point(x, y);
140         }
141 
142         // draw the points
143         StdDraw.enableDoubleBuffering();
144         StdDraw.setXscale(0, 32768);
145         StdDraw.setYscale(0, 32768);
146 
147         for (Point p : points) {
148             p.draw();
149         }
150 
151         StdDraw.show();
152 
153         // print and draw the line segments
154         FastCollinearPoints collinear = new FastCollinearPoints(points);
155 
156         for (LineSegment segment : collinear.segments()) {
157             StdOut.println(segment);
158             segment.draw();
159         }
160 
161         StdDraw.show();
162     }
163 
164     private class Node {
165         private LineSegment value;
166         private Node prev;
167     }
168 }
FastCollinearPoints

 

转载于:https://www.cnblogs.com/enigmaxp/p/5905658.html

这篇关于算法导论第四版学习——习题三Collinear Points的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/219994

相关文章

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖