您可以使用两点之间与Ox轴的角系数来解决这个问题。例如,对于3个点:A B C。只有当线段AB和线段AC与Ox线具有相同的角系数时,它们才共线。因此,这是我的伪代码:
List<Type> res = new ArrayList<Type>();
for (int i = 0; i < points.lenght(); i++) {
for (int j = i+1; j < points.length(); j++) {
double coefficient = CoeffiecientBetweenTwoLine(
line(points[i], points[j]), line((0,0), (0,1));
res.add(new Type(points[i], points[j], coefficient);
}
}
在此之后,您可以使用QuickSort在系数上再次排序以上List。 如果任何系数相等,则我们可以知道哪些点共线。 此算法的复杂度为
O(N ^ 2logN)
(由于对具有
O(N ^ 2)
元素的列表进行排序而主导,仅需
O(N ^ 2)
来构建列表)。
@ Edit:
那么,在显示相等的系数时,我们如何知道有多少点共线?
有很多方法可以解决这个问题。
- 在排序步骤中,当两个系数相等时,可以按第一个参数(表示该行中的哪个点)进行排序。例如,在排序后,结果应为(在这种情况下,如果1 3和4共线):
(1 3)
(1 4)
(3 4)
从上述构建中,您只需要查看1.的连续段。 在这个例子中,是2。 因此,结果应为3.(总是k + 1)
- 使用公式:因为相等的配对数量总是:
n *(n-1)/ 2
。 因此,您将拥有:
n *(n-1)/ 2 = 3
。 然后,您可以知道n = 3(n> = 0)。 这意味着您可以在这里解决二次方程(但不会太困难,因为您总是知道它有解,并且只需获得一个正解)
Edit 2
上述步骤用于确定有多少条共线点是不正确的,因为例如,A B和C D是两条平行线(线AB与CD线不同),结果,它们仍然具有与Ox相同的系数。 因此,我认为要解决这个问题,您可以使用Union-Find数据结构来解决此问题。 步骤将是:
重新排序角系数。例如:(1 2 3 4)是共线的,它们与(5,6,7)平行,而点8则位于其他位置。因此,在排序后,结果应为:
(1 2) (1 3) (1 4) (2 3) (2 4) (5 6) (5,7) (6,7) 角系数相等,但在两条不同的直线上
(1,5) (1, 6) .. //将有一些对连接在两组平行线之间。(1, 8)
(5, 8) (3, 8) .... //随机顺序。因为不知道。
使用并查集数据结构来连接树:从第二个元素开始迭代,如果看到它的角系数与前一个相等,则连接自身并连接前一个。例如,
(1,3) == (1,2):连接1和2,连接1和3。
(1,4) == (1,3):连接1和3,连接1和4。....
(5,6):连接2和4,连接5和6。
(5,7):连接5和7,连接5和6...
(1,8):不连接任何东西。(5,8):不连接任何东西...
完成这一步后,您拥有的是一个多树,在每棵树中,都有一组共线的点。
在上一步中,您会发现有些对被连接了多次。您可以通过标记来简单地修复这个问题,如果它们已经连接,则忽略以提高性能。
@:我认为这个解决方案不好,我只是凭借自己的思维方式做出来的,并没有真正的算法支持。因此,如果有任何其他清晰的想法,请告诉我。
return (y1 - y2) * (x1 - x3) = (y1 - y3) * (x1 - x2);
中存在问题,因为这是一个赋值语句,而不是比较语句。 - phuclv