如果有人能帮我的话,我很惊讶:我正试图创建一段Java代码,找到一个点的最近两个点。以下是我目前掌握的情况:
import java.util.Random;
public class Main {
static int distance(int x1, int x2) {
return Math.round((x2 - x1) * (x2 - x1));
// Math.sqrt is the square root of the 2 co-ordinates
}
public static void main(String[] args) {
Random randomGenerator = new Random();
int x2, x1; // The Points
int distance;// The Math to work out distance
int randomInt2 = randomGenerator.nextInt(10) + 1;// For Length of array
int[] distances = new int[randomInt2];// The Array
int store;
x1 = 0;// used to calculate distance from original point to current point
System.out.println("Distance Generated for Point 1 : 0");// For First Point
int origin = 1;// increment which point start from
int range = 0;// Amount of Points
int point = 2;// Counts the number of points
while (range < randomInt2) {
int randomInt3 = randomGenerator.nextInt(10) + 2;// Distance for all points besides first
x2 = randomInt3;
distance = distance(x1, x2); // System.out.println("The distance between point 1 and point " +point+ " is " + distance + " .");
System.out.println("Distance from Point " + origin + " to Point " + point + " is distance = " + distance);
store = distance;// stores the distance to be put into array
point++;// increments the point number each time
distances[range] = store;
// System.out.println(" ,from Point " +point+" to Point "+origin+" = " + distance);
origin++;// Increments Original Point
range++;// increments amount of points each time
}
/*
* for (int val : distances) { System.out.println(val); }
*/
}
}
到目前为止,它创建了具有随机距离的点,我能够从上一个点中找到每个点的最近点。然而,我正试图使它,以便我可以使一种树结构,其中每个点有2个最接近的点分支离它很抱歉,如果我没有说清楚,但如果有人可以给我任何提示,他们将非常感谢。
最佳答案
很难猜到你想做什么根据我对你的问题的理解,你想在一条线上创建一些点(即一维点),并为每个点找到另外两个最近的点。
——————————————————————————————————————————--
对于直线上的这些点a-e,这将导致如下结果:
A的邻居是B和C。
B的邻居是A和C。
C的邻居是D和E。
D的邻居是C和E。
E的邻居是C和D。
但是,代码的结果如下:
A与B之间有距离D。
B与C之间有距离d。
C有d到d的距离。
D与E之间有距离D。
关于如何改进代码,已经有一些建议,我现在将添加这些建议,并列举一些其他建议。
你的确切问题是什么?
我们现在只能猜测,因为您的代码所做的与您的问题所读的完全不同再想一想,试着提出一些更清楚的问题。
试着思考面向对象
前面已经提到过:最好有一些类,至少是一个用于Point
s的类。也可以将distance
方法放入另一个类中,可能是某种数学库。
还要考虑可见性。包可见性(您的distance()
方法使用的)通常不是您想要的。
使用类可以使代码更加结构化,并且通常更容易扩展或增加一些可重用性。
变量名和代码样式
我们很难猜出你所说的range
、randomInt2
和store
是什么意思。如果你有一个合适的上下文,一个好的缩进和一些有意义的名字,我们可以更容易地猜测它的作用,即使评论更少。
另一个问题是你一次又一次地重用x2最终,你有一些距离,存储在你的距离数组中,但不知道它们属于哪个点——因为这些点不再存在。
解决问题
好吧,虽然你的问题不是最有帮助的,但我会尽力解决这个问题。
首先想到一个点类。我决定称它为Point1D
,以表明它可以很容易地扩展到Point2D
或Point3D
。
package sto;
public class Point1D {
private final double x; // this could also be a good public variable
private final String name;
public Point1D(double x, String name) {
this.x = x;
this.name = name;
}
public double distanceTo(Point1D other) {
return Math.abs(other.x - this.x);
}
}
根据您的需要,这可能是一个简单的
Point1D
类。它包含一个String name
、一个值(这里是double x
)以及计算这个Point1D
和另一个public double distanceTo(Point1D other)
之间距离的方法。在您的
Main
中,您现在可以创建任意数量的点,这些点很容易重用:package sto;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random rng = new Random();
// generate points
int numberOfPoints = rng.nextInt(10) + 1;
Point1D[] points = new Point1D[numberOfPoints];
for(int i = 0; i < numberOfPoints; ++i) {
points[i] = new Point1D(rng.nextDouble() * 10.0d, "Point " + i);
}
}
}
这将在
Point1D[] points
数组中创建1-10个点。注意命名:numberOfPoints
比randomInt2
更有意义。因为在main中有一个distance函数,所以我们也可以添加这个。请注意,我们现在使用的是公共可见性,因此可以从任何地方访问:
public static double distance(Point1D p1, Point1D p2) {
return p1.distanceTo(p2);
}
最好将这样的方法移到一个单独的类中,比如
MathUtil
。因为我已经创建了distanceTo(Point1D)
,所以现在不需要它。现在要为每个点找到两个最近的点。可能有比这一个更好的方法,但这一个做得很好:
for(int i = 0; i < numberOfPoints; ++i) {
Point1D currentPoint = points[i];
Point1D closestPoint = null;
Point1D secondClosestPoint = null;
for(int j = 0; j < numberOfPoints; ++j) {
if(i == j) continue;
if(closestPoint == null || currentPoint.distanceTo(points[j]) < currentPoint.distanceTo(closestPoint)) {
secondClosestPoint = closestPoint;
closestPoint = points[j];
} else if(secondClosestPoint == null || currentPoint.distanceTo(points[j]) < currentPoint.distanceTo(secondClosestPoint)) {
secondClosestPoint = points[j];
}
}
currentPoint.setNeighbors(closestPoint, secondClosestPoint);
}
首先定义最近点和第二最近点,并用空值初始化它们。然后我们比较当前点和其他点之间的距离,只要距离比当前最近的点更近,我们就指定它否则我们检查第二个最近点。注意
null
检查,这是为了避免空指针异常,并且(如果您说:嘿,我可以一直用points[0]
或points[j]
初始化它)您将距离与零距离(如果currentPoint
等于points[0]
或currentPoint
等于points[j]
)进行比较,或者您最初设置最接近点和第二接近点。还要注意,只有1个或2个生成的点,其中一个或两个邻居将
null
。最后一个方法调用
currentPoint.setNeighbors(closestPoint, secondClosestPoint);
对您来说是新的不知怎的你想把邻居都藏起来我只是决定将邻居存储在Point1D
对象本身中,而不是真正的树结构(在回答这个问题后,您应该能够使用现有的树结构来构建)为此,Point1D
类稍微改变了一点: /* extensions for your special case: two neighbors */
private Point1D neighbor1 = null;
private Point1D neighbor2 = null;
public void setNeighbors(Point1D p1, Point1D p2) {
neighbor1 = p1;
neighbor2 = p2;
}
public String toString() {
return "Point1D \"" + name + "\" at " + x + ", "
+ "Neighbors: " + (neighbor1 != null? neighbor1.name + " (" + distanceTo(neighbor1) + "), " : "")
+ (neighbor2 != null? neighbor2.name + " (" + distanceTo(neighbor2) + ")" : "");
}
Point1D得到两个简单成员和一个setter当然,您可以很容易地修改它,还可以使用getter等扩展它我还重载了
public String toString()
以便能够轻松打印Point1D
s。毕竟我们只需要打印它们,这只是另一个非常简单的for循环。
完整代码
主类
package sto;
import java.util.Random;
public class Main {
// better into a seperate MathLibrary
public static double distance(Point1D p1, Point1D p2) {
return p1.distanceTo(p2);
}
public static void main(String[] args) {
Random rng = new Random();
// generate points
int numberOfPoints = rng.nextInt(10) + 1;
Point1D[] points = new Point1D[numberOfPoints];
for(int i = 0; i < numberOfPoints; ++i) {
points[i] = new Point1D(rng.nextDouble() * 10.0d, "Point " + i);
}
for(int i = 0; i < numberOfPoints; ++i) {
Point1D currentPoint = points[i];
Point1D closestPoint = null;
Point1D secondClosestPoint = null;
for(int j = 0; j < numberOfPoints; ++j) {
if(i == j) continue;
if(closestPoint == null || currentPoint.distanceTo(points[j]) < currentPoint.distanceTo(closestPoint)) {
secondClosestPoint = closestPoint;
closestPoint = points[j];
} else if(secondClosestPoint == null || currentPoint.distanceTo(points[j]) < currentPoint.distanceTo(secondClosestPoint)) {
secondClosestPoint = points[j];
}
}
currentPoint.setNeighbors(closestPoint, secondClosestPoint);
}
for(int i = 0; i < numberOfPoints; ++i)
System.out.println(points[i]);
}
}
点1d.java
package sto;
public class Point1D {
private final double x; // this could also be a good public variable
private final String name;
public Point1D(double x, String name) {
this.x = x;
this.name = name;
}
public double distanceTo(Point1D other) {
return Math.abs(other.x - this.x);
}
/* extensions for your special things: 2 neighbors */
private Point1D neighbor1 = null;
private Point1D neighbor2 = null;
public String toString() {
return "Point1D \"" + name + "\" at " + x + ", "
+ "Neighbors: " + (neighbor1 != null? neighbor1.name + " (" + distanceTo(neighbor1) + "), " : "")
+ (neighbor2 != null? neighbor2.name + " (" + distanceTo(neighbor2) + ")" : "");
}
public void setNeighbors(Point1D p1, Point1D p2) {
neighbor1 = p1;
neighbor2 = p2;
}
}
示例输出
有1个生成点:
Point1D "Point 0" at 6.420136069230588, Neighbors:
有2个生成点:
Point1D "Point 0" at 5.944088209230237, Neighbors: Point 1 (0.43915003704614364),
Point1D "Point 1" at 6.383238246276381, Neighbors: Point 0 (0.43915003704614364),
2分以上:
Point1D "Point 0" at 8.843803983191671, Neighbors: Point 8 (1.1272536955360408), Point 3 (1.561097922588882)
Point1D "Point 1" at 5.769064395124087, Neighbors: Point 9 (0.2901718634798556), Point 3 (1.5136416654787022)
Point1D "Point 2" at 3.1745401994446834, Neighbors: Point 7 (0.23098459949774464), Point 5 (0.2711748146393602)
Point1D "Point 3" at 7.28270606060279, Neighbors: Point 9 (1.2234698019988466), Point 1 (1.5136416654787022)
Point1D "Point 4" at 1.3174388168729179, Neighbors: Point 5 (1.5859265679324053), Point 7 (1.6261167830740209)
Point1D "Point 5" at 2.903365384805323, Neighbors: Point 7 (0.04019021514161558), Point 2 (0.2711748146393602)
Point1D "Point 6" at 3.8143932773804448, Neighbors: Point 2 (0.6398530779357614), Point 7 (0.870837677433506)
Point1D "Point 7" at 2.9435555999469387, Neighbors: Point 5 (0.04019021514161558), Point 2 (0.23098459949774464)
Point1D "Point 8" at 9.971057678727712, Neighbors: Point 0 (1.1272536955360408), Point 3 (2.6883516181249227)
Point1D "Point 9" at 6.059236258603943, Neighbors: Point 1 (0.2901718634798556), Point 3 (1.2234698019988466)
锻炼
尝试对点2d和点3d实现此功能,在单独的
public static double distance(PointND p1, PointND p2)
中使用MathUtil.java
。