如何获取从固定点到特定距离的坐标邻居
How to get coordinate neighbors from a fixed point to a specific distance
我的任务是实现 GetNeighbors 方法,该方法 returns 来自一组点,仅是具有整数坐标 x 和 y 的点的 h 邻点。 (阅读代码中的摘要以获得更多理解)
其实我和这个人有同样的任务,但是那里的答案好像不行。我想只用循环来做这件事,我想我应该这样 :)>.
现在我的代码:
/// <summary>
/// Gets from a set of points only points that are h-neighbors for a point with integer coordinates x and y.
/// </summary>
/// <param name="point">Given point with integer coordinates x and y.</param>
/// <param name="h">Distance around a given point.</param>
/// <param name="points">A given set of points.</param>
/// <returns>Only points that are h-neighbors for a point with integer coordinates x and y.</returns>
/// <exception cref="ArgumentNullException">Throw when array points is null.</exception>
/// <exception cref="ArgumentException">Throw when h-distance is less or equals zero.</exception>
public static Point[] GetNeighbors(Point point, int h, params Point[] points)
{
if (points is null)
{
throw new ArgumentNullException(nameof(points));
}
if (h <= 0)
{
throw new ArgumentException(null);
}
List<Point> neighbors = new List<Point>();
int left = point.X - h;
int right = point.X + h;
int bottom = point.Y - h;
int top = point.Y + h;
for (int y = top; y <= bottom; y++)
{
for (int x = left; x <= right; x++)
{
// Yeah...
}
}
return neighbors.ToArray();
}
到目前为止,我所做的就是找到附近的上、下、左、右边界。我认为我只需要做的是一个 if 语句,它可以比较我拥有的点和来自点数组的点。嗯,怎么办,我不太熟悉使用结构体,每次都是失败。
结构点是这样构建的:
/// <summary>
/// Represents a point on the coordinate plane.
/// </summary>
public readonly struct Point : System.IEquatable<Point>
{
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
public int X { get; }
public int Y { get; }
public static bool operator ==(Point left, Point right)
{
return left.Equals(right);
}
public static bool operator !=(Point left, Point right)
{
return !(left == right);
}
public override int GetHashCode()
{
return this.X.GetHashCode() ^ this.Y.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj is null)
{
return false;
}
if (!(obj is Point))
{
return false;
}
if (obj.GetType() != this.GetType())
{
return false;
}
Point point = (Point)obj;
return this.Equals(point);
}
public bool Equals(Point other)
{
return this.X == other.X && this.Y == other.Y;
}
}
你不能遍历坐标,而是遍历点。这是一个使用 LINQ 的解决方案:
public static Point[] GetNeighbors(Point point, int h, params Point[] points)
{
int minX = point.X - h;
int maxX = point.X + h;
int minY = point.Y - h;
int maxY = point.Y + h;
return points
.Where(p => p.X >= minX && p.X <= maxX && p.Y >= minY && p.Y <= maxY)
.ToArray();
}
使用 C# 9.0,您可以通过模式匹配简化比较
.Where(p => p.X is >=minX and <=maxX && p.Y is >=minY and <=maxY)
这是一个使用显式循环的解决方案。由于我们不知道结果数组的大小,我将结果存储在列表中:
...
var list = new List<Point>();
foreach (Point p in points) {
if (p.X is >=minX and <=maxX && p.Y is >=minY and <=maxY) {
list.Add(p);
}
}
return list.ToArray();
或者您可以 return 一个列表。
另一种解决方案是使用 iterator method:
public static IEnumerable<Point> GetNeighbors(Point point, int h, params Point[] points)
{
int minX = point.X - h;
int maxX = point.X + h;
int minY = point.Y - h;
int maxY = point.Y + h;
foreach (Point p in points) {
if (p.X is >=minX and <=maxX && p.Y is >=minY and <=maxY) {
yield return p;
}
}
}
请注意,此方法不会将点存储在集合中,而是在循环结果时执行方法内的循环(显式地在 foreach 循环中或隐式地应用 .ToArray()
或.Count()
等等)。
Point[] result = GetNeighbors(center, 2, p1, p2, p3, p4).ToArray();
我的任务是实现 GetNeighbors 方法,该方法 returns 来自一组点,仅是具有整数坐标 x 和 y 的点的 h 邻点。 (阅读代码中的摘要以获得更多理解)
其实我和这个人有同样的任务
现在我的代码:
/// <summary>
/// Gets from a set of points only points that are h-neighbors for a point with integer coordinates x and y.
/// </summary>
/// <param name="point">Given point with integer coordinates x and y.</param>
/// <param name="h">Distance around a given point.</param>
/// <param name="points">A given set of points.</param>
/// <returns>Only points that are h-neighbors for a point with integer coordinates x and y.</returns>
/// <exception cref="ArgumentNullException">Throw when array points is null.</exception>
/// <exception cref="ArgumentException">Throw when h-distance is less or equals zero.</exception>
public static Point[] GetNeighbors(Point point, int h, params Point[] points)
{
if (points is null)
{
throw new ArgumentNullException(nameof(points));
}
if (h <= 0)
{
throw new ArgumentException(null);
}
List<Point> neighbors = new List<Point>();
int left = point.X - h;
int right = point.X + h;
int bottom = point.Y - h;
int top = point.Y + h;
for (int y = top; y <= bottom; y++)
{
for (int x = left; x <= right; x++)
{
// Yeah...
}
}
return neighbors.ToArray();
}
到目前为止,我所做的就是找到附近的上、下、左、右边界。我认为我只需要做的是一个 if 语句,它可以比较我拥有的点和来自点数组的点。嗯,怎么办,我不太熟悉使用结构体,每次都是失败。
结构点是这样构建的:
/// <summary>
/// Represents a point on the coordinate plane.
/// </summary>
public readonly struct Point : System.IEquatable<Point>
{
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
public int X { get; }
public int Y { get; }
public static bool operator ==(Point left, Point right)
{
return left.Equals(right);
}
public static bool operator !=(Point left, Point right)
{
return !(left == right);
}
public override int GetHashCode()
{
return this.X.GetHashCode() ^ this.Y.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj is null)
{
return false;
}
if (!(obj is Point))
{
return false;
}
if (obj.GetType() != this.GetType())
{
return false;
}
Point point = (Point)obj;
return this.Equals(point);
}
public bool Equals(Point other)
{
return this.X == other.X && this.Y == other.Y;
}
}
你不能遍历坐标,而是遍历点。这是一个使用 LINQ 的解决方案:
public static Point[] GetNeighbors(Point point, int h, params Point[] points)
{
int minX = point.X - h;
int maxX = point.X + h;
int minY = point.Y - h;
int maxY = point.Y + h;
return points
.Where(p => p.X >= minX && p.X <= maxX && p.Y >= minY && p.Y <= maxY)
.ToArray();
}
使用 C# 9.0,您可以通过模式匹配简化比较
.Where(p => p.X is >=minX and <=maxX && p.Y is >=minY and <=maxY)
这是一个使用显式循环的解决方案。由于我们不知道结果数组的大小,我将结果存储在列表中:
...
var list = new List<Point>();
foreach (Point p in points) {
if (p.X is >=minX and <=maxX && p.Y is >=minY and <=maxY) {
list.Add(p);
}
}
return list.ToArray();
或者您可以 return 一个列表。
另一种解决方案是使用 iterator method:
public static IEnumerable<Point> GetNeighbors(Point point, int h, params Point[] points)
{
int minX = point.X - h;
int maxX = point.X + h;
int minY = point.Y - h;
int maxY = point.Y + h;
foreach (Point p in points) {
if (p.X is >=minX and <=maxX && p.Y is >=minY and <=maxY) {
yield return p;
}
}
}
请注意,此方法不会将点存储在集合中,而是在循环结果时执行方法内的循环(显式地在 foreach 循环中或隐式地应用 .ToArray()
或.Count()
等等)。
Point[] result = GetNeighbors(center, 2, p1, p2, p3, p4).ToArray();