【问题标题】:Parse a table from stdin从标准输入解析表
【发布时间】:2014-03-20 15:49:18
【问题描述】:

从标准输入中逐行获取如下表格:

3 9 $12  $7  $2
4 $5  1 $4  $21
12  $11 0 0  $17

我需要以这种方式解析它,这样我就会有两个二维列表: 1) 只是一个数字表:

3 9 12 7 2
4 5 1 4 21
12 11 0 0 17

2) 表,其中 true 表示数字前面有一个美元符号:

false false true true true
false true false true true
false true false false true

最好的方法是什么?

我有以下代码:

public static List[] parseTable() {
    ArrayList<ArrayList<Integer>> vals = new ArrayList<>();
    ArrayList<ArrayList<Boolean>> truthtable = new ArrayList<>();
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String mark = "$";
    try {
        while (true) {
            String[] splitline = reader.readLine().split("\\s+");
            ArrayList<Integer> valsrow = new ArrayList<>();
            ArrayList<Boolean> truthrow = new ArrayList<>();
            System.out.println(Arrays.toString(splitline));
            for (String element: splitline) {
                if (element.startsWith(mark)) {
                    truthrow.add(true);
                }
                else {
                    truthrow.add(false);
                }
                valsrow.add(Integer.parseInt(el.replaceAll(mark, "")));
            }
            vals.add(valsrow); truthtable.add(truthrow);
        }
    }
    catch(IOException e) {
        List[] output = new List[2];
        res[0] = truthtable; res[1] = vals;
        return  output;
    }

但它没有正确去除空格并导致

NumberFormatException: for input string: ""

我初步不知道输入的大小。

【问题讨论】:

  • 你肯定尝试过。展示它!

标签: java parsing input tabular


【解决方案1】:

在那之后,我只能说 Lutz Horn,这是你必须做的步骤 ;)

我对您的代码做了一些小改动,现在它适用于我;)

    ArrayList<ArrayList<Integer>> vals = new ArrayList<ArrayList<Integer>>();
    ArrayList<ArrayList<Boolean>> truthtable = new ArrayList<ArrayList<Boolean>>();
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String mark = "$";
    try {
        while (true) {
            String[] splitline = reader.readLine().split("\\s+");
            ArrayList<Integer> valsrow = new ArrayList<Integer>();
            ArrayList<Boolean> truthrow = new ArrayList<Boolean>();
            for (String element: splitline) 
            {
                if(!element.isEmpty())
                {
                    if (element.startsWith(mark))
                    {
                        truthrow.add(true);
                        element = element.substring(1, element.length());
                    }
                    else 
                        truthrow.add(false);

                    valsrow.add(Integer.parseInt(element.trim()));
                }
            }
            vals.add(valsrow); 
            truthtable.add(truthrow);
        }
    }
    catch(IOException e) {
        System.out.println("prob");
    }

享受 ;)

【讨论】:

  • 但是我如何在不知道的情况下阅读行,其中会有多少行?当输入结束时,它只会引发异常。
  • 你说:“从标准输入我得到一个表格:3 9 $12 $7 $2 4 $5 1 $4 $21 12 $11 0 0 $17”当你有这个时你知道长度所以你不需要一段时间是真的:)
  • 我一行一行的搞定,这就是问题
  • 所以每次你得到一个新行你想做点什么?首先你得到:3 9 $12 $7 $2 然后你会得到第二个等等,但是你的程序没有尽头吗?有什么意义?
  • 当没有任何可用的输入时,将引发 IOException,捕获并返回结果。
【解决方案2】:

这很容易。

  1. 阅读每一行。
  2. 在空白处拆分。
  3. 从每个字段中提取数字,将其保存在您准备好的int[][]中。
  4. 检查$ 是否在该字段中,并在您准备好的boolean[][] 中注明
  5. 打印两个数组。

【讨论】:

    【解决方案3】:

    我认为您的第一个问题是如何知道何时停止阅读。答案在Reader.readLine() 的文档中:

    返回:包含行内容的字符串,不包括 任何行终止字符, 或 null 如果流的末尾有 已到达

    所以你程序的外循环是:

    String line = reader.readLine();
    while(line != null) {
        handleLine(line, numTable, boolTable);
        line = reader.readLine();
    }
    

    为确保有效,请编写最简单的handeLine() 以证明其有效:

     public void handleLine(String line, 
                    List<List<Integer>> numTable, List<List<Boolean>> boolTable) {
          System.out.println(line);
     }
    

    现在可以了,您可以改进 handleLine() 来做您需要的事情。

    一次做一个,把它们写成小方法。编写小程序来练习只是你正在研究的小方法,然后再把它们放在一起。或者更好的是,了解 jUnit,它可以更轻松地编写和保存这些小程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      • 1970-01-01
      • 2014-07-22
      相关资源
      最近更新 更多