2.5.25 #
解答 #
官方解答见:https://algs4.cs.princeton.edu/25applications/Point2D.java.html
这些比较器都以嵌套类的形式在 Point2D
中定义。
静态比较器直接在类中以静态成员的方式声明。
非静态比较器则需要提供工厂方法,该方法新建并返回对应的比较器对象。
代码 #
/// <summary>
/// 按照 X 顺序比较。
/// </summary>
private class XOrderComparer : Comparer<Point2D>
{
public override int Compare(Point2D x, Point2D y)
{
if (x.X < y.X)
{
return -1;
}
if (x.X > y.X)
{
return 1;
}
return 0;
}
}
/// <summary>
/// 按照 Y 顺序比较。
/// </summary>
private class YOrderComparer : Comparer<Point2D>
{
public override int Compare(Point2D x, Point2D y)
{
if (x.Y < y.Y)
{
return -1;
}
if (x.Y > y.Y)
{
return 1;
}
return 0;
}
}
/// <summary>
/// 按照极径顺序比较。
/// </summary>
private class ROrderComparer : Comparer<Point2D>
{
public override int Compare(Point2D x, Point2D y)
{
var delta = (x.X * x.X + x.Y * x.Y) - (y.X * y.X + y.Y * y.Y);
if (delta < 0)
{
return -1;
}
if (delta > 0)
{
return 1;
}
return 0;
}
}
/// <summary>
/// 按照 atan2 值顺序比较。
/// </summary>
private class Atan2Order : Comparer<Point2D>
{
private readonly Point2D _parent;
public Atan2Order(Point2D parent)
{
_parent = parent;
}
public override int Compare(Point2D x, Point2D y)
{
var angle1 = _parent.AngleTo(x);
var angle2 = _parent.AngleTo(y);
if (angle1 < angle2)
{
return -1;
}
if (angle1 > angle2)
{
return 1;
}
return 0;
}
}
/// <summary>
/// 按照极角顺序比较。
/// </summary>
private class PolarOrder : Comparer<Point2D>
{
private readonly Point2D _parent;
public PolarOrder(Point2D parent)
{
_parent = parent;
}
public override int Compare(Point2D q1, Point2D q2)
{
var dx1 = q1.X - _parent.X;
var dy1 = q1.Y - _parent.Y;
var dx2 = q2.X - _parent.X;
var dy2 = q2.Y - _parent.Y;
if (dy1 >= 0 && dy2 < 0)
{
return -1;
}
if (dy2 >= 0 && dy1 < 0)
{
return 1;
}
if (dy1 == 0 && dy2 == 0)
{
if (dx1 >= 0 && dx2 < 0)
{
return -1;
}
if (dx2 >= 0 && dx1 < 0)
{
return 1;
}
return 0;
}
return -Ccw(_parent, q1, q2);
}
}