【发布时间】:2023-03-15 10:42:01
【问题描述】:
虽然国际象棋规则不允许国王互相威胁,但这对于真正的问题来说是一个很好的几何类比。
给定以下几何形状
K1 [] [] [] []
K2 K3 [] [] []
[] K4 [] K5 []
所需算法的结果应该是具有以下条目的数据结构:[K1, K2], [K1, K3], [K2, K3], [K2, K4], [K3, K4]。
- 条目中的顺序无关紧要,因此
[Kx, Ky]与[Ky, Kx]相同。 - 数据结构中的条目不需要排序。
- 国王有 0 到 8 个相邻的国王。
存在以下代码:
class King {
Point location; // Point contains x and y fields corresponding to the grid
Point getLocation() { return location; }
}
class Square {
Point location;
Point getLocation() { return location; }
King king; // null if there is no King in the square
King getKing() { return king; }
}
还有实用方法
static List<Square> getThreatenedSquares(Point location) { ... }
返回与给定坐标相邻的 8 个Squares。以上都不是必须使用的,它只是可用的。
输入是Collection<King> kingsColl,包含所有棋盘上没有相关顺序的K(它是LinkedHashMap#values())。换句话说,我当前的非流算法遍历所有国王,对于每一个国王,它都会查看所有尚未查看的国王,并检查匹配条件。
List<King> kings = new ArrayList<>(kingsColl);
if (kings.size() > 1) {
Map<King, King> conflicts = new HashMap<>();
for (int i = 0; i < kings.size() - 1; i++) { // if the last king has a conflict, it would show up in the other king
King k1 = kings.get(i);
Point loc1 = k1.getLocation();
List<Square> adj = getThreatenedSquares(loc1);
for (int j = i + 1; j < kings.size(); j++) { // avoids duplicates Kx <-> ky
King k2 = kings.get(j);
Point loc2 = k2.getLocation();
for (Square sqr : adj) { // check for adjacency
if (sqr.getLocation().equals(loc2)) {
conflicts.put(k1, k2);
}
}
}
}
}
这个算法很糟糕,因为它依赖于索引并且需要创建一个索引访问集合,它不能被并行化,并且它进行的检查超出了它的需要。请注意,这里的结果存储在 Map 中,但任何对的集合都可以(包括 Guava)。
我尝试了一些使用流的想法,但我都不想发布,因为它们一团糟(如果有人不相信我会发布常见的“你试过什么?”)。流倾向于解决上述问题,因为它们是独立于实现的。如何使用流实现此算法?
【问题讨论】:
-
你有什么问题?
-
@Code-Apprentice 标题中的那个。我也把它复制到底部。
-
@maraca 已修复,但是该方法确实指定了 8。
标签: java algorithm java-stream