1

Assume i have a text file like this.

1 4 6
2 3    
5 8 9 4
2 1
1

What i want to do is to store them into a 2d array exactly how they are represented. After some googling and reading i came up with the following code.

Scanner s = new Scanner(new BufferedReader(new FileReader("myData.txt")));     

while (s.hasNextLine())
{
    String myStr = s.nextLine();
    x = 0;
    for ( int y = 0; y <= myStr.length(); y+=2)
    {
        myStr = myStr.trim();
        tempStr = myStr.substring(y, y+1)
        num[row][coln] = Integer.parseInt(tempStr);
        coln++
    }
    row++;
}

It works okay, but for integers that have only 1 digit. But what if i have integers of different length. How can i do it to dynamically check length of integers?

For example, i want to store this text file in an 2d array

13 4 652
2 343    
5 86 9 41
2 18
19

If someone can point me in the right direction, that would be very much helpful. Thanks

kype
  • 525
  • 1
  • 5
  • 20

7 Answers7

3

You can use split() for Strings. If you use white-space as a delimiter, it will return an array of Strings, where each number in the line will map to one slot in the array. Then, loop through the array and use Integer.parseInt().

Another way to do it would be to feed the output from nextLine() into another Scanner and use nextInt() to retrieve the numbers.

Steve P.
  • 13,674
  • 6
  • 38
  • 67
0

you can use nextInt method of scanner class it will give you integer value one by one.

Firslty you schould use hasnextXXX method to check that is there any integer value in your file like

scanner.hasNextInt()

Than you can write a program like

import java.util.*;

public class ScannerDemo {
   public static void main(String[] args) {

     Scanner scanner = new Scanner(new BufferedReader(new FileReader("myData.txt")));     


      while (scanner.hasNext()) {
         if (scanner.hasNextInt()) {
            System.out.println("integer present" + scanner.nextInt());
         }
         System.out.println("no integer" + scanner.next());
      }
      scanner.close();
   }

}

From the JavaDocs, the nextInt() method will throw these exceptions under these conditions:

InputMismatchException - if the next token does not match the Integer regular expression, or is out of range
NoSuchElementException - if input is exhausted
IllegalStateException - if this scanner is closed
SSP
  • 2,703
  • 5
  • 27
  • 47
  • Im sorry to ask. But why is the scanner cascaded unnecessarily? scanner = s = new Scanner ( new buffered...); //literally this is what happens right? – kype Oct 27 '13 at 05:00
  • firstly i was thinking to convert string to scanner than i took inpt like you and forget to edit next line – SSP Oct 27 '13 at 05:07
0

You can use this code:

Scanner scan = new Scanner(new File("test.txt"));
scan.useDelimiter("\\Z");
String content = scan.next();
ArrayList output=new ArrayList();
ArrayList<Inteher> inner=new ArrayList<Integer>();
String[] a1=content.split("\n");
for(String a:a1){
String a2=a1.plit(" ");
for(String b:a2){
inner=new ArrayList<Integer>();
inner.add(Integer.parseInt(b));
}
output.add(inner);

}
Mohsen Kashi
  • 4,102
  • 3
  • 38
  • 61
0

I would do it this way

    String[] a = mystr.split(" +");
    num[i] = new int[a.length];
    for (int j = 0; j < a.length; j++) {
        num[i][j] = Integer.parseInt(a[j]);
    }

I would also change the first part as follows

    List<String> lines = Files.readAllLines(Paths.get("myData.txt"), StandardCharsets.UTF_8);
    int[][] num = new int[lines.size()][];
    for(int i = 0; i < lines.size(); i++) {
        ...
Evgeniy Dorofeev
  • 124,221
  • 27
  • 187
  • 258
0

You could try this:

try {

        InputStream in = getClass().getResourceAsStream(s);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));

        int[][] values = new int[numRows][numCols];

        int numRows = br.readLine();
        int numCols = br.readLine();

        String delims = "\\s+";
        for (int row = 0; row < numRows; row++) {
            String line = br.readLine();
            String[] tokens = line.split(delims);
            for (int col = 0; col < numCols; col++) {
                values[row][col] = Integer.parseInt(tokens[col]);
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

For the text file, set it out like this:

10 // amount of numbers across
7 // amount of numbers down
6 6 6 6 6 65 6 6 6 6
6 6 7 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 72 6 6 6
6 6 6 6 6 6 6 6 6 6
6 6 89 6 6 6 6 345 6 6
6 6 6 6 6 6 6 6 6 6

You put the across and down numbers in so when it reads the integers into the 2D array, it knows the width and height.

Hope this helped!

sparklyllama
  • 1,076
  • 4
  • 18
  • 27
0

It's significantly faster to use a MappedByteBuffer and read this in as binary, and process the numbers that way. In my experiments in this similar context, it was three times as fast. There is a huge overhead to reading line by line, in two respects:

  1. The garbage collector goes crazy because you're creating and discarding so many String objects.
  2. You process every character twice: once when constructing the String, and then once more when turning it into numbers. If you split the String and then convert each one, you process each character three times.

It depends rather on whether you want speed or concise and simple code. There's no doubt that the String approach is easier to understand, so it's better if you know your file will always be small; but if it might get huge, you really should look at a binary approach.

Community
  • 1
  • 1
chiastic-security
  • 19,689
  • 3
  • 33
  • 62
0

Maybe I misunderstand the question, but why don't you just read it in like this?

list1 = [map(int,x.strip().split()) for x in open("/ragged.txt")]

for z in list1:
    for y in z:
        print y,
    print

It prints the following integers (same as file contents):

1 4 6
2 3
5 8 9 4
2 1
1

It works for longer integers too.

Stefan Gruenwald
  • 2,342
  • 22
  • 24