从stdin解析表

时间:2014-03-20 15:49:19

标签: java parsing input tabular

从stdin逐行输入得到如下表格:

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

我需要以这种方式解析它,以便我将有两个2d列表:  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: ""

我不知道输入的大小。

3 个答案:

答案 0 :(得分:0)

这很容易。

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

答案 1 :(得分:0)

之后我不能说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");
    }

享受;)

答案 2 :(得分:0)

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

  

返回:包含行内容的String,不包括   任何行终止字符,,如果流的末尾有,则为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 ,这使得编写和保持这些小程序更容易。