Domanda

From stdin input line by line get a table like:

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

I need to parse it in a such way, so that I will have two 2d lists: 1) Just a table of numbers:

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

2) table, in which true will mean that there was a dollar sign in front of a number:

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

Which is the best way to do this?

I've had the following code:

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;
    }

but it does not correctly strip spaces and results in a

NumberFormatException: for input string: ""

I don't know the size of an input preliminarily.

È stato utile?

Soluzione

After that I can't say more than Lutz Horn, it's the steps you have to do ;)

I made some small changes to your code and now it works for me ;)

    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");
    }

enjoy ;)

Altri suggerimenti

That is easy.

  1. Read each line.
  2. Split it on whitespace.
  3. Extract the number from each field, save it in a int[][] you have prepared.
  4. Check if the $ is in the field, note it in a boolean[][] you have prepared
  5. Print both arrays.

I think your first question is how to know when to stop reading. The answer is in the documentation for Reader.readLine():

Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

So the outer loop of your program is:

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

To make sure that works, write the simplest handeLine() that proves it works:

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

Now that works, you can improve handleLine() to do the things you need.

Do them one at a time, and write them as small methods. Write small programs to exercise just the small method you are working on, before putting it all together. Or better still, find out about jUnit, which makes writing and keeping those small programs easier.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top