原题目:Programming Assignment 3: Pattern Recognition
题目给定n个二维平面点,搜索能够连成线的大于等于四个点的集合。需要分别实现三个类,点的类,暴力搜索,快速搜索。
点的类需要实现根据点的坐标比较以及两个点根据某个点的斜率的比较。
暴力搜索和快速搜索均需要实现寻找点的功能。
主要是分析如何实现暴力搜索和快速搜索。
这个一开始读题我还没读懂,还以为只会给四个点,要求判断是否共线。
题目要求的性能是n^4,明显就是四重循环,建立一个比较斜率的比较器,第二重和第三重循环的点相对于第一重循环的斜率比较,若相同,则说明这三点共线,再去第四重循环寻找最后一个点。
这道题的思路在题目里已经很清晰了,就是计算每一个点和其他点的斜率,然后按照斜率排序,寻找其中斜率相同的部分,若大于等于4个,就是满足题目要求的共线。
由于写了比较器,可以不计算斜率,直接在sort时送入参数即可。这时我是将计算斜率的参考点和相同的点最后一个相连,这个思路是错误的。
按上面做完确实可以找到所有共线的点了,但是解是错误的,若这条线上有超过4个点,就会有重复的线段出现。甚至有的线段长度都小于4。
怎么解决这个问题呢?
这时候想到Arrays提供的sort是稳定的,我们最初的point数组是根据点的坐标大小进行排序的,然后又根据斜率进行排序。
因为排序是稳定的,所以同斜率中,第一个肯定时坐标最小的点,即起点,只需要比较计算斜率的参考点和同斜率中第一个点谁小就可以判断参考点是不是起点了。就实现了去重。
提交答案时,除了api以外的函数,如果设置为public,直接就0分。实际写程序中,对于public和private考虑的比较少。要思考那些不应该被client访问,那些一定要设置成private。
1.普林斯顿大学算法Week3:CollinearPoints共线模式识别(99分)--总结及代码
2.Coursera Algorithms Programming Assignment 3: Pattern Recognition (100分)