我正在输入图的邻接表。有三列数据(顶点、目的地、边),由一个空格分隔。到目前为止,这是我的实现:
FileStream in = new FileStream("input1.txt");
Scanner s = new Scanner(in);
String buffer;
String [] line = null;
while (s.hasNext())
{
buffer = s.nextLine();
line = buffer.split("\\s+");
g.add(line[0]);
System.out.println("Added vertex " + line[0] + ".");
g.addEdge(line[0], line[1], Integer.parseInt(line[2]));
System.out.println("Added edge from " + line[0] + " to " + line[1] + " with a weight of " + Integer.parseInt(line[2]) + ".");
}
System.out.println("Size of graph = " + g.size());
这是输出:
Added vertex a.
Added edge from a to b with a weight of 9.
Exception in thread "main" java.lang.NullPointerException
at structure5.GraphListDirected.addEdge(GraphListDirected.java:93)
at Driver.main(Driver.java:28)
我的印象是
line = buffer.split("\\s+");
会将二维字符串数组返回给变量 line
。它似乎第一次工作但不是第二次。有什么想法吗?
我还想得到一些关于我对这个问题的实现的反馈。有没有更好的办法? 有什么可以帮助新手的! :)
编辑:
我今天早些时候尝试了这个实现,但没有成功。我在这里又做了一次:
FileStream in = new FileStream("input1.txt");
Scanner s = new Scanner(in).useDelimiter("\\s+");
while (s.hasNext())
{
Scanner line = new Scanner(s.nextLine());
String vertex = line.next();
String destination = line.next();
int weight = line.nextInt();
g.add(vertex);
System.out.println("Added vertex " + vertex + ".");
g.addEdge(vertex, destination, weight);
System.out.println("Added edge from " + vertex + " to " + destination + " with a weight of " + weight + ".");
}
System.out.println("Size of graph = " + g.size());
输出:
Added vertex a.
Exception in thread "main" java.lang.NullPointerException
at structure5.GraphListDirected.addEdge(GraphListDirected.java:93)
at Driver.main(Driver.java:22)
编辑2:
这是 addEdge 函数。这不是我自己的实现,我用它来节省在这个开始阶段无力编写自己的时间...
package structure5;
import java.util.Iterator;
abstract public class GraphList<V,E> extends AbstractStructure<V> implements Graph<V,E>
{
protected Map<V,GraphListVertex<V,E>> dict; // label -> vertex
protected boolean directed; // is graph directed?
protected GraphList(boolean dir)
{
dict = new Hashtable<V,GraphListVertex<V,E>>();
directed = dir;
}
public void add(V label)
{
if (dict.containsKey(label)) return; // vertex exists
GraphListVertex<V,E> v = new GraphListVertex<V,E>(label);
dict.put(label,v);
}
abstract public void addEdge(V v1, V v2, E label);
}
图形.java:
package structure5;
import java.util.Iterator;
public interface Graph<V,E> extends Structure<V>
{
public void add(V label);
public void addEdge(V vtx1, V vtx2, E label);
}
注意:我省略了与该程序无关的其余方法
编辑3: 这是 GraphListDirected.java
public class GraphListDirected<V,E> extends GraphList<V,E>
{
public GraphListDirected()
{
super(true);
}
public void addEdge(V vLabel1, V vLabel2, E label)
{
GraphListVertex<V,E> v1 = dict.get(vLabel1);
GraphListVertex<V,E> v2 = dict.get(vLabel2);
Edge<V,E> e = new Edge<V,E>(v1.label(), v2.label(), label, true); //Line 93
v1.addEdge(e);
}
最佳答案
String.split
返回一个 String[]
,一个一维数组,而不是一个二维数组。当然,您可以进一步split
String
,它是split
的结果(等等)。
话虽如此,因为您已经在使用 Scanner
,所以您永远不需要使用 split
和 Integer.parseInt
等。只是创建另一个 Scanner
来扫描s.nextLine()
。
Scanner line = new Scanner(s.nextLine());
String from = line.next();
String to = line.next();
int weight = line.nextInt();
我不确定是什么导致了 NullPointerException
,尽管我们从您的输出中知道至少已成功添加一条边。
API 链接
-
Scanner(String source)
- 构造一个新的
Scanner
,它生成从指定字符串扫描的值。
- 构造一个新的
在多个Scanner
小 A-ha!! 时刻意识到,就像您可以对前一个 split
的结果进行split
一样,您可以创建一个 Scanner
来扫描从另一个 Scanner
返回的字符串。
String inputText =
"Line1 a b\n" +
"Line2 d e f\n" +
"Line3";
Scanner input = new Scanner(inputText);
while (input.hasNext()) {
Scanner line = new Scanner(input.nextLine());
System.out.println("[" + line.next() + "]");
while (line.hasNext()) {
System.out.println(" " + line.next());
}
}
以上片段打印:
[Line1]
a
b
[Line2]
d
e
f
[Line3]
这只是一个简单的示例,但是当每一行都比较复杂时,您可以看到这种技术的值(value),例如当它包含数字和正则表达式模式时。
关于NullPointerException
由于 addEdge
的实现方式,您需要添加
开始和结束顶点。
Scanner line = new Scanner(s.nextLine());
String vertex = line.next();
String destination = line.next();
int weight = line.nextInt();
g.add(vertex);
g.add(destination); // <--- ADD THIS LINE!!
g.addEdge(vertex, destination, weight);
这应该修复 NullPointerException
。
希望发现此错误的过程具有教育意义:对问题进行了多次修改以收集相关信息,但最终确定了错误的罪魁祸首。
关于Java:使用拆分从文件输入文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2901964/