Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从映射添加到堆栈_Java_Map_Stack_Shortest Path - Fatal编程技术网

Java 从映射添加到堆栈

Java 从映射添加到堆栈,java,map,stack,shortest-path,Java,Map,Stack,Shortest Path,我正在为学校做一个项目,要求我们找到两点之间的最短路径。基本上,我使用广度优先搜索遍历图形,然后使用地图跟踪每个城市。我的想法是,当我到达终点时,我将使用边缘地图找出一个城市是如何到达的,并且基本上是反向工作的。然而,当我试图从映射中提取值时,我得到的结果都是空的,即使当我打印出内容时,它也会显示其中有一些内容。如果有人能帮我找出这个问题,我将不胜感激 每个城市及其邻居的输入文件内容: basic Bismark Fargo Minneapolis Chicago StPaul

我正在为学校做一个项目,要求我们找到两点之间的最短路径。基本上,我使用广度优先搜索遍历图形,然后使用地图跟踪每个城市。我的想法是,当我到达终点时,我将使用边缘地图找出一个城市是如何到达的,并且基本上是反向工作的。然而,当我试图从映射中提取值时,我得到的结果都是空的,即使当我打印出内容时,它也会显示其中有一些内容。如果有人能帮我找出这个问题,我将不胜感激

每个城市及其邻居的输入文件内容:

basic
Bismark      Fargo
Minneapolis  Chicago
StPaul       Chicago
Minneapolis  StPaul
Minneapolis  Fargo
Fargo        GrandForks
代码(已更正的版本,因此此代码不再显示所描述的问题):

import java.util.*;
导入java.io.*;
公共类BFSBasics{
公共静态void main(字符串[]args)引发FileNotFoundException{
映射图=新的HashMap();
openFile(图形,参数[0]);
字符串开始=args[1];
字符串结束=args[2];
BFS(图形、开始、结束);
}
公共静态void openFile(映射图,
字符串文件)
抛出FileNotFoundException{
Map aGraph=newhashmap();
尝试(扫描程序扫描=新扫描程序(新文件))){
如果(!scan.next().equals(“basic”)){
System.err.println(“无法读取文件”);
系统出口(1);
}否则{
while(scan.hasNext()){
字符串city1=scan.next();
字符串city2=scan.next();
附录(图表,城市1,城市2);
附录(图表,城市2,城市1);
}   
}   
}
}
专用静态void addEdge(映射图,字符串city1,
字符串(城市2){
列表相邻=graph.get(city1);
如果(相邻==null){
相邻=新的ArrayList();
图1.put(城市1,相邻);
}
添加(城市2);
}
公共静态void BFS(映射图、字符串开始、,
字符串结束){
布尔完成=假;
//仍然需要改进的城市
队列工作=新建ArrayQue();
//已经看到的城市
Set seen=新的HashSet();
//例如,它是如何实现的
映射边=新的HashMap();
LinkedList路径=新建LinkedList();
字符串city=start;
工作。添加(开始);
而(!done&!work.isEmpty()){
城市=工作。删除();
for(字符串s:graph.get(城市)){
如果(!seen.contains){
(s,城市);;
工作。添加(s);
见。添加(s);
如果(s.等于(结束)){
完成=正确;
}
}
}
}
//向后遍历边贴图并推到路径堆栈上
路径。推(结束);
字符串温度=边。获取(结束);
而(!temp.equals(start)){
路径推送(温度);
temp=edges.get(path.peek()};
}
路径推送(启动);
//打印出路径
而(!path.isEmpty()){
System.out.println(path.pop());
}
}
}

路径构建代码有问题:

path.push(end);                 // push node (n - 1)
String temp = edges.get(end);   // temp = node (n - 2)
while(!temp.equals(start)){
    path.push(edges.get(temp)); // push node (n - 3) down to and including node 0
    temp = path.peek();         // temp = node (n - 3) down to and including node 0
}
path.push(start);               // push node 0
因此,节点(n-2)永远不会被推送到路径,而节点0将被推两次

但除此之外,该程序对我有效。因此,正如建议的那样,你确实有一个无法到达的目标。你应该检查你是否实际到达了结束节点。请注意,你的graph datra结构模拟了一个有向图,因此如果你想将输入解释为无向边,你必须为它插入两条有向边每行输入

还要注意的是,您没有将初始节点标记为可见,而当您将所有其他节点添加到队列中时,它们将被标记为可见。您还应该将第一个节点标记为可见

编辑:
粘贴(几乎)完整的代码后,我通过以下方式修复了它:

  • 添加了两个通配符导入,分别用于
    java.util.*
    java.io.*
    。通配符导入既快速又脏
  • 在最后添加了一个结束符
    }
    ,以关闭类定义
  • 在输入数据中添加了一行带有单词
    basic
    。您确实应该
    System。如果该关键字丢失,请退出(1)
    ,而不是继续使用不一致的状态

通过这些修改,我测试了两个城市的所有可能组合,总是以两种顺序,包括从一个城市到它自己的路径。没有证据表明任何地方存在
null
值,无论是在输出中还是作为打印异常的原因。

我在这里看到了几个可能的问题。直接原因可能是:您的逻辑隐含它假设只有一种方法可以到达任何给定的节点。虽然这可能是真的,但我对此表示怀疑。如果有两种方法可以到达同一个节点,则在地图中用第二种方法覆盖第一种方法

例如,假设输入为:

A->B
C->B
B->E
D->E
你想从A到E。这可以通过A,B,E来完成。但是当你构建地图时,你会为B,A创建一个边缘条目。然后你会写B,C,覆盖B,A。然后你写E,B。好。然后你写E,D,覆盖E,B。所以当你完成后,边缘地图中的所有内容都是(B,C)和(E,D)。然后尝试从E向后走。找到E,D。但这是错误的:您想要E,B,但被覆盖。当您尝试找到D的条目时,没有条目,因此无法返回A

第二个问题是,你说目标是找到从头到尾的最短路径。但你没有做任何事情来找到最短路径:一旦找到任何路径,你就停止寻找。原则上,你真的需要找到所有可能的路径,然后选择
A->B
C->B
B->E
D->E