对不起,如果标题有点尴尬,我不太清楚如何说出我的问题。
所以 - 我试图建立一个棋盘游戏,而我却试图以有效的方式检查棋盘上的区域之间的距离。
我有一个" Territory" class,它为游戏板上的每个tile创建一个Territory对象。每个Territory对象都有一个" String name"和"列表<串GT; adjacentTerritories"包含与其相邻的所有地区的名称。
我还有一个" HashMap<字符串,地区> territoriesMap",包含董事会的所有地区。
我提出作品的方式,但它是硬编码,用于检查远离最初的三个地区,并不是特别优雅。我想知道是否有办法更有效地完成这项任务,甚至可以让我对任何距离执行此检查?如果我在提出这个问题时犯了错误或错过了一些明显的答案,请原谅我,我大多是自学成才。
下面的这个函数包含我所有地区的HashMap以及它想要找到(源和目标)之间距离的两个地区。
public void checkDistance(String source, String target, HashMap<String, Territories> territoriesMap) {
int targetDistance = 0;
List<String> sourceAdj = territoriesMap.get(source).getAdjacentTerritory();
if (sourceAdj.contains(target)) { targetDistance = 1; }
else {
for (String adjacent1 : sourceAdj) {
List<String> nextAdj = territoriesMap.get(adjacent1).getAdjacentTerritory();
if (nextAdj.contains(target)) { targetDistance = 2; }
else {
for (String adjacent2 : nextAdj) {
List<String> lastAdj = territoriesMap.get(adjacent2).getAdjacentTerritory();
if (lastAdj.contains(target)) { targetDistance = 3; }
}
}
}
}
System.out.println(targetDistance);
我觉得我很接近,但我很难弄清楚如何精简这一点。任何帮助都会受到赞赏 - 甚至指向我阅读材料将是一个巨大的帮助。
答案 0 :(得分:2)
我们可以使用Breadth-First Search来计算这些距离。这是一个示例实现:
public int computeDistance(String source, String target, Map<String, Territory> territoriesMap) {
Queue<String> q = new ArrayDeque<>();
Map<String, Integer> dist = new HashMap<>();
q.add(source);
dist.put(source, 0);
while (!q.isEmpty()) {
Territory cur = territoriesMap.get(q.poll());
int curDist = dist.get(cur.getName());
for (String neighbor : cur.getAdjacentTerritories()) {
if (neighbor.equals(target))
return curDist + 1;
if (!dist.containsKey(neighbor)) {
dist.put(neighbor, curDist + 1);
q.add(neighbor);
}
}
}
return -1; // not connected by a path
}
请注意,通过少量修改(实际上是简化),我们可以找到从源到所有可到达目标的距离,如下所示:
public Map<String, Integer> computeAllDistances(String source, Map<String, Territory> territoriesMap) {
Queue<String> q = new ArrayDeque<>();
Map<String, Integer> dist = new HashMap<>();
q.add(source);
dist.put(source, 0);
while (!q.isEmpty()) {
Territory cur = territoriesMap.get(q.poll());
int curDist = dist.get(cur.getName());
for (String neighbor : cur.getAdjacentTerritories()) {
if (!dist.containsKey(neighbor)) {
dist.put(neighbor, curDist + 1);
q.add(neighbor);
}
}
}
return dist;
}