Java:使用拆分从文件输入文本

标签 java file-io

我正在输入图的邻接表。有三列数据(顶点、目的地、边),由一个空格分隔。到目前为止,这是我的实现:

         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,所以您永远不需要使用 splitInteger.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

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/

相关文章:

java - jsp/servlet 中的聊天网站

java - LDAP 中基于角色的安全实现

c# - 替换文本文件中的一行

java - JTable从第二行读取文本文件

java - 为java的try with resources语句管理的资源声明自变量

java - java中的过滤集合

java - 如何在 JFrame 上显示两个带有图像的 JPanel,并且两个图像都可见?

java - 从另一个类调用字符串时出现问题 - 变量可能尚未初始化

将文件中的第一个字母大写

java - 将 java.io.File 转换为 org.apache.struts.upload.FormFile