如何遍历点 (x, y) 上的有序方向?
How to iterate over ordinal directions over a point (x, y)?
下面这个函数叫做 findNeighboringChains(i, j)。你传入一个点 (x, y),它 returns 存在于相邻点 (x + 1, y), (x - 1, y), (x, y + 1) 中的所有链对象, 和 (x, y - 1)。如果 (x, y) 处不存在链,则 findChainId(x, y) = -1,否则它将 return ID >= 0。每个 (x, y) 处只能存在一条链。有关更多上下文,这是我用来在围棋游戏中查找单元格的相邻链的函数。
我觉得到目前为止我的内容有点冗长,但我不确定如何让它变得更好。如果我可以通过循环迭代这些点 (x + 1, y) ... (x, y - 1) 似乎是理想的。有什么建议吗?
public ArrayList<Integer> findNeighboringChains(int i, int j) {
ArrayList<Integer> neighboringChains = new ArrayList<>();
int tmp = findChainId(i - 1, j);
if (tmp != -1) {
neighboringChains.add(tmp);
}
tmp = findChainId(i + 1, j);
if (tmp != -1) {
neighboringChains.add(tmp);
}
tmp = findChainId(i, j - 1);
if (tmp != -1) {
neighboringChains.add(tmp);
}
tmp = findChainId(i, j + 1);
if (tmp != -1) {
neighboringChains.add(tmp);
}
return neighboringChains;
}
一种方法是利用 Java 中内置的 Point 对象,并遍历点列表 - 每次调用相同的代码段。在我的 solution/refactoring 中,我创建了一个名为 "getNeighboringPoints(Point p)" 的新方法,用于检索四个相邻点。然后,在您的函数 findNeighboringChains 中,您可以使用 for-each 循环遍历该点列表。
您可以对这种模式进行多种变体,但您认为可以减少冗余的想法绝对是正确的。尝试遵循 DRY 原则总是一个好主意。
public ArrayList<Integer> findNeighboringChains(int i, int j) {
ArrayList<Integer> neighboringChains = new ArrayList<>();
Point p = new Point(i, j);
List<Point> neighboringPoints = getNeighboringPoints(p);
for (Point point : neighboringPoints) {
int tmp = findChainId(point.x, point.y);
if (tmp != -1) {
neighboringChains.add(tmp);
}
}
return neighboringChains;
}
/**
*
* @param p
* The input point.
* @return a list of points neighboring point p
*/
private List<Point> getNeighboringPoints(Point p) {
ArrayList<Point> neighboringPoints = new ArrayList<Point>();
neighboringPoints.add(new Point(p.x - 1, p.y));
neighboringPoints.add(new Point(p.x + 1, p.y));
neighboringPoints.add(new Point(p.x, p.y + 1));
neighboringPoints.add(new Point(p.x, p.y - 1));
return neighboringPoints;
}
上述方法的一个好处是,现在您可以稍后发现您可能需要对所有相邻点进行另一次操作,并且您可以重用方法 getNeighboringPoints()。
编辑:
另一种减少冗余的方法是使用 extract method 技术。
public ArrayList<Integer> findNeighboringChains(int i, int j) {
ArrayList<Integer> neighboringChains = new ArrayList<>();
int tmp = findChainId(i - 1, j);
checkChain(neighboringChains, tmp);
tmp = findChainId(i + 1, j);
checkChain(neighboringChains, tmp);
tmp = findChainId(i, j - 1);
checkChain(neighboringChains, tmp);
tmp = findChainId(i, j + 1);
checkChain(neighboringChains, tmp);
return neighboringChains;
}
private void checkChain(ArrayList<Integer> neighboringChains, int tmp) {
if (tmp != -1) {
neighboringChains.add(tmp);
}
}
这可能会更好,因为它不会强制在尚未使用积分的项目上使用积分 class。 (当有一种方法使用点而其他所有方法都需要输入两个整数时,这可能会很烦人)。
下面这个函数叫做 findNeighboringChains(i, j)。你传入一个点 (x, y),它 returns 存在于相邻点 (x + 1, y), (x - 1, y), (x, y + 1) 中的所有链对象, 和 (x, y - 1)。如果 (x, y) 处不存在链,则 findChainId(x, y) = -1,否则它将 return ID >= 0。每个 (x, y) 处只能存在一条链。有关更多上下文,这是我用来在围棋游戏中查找单元格的相邻链的函数。
我觉得到目前为止我的内容有点冗长,但我不确定如何让它变得更好。如果我可以通过循环迭代这些点 (x + 1, y) ... (x, y - 1) 似乎是理想的。有什么建议吗?
public ArrayList<Integer> findNeighboringChains(int i, int j) {
ArrayList<Integer> neighboringChains = new ArrayList<>();
int tmp = findChainId(i - 1, j);
if (tmp != -1) {
neighboringChains.add(tmp);
}
tmp = findChainId(i + 1, j);
if (tmp != -1) {
neighboringChains.add(tmp);
}
tmp = findChainId(i, j - 1);
if (tmp != -1) {
neighboringChains.add(tmp);
}
tmp = findChainId(i, j + 1);
if (tmp != -1) {
neighboringChains.add(tmp);
}
return neighboringChains;
}
一种方法是利用 Java 中内置的 Point 对象,并遍历点列表 - 每次调用相同的代码段。在我的 solution/refactoring 中,我创建了一个名为 "getNeighboringPoints(Point p)" 的新方法,用于检索四个相邻点。然后,在您的函数 findNeighboringChains 中,您可以使用 for-each 循环遍历该点列表。
您可以对这种模式进行多种变体,但您认为可以减少冗余的想法绝对是正确的。尝试遵循 DRY 原则总是一个好主意。
public ArrayList<Integer> findNeighboringChains(int i, int j) {
ArrayList<Integer> neighboringChains = new ArrayList<>();
Point p = new Point(i, j);
List<Point> neighboringPoints = getNeighboringPoints(p);
for (Point point : neighboringPoints) {
int tmp = findChainId(point.x, point.y);
if (tmp != -1) {
neighboringChains.add(tmp);
}
}
return neighboringChains;
}
/**
*
* @param p
* The input point.
* @return a list of points neighboring point p
*/
private List<Point> getNeighboringPoints(Point p) {
ArrayList<Point> neighboringPoints = new ArrayList<Point>();
neighboringPoints.add(new Point(p.x - 1, p.y));
neighboringPoints.add(new Point(p.x + 1, p.y));
neighboringPoints.add(new Point(p.x, p.y + 1));
neighboringPoints.add(new Point(p.x, p.y - 1));
return neighboringPoints;
}
上述方法的一个好处是,现在您可以稍后发现您可能需要对所有相邻点进行另一次操作,并且您可以重用方法 getNeighboringPoints()。
编辑:
另一种减少冗余的方法是使用 extract method 技术。
public ArrayList<Integer> findNeighboringChains(int i, int j) {
ArrayList<Integer> neighboringChains = new ArrayList<>();
int tmp = findChainId(i - 1, j);
checkChain(neighboringChains, tmp);
tmp = findChainId(i + 1, j);
checkChain(neighboringChains, tmp);
tmp = findChainId(i, j - 1);
checkChain(neighboringChains, tmp);
tmp = findChainId(i, j + 1);
checkChain(neighboringChains, tmp);
return neighboringChains;
}
private void checkChain(ArrayList<Integer> neighboringChains, int tmp) {
if (tmp != -1) {
neighboringChains.add(tmp);
}
}
这可能会更好,因为它不会强制在尚未使用积分的项目上使用积分 class。 (当有一种方法使用点而其他所有方法都需要输入两个整数时,这可能会很烦人)。