0

I have a .txt file with 1302 lines, which divides evenly to 14 x 93 (corresponding to 14 columns and 93 rows). I would like to parse the 1302 lines into a [93][14] multi-dimensional array. I have the following script that traverses each individual "cell", but as for the file parsing, I have some questions.

        int rows = 93;
        int columns = 14;
        int i;
        int j;
        int count = 0;

        String[][] array = new String[rows][columns];
        for(i = 0; i < rows; i++){
            for(j = 0; j < columns; j++){
                System.out.println(i + "," + j);
                count++;
            }
        }

How do I assign each "line" of the text file into each cell?

theGreenCabbage
  • 5,197
  • 19
  • 79
  • 169

3 Answers3

1

My Recommendation (aside from changing using double[][] to something like List<List<Double>>) would be to go through each text line as such:

InputStream    fis;
BufferedReader br;
String         line;

fis = new FileInputStream("the_file_name");
br = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));
while ((line = br.readLine()) != null) {
    // Deal with the line
}

// Done with the file
br.close();
br = null;
fis = null;

With this, you should be able to get each individual 'line' of the file. The reason I mention above using the List<List<Double>> instead of double[][] is because you get two things out of that:

1) dynamic resizeability. Even if you know the size and want to give that list a default size to help with performance, you aren't LIMITED to that size, which is worth it's weight in.. flops? programmers gold.

2) using the primitive double (lowercase d) as opposed to the Java object Double (uppercase D) really kill you as far as not getting access to a LOT of great methods and useability built into Double (capitol D object). for more explanation on this, see: Double vs. double

Also note, the code above has no error checking, so you'll want to build some of that into it, it's a pretty basic implementation.

EDIT::

Alright, so in your code that you posted at: code snipped you have a double for-loop INSIDE of the readLine() loop. like so:

while ((line = br.readLine()) != null) {
    for (int i = 0; i < rows; i++){
        for(int j = 0; j< columns; j++){
            line = array[i][j];
         }
     }   
}

Now, there are two problems with this:

1) you are setting LINE equal to the content of array[i][j] which means nothing, since array is just an empty 2-dimensional array.

2) for EVERY line in the text file you are looping 1302 times (and then some more because you're doing (1302 * columns) * 1302

really what this code above does, is it takes care of your 'row' loop. so instead of what you're doing, just do:

int i = 0;
while ((line = br.readLine()) != null) {
    array[i][0] = line;
    i++
}

that will fill up your array with all of the strings from the file.

Community
  • 1
  • 1
WillBD
  • 1,919
  • 1
  • 18
  • 26
  • I've implemented some basic error checking. What I did was I put my multidimensional-array-traversing into your while loop, assigned `line=array[i][j]`. Would that work? – theGreenCabbage Nov 22 '13 at 17:28
  • Well each line that is obtained with br.readLine() is going to be a String, so you're going to encounter some type mismatch there, what you'd need to do is add Zong Zheng Li's answer where you use `split("\\s+")` and then use Double.parseDouble() to tokenize each line, then you can place those individual tokens inside of your double array. – WillBD Nov 22 '13 at 17:30
  • I have changed my array type to a `String` to counter that =P. I don't know why I made the original decision to do double, as those values aren't doubles in the get-go. – theGreenCabbage Nov 22 '13 at 17:30
  • Ah, well in that case, yes I don't see why that wouldn't work. Again, just keep in mind that if you decide to ever use a larger .txt file, with more lines OR more columns, you're liable to get an outOfBoundsException ^^ there could be a few other small intracacies, I haven't gone through and run the code, but I don't see why it wouldn't work. – WillBD Nov 22 '13 at 17:33
  • This is what I did: http://puu.sh/5q1Me/b32144324e.png With my counter, I count how many times the line was read. The `count` should say 1302 (for 1302 lines), but for some reason, it traverses through the array 1695204 times! – theGreenCabbage Nov 22 '13 at 17:37
  • I think the only reason it would do it that many times is because it mistakes something in the file for a line-break, like a comma. And what do you know - if you take the number of `commas` in the file, multiply it by the number of lines, and then divide it by 2, you get that number `1695204`. – theGreenCabbage Nov 22 '13 at 17:38
  • The reason it's doing that is because for EACH LINE of the text file, you're iterating over and copying it, 1302 times! I'll edit my answer to explain more fully so it's not hidden in the comments – WillBD Nov 22 '13 at 17:40
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/41720/discussion-between-thegreencabbage-and-willbd) – theGreenCabbage Nov 22 '13 at 17:44
0

Read in the lines (rows) with Scanner or BufferedReader, then use split("\\s+"); to split the lines into tokens (columns). Then use Double.parseDouble() on each of the tokens and then insert it into your array.

Zong
  • 6,160
  • 5
  • 32
  • 46
0

In order to assign anything to a 2D matrix, you can do something like this:

for (int r=0; r<NUM_ROWS; r++)
    for (int c=0; c<NUM_COLS; c++)
        matrix[r][c] = get_line(r*NUM_COLS + c)

Where get_line(i) will get the i'th line in the file

Daniel
  • 21,933
  • 14
  • 72
  • 101