我是二维数组,我在其中存储了一些点,以便得到最近的两个点,例如: "( - 1,3),( - 1,-1),(1,1),(2,0.5),(2,-1),(3,3),(4, 2),(4,0.5)" 结果是:"(1.0,1.0)和(2.0,0.5)" 这非常有效:
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the number of points");
int numberOfPoints = scanner.nextInt();
//setting number of rows, number of column is unable to change
double[][] points = new double[numberOfPoints][2];
for (int i = 0; i < points.length; i++) {
points[i][0] = scanner.nextDouble();
points[i][1] = scanner.nextDouble();
}
int point1 = 0, point2 = 1;
double shortestDistance = distance(points[point1][0], points[point1][1],
points[point2][0], points[point2][1]);
//get shortest distance
for (int i = 0; i < points.length; i++) {
for (int j = i + 1; j < points.length; j++) {
double distance = distance(points[i][0], points[i][1],
points[j][0], points[j][1]);
if (shortestDistance > distance) {
point1 = i;
point2 = j;
shortestDistance = distance;
}
}
}
System.out.println("The closest two points is" +
"(" + points[point1][0] + ", " + points[point1][1] + ") and (" +
points[point2][0] + ", " + points[point2][1] + ")");
}
public static double distance(double x1, double y1, double x2, double y2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
我试图获得所有最近的点不仅仅是两点。
我试图通过这种方式获得它,但它并不涵盖所有情况并且不会显示所有点:
for (int i = 0; i < points.length; i++) {
for (int j = 0; j < points.length; j++) {
if (distance(points[i][0], points[i][1],
points[j][0], points[j][1]) == shortestDistance)
System.out.println("The closest two points are " +
"(" + points[i][0] + ", " + points[i][1] + ") and (" +
points[j][0] + ", " + points[j][1] + ")");
}
}
此外,我尝试初始化新阵列并将距离存储到其中然后对其进行排序,但它失败了。
我如何显示所有最近点?
注意:
我没有发现this question对我有用。
答案 0 :(得分:0)
以下comment阐明了问题的实际目标:
所以你的意思是,当你找到彼此最接近的2个点(
(1.0, 1.0) - (2.0, 0.5)
)时,你想要消除它们然后找到下一个&#34;对&#34;那些现在彼此最接近((3.0, 3.0) - (4.0, 2.0)
),然后重复((2.0, -1.0) - (4.0, 0.5)
),最后得到最后一对((-1.0, 3.0) - (-1.0, -1.0)
)?
为此,您应首先创建一个Point
类,以便轻松跟踪已使用过的点。如果您不想自己编写,可以使用java.awt.geom.Point2D.Double
。
您还应该创建一个用于跟踪点对的类,以便您可以轻松地按距离对对进行排序。它可以命名为任何名称,但我将其命名为Distance
。
现在的逻辑是你创建一个包含所有可能的Distance
个对象的列表,即成对的点。然后按距离对其进行排序。
第一个列表元素现在是彼此最近的一对。然后迭代列表以找到最接近的下一对点,跳过任何使用已使用点的点。
如果多于一对并且#34;最接近&#34;,则下面的逻辑将选择其中一个。一旦定义了该场景中应该发生的事情,您就可以更改该行为。
public static void main(String[] args) {
double[][] pointValues = { {-1, 3}, {-1, -1}, {1, 1}, {2, 0.5}, {2, -1}, {3, 3}, {4, 2}, {4, 0.5} };
Point[] points = new Point[pointValues.length];
for (int i = 0; i < points.length; i++)
points[i] = new Point(pointValues[i][0], pointValues[i][1]);
List<Distance> distances = new ArrayList<>();
for (int i = 0; i < points.length; i++)
for (int j = i + 1; j < points.length; j++)
distances.add(new Distance(points[i], points[j]));
Collections.sort(distances);
Set<Point> used = new HashSet<>();
for (Distance distance : distances) {
if (! used.contains(distance.getPoint1()) && ! used.contains(distance.getPoint2())) {
System.out.println(distance);
used.add(distance.getPoint1());
used.add(distance.getPoint2());
}
}
}
public final class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
@Override
public String toString() {
return "(" + this.x + ", " + this.y + ")";
}
@Override
public int hashCode() {
return Double.hashCode(this.x) * 31 + Double.hashCode(this.y);
}
@Override
public boolean equals(Object obj) {
if (! (obj instanceof Point))
return false;
Point that = (Point) obj;
return (Double.doubleToLongBits(this.x) == Double.doubleToLongBits(that.x)
&& Double.doubleToLongBits(this.y) == Double.doubleToLongBits(that.y));
}
}
public final class Distance implements Comparable<Distance> {
private final Point p1;
private final Point p2;
private final double distance;
public Distance(Point p1, Point p2) {
this.p1 = p1;
this.p2 = p2;
this.distance = Math.hypot(p2.getX() - p1.getX(), p2.getY() - p1.getY());
}
public Point getPoint1() {
return this.p1;
}
public Point getPoint2() {
return this.p2;
}
public double getDistance() {
return this.distance;
}
@Override
public String toString() {
return String.format("%-12s - %-12s: %s", this.p1, this.p2, this.distance);
}
@Override
public int compareTo(Distance that) {
return Double.compare(this.distance, that.distance);
}
}
输出
(1.0, 1.0) - (2.0, 0.5) : 1.118033988749895
(3.0, 3.0) - (4.0, 2.0) : 1.4142135623730951
(2.0, -1.0) - (4.0, 0.5) : 2.5
(-1.0, 3.0) - (-1.0, -1.0): 4.0
答案 1 :(得分:-1)
首先是一个优化技巧:代替距离,使用它的方块(掉根)。
public static double distance2(double x1, double y1, double x2, double y2) {
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
}
取所有最近的点需要维护一个(i,j)列表。
List<int[]> nearestPointIndices = new ArrayList<>();
double shortestDistance2 = Double.MAX_VALUE;
for (int i = 0; i < points.length; i++) {
for (int j = i + 1; j < points.length; j++) {
double distance2 = distance2(points[i][0], points[i][1],
points[j][0], points[j][1]);
if (shortestDistance2 >= distance2) {
if (shortestDistance2 > distance2) {
nearestPointIndices.clear();
shortestDistance2 = distance2;
}
nearestPointIndices.add(new int[] { i, j });
}
}
}
那是一个收集最近点(i,j)和最近点的列表 要么在更近点清除该列表,要么在相同的近点清除列表。
另外值得一提的是另一个Math类的功能,如sqrt:
public static double distance(double x1, double y1, double x2, double y2) {
return Math.hypot((x2 - x1), (y2 - y1)); // Hypotenuse sqrt(a² + b²).
}