Search code examples
javaarraysparsingscientific-notation

Parse varying sized arrays in data structure - Java


As a novice Java programmer, I've run into a rather high hurdle while trying to analyze data for a personal project of mine. I have a text file with ~33.5k data points in the following format:

PointNumber:        33530  
Lat:                8.99167773897820e-001  
Lon:                6.20173660875318e+000  
Alt:                0.00000000000000e+000  
NumberOfAccesses:   4  
0    4.80784667215499e+003   4.80872732950073e+003  
0    1.05264215520092e+004   1.05273043378212e+004  
1    1.65167780853593e+004   1.65185840063538e+004  
1    6.52228387069902e+004   6.52246514228552e+004  

The final rows, i.e. ones beginning with 0 or 1, correspond to the integer in the Number of Accesses row. I would like to parse through the file and print the Lat, Lon, and two values following each access instance of only PointNumbers having more than 1 number of accesses.

I'm not sure whether to start with a scanner or tokenizer or to compile a pattern. Which technique makes storing only valid PointNumbers easier? Intuition tells me to parse through the file, placing relevant values into an object:

PointNumber num1 = new PointNumber(lat, lon, accesses[]);

Then loop through the objects and print the object's values if the accesses array length is > 1. On the other hand, it would be better to disregard the information that does not meet the requirements. Could this be done by checking the NumberOfAccesses value while parsing then jump ahead to the next string.startsWith("PointNumber:") if the value is <= 1?

I have a feeling the overwhelming majority of this community will try steering me towards XML or YAML, but I really prefer trying to tackle this in Java. Any advice, direction, or applicable examples is always greatly appreciated.


Solution

  • You can loop through this while you have input to parse

    // Assuming you have a scanner object named s and pointed to your file:
    
    // PointNumber: 33530
    int pointNumber = 0;
    while(!s.next().equals("PointNumber:")) {
        pointNumber = s.nextInt();
    }
    
    // Lat: 8.99167773897820e-001
    double lat = 0.0;
    while(!s.next().equals("Lat:")) {
        lat = s.nextDouble();
    }
    
    // Lon: 6.20173660875318e+000
    double lon = 0.0;
    while(!s.next().equals("Lon:")) {
        lon = s.nextDouble();
    }
    
    // Alt: 0.00000000000000e+000
    double alt = 0.0;
    while(!s.next().equals("Alt:")) {
        alt = s.nextDouble();
    }
    
    // NumberOfAccesses: 4
    int numberOfAccesses = 0;
    while(!s.next().equals("NumberOfAccesses:")) {
        numberOfAccesses = s.nextInt();
    }
    
    // 0 4.80784667215499e+003 4.80872732950073e+003
    // 0 1.05264215520092e+004 1.05273043378212e+004
    // 1 1.65167780853593e+004 1.65185840063538e+004
    // 1 6.52228387069902e+004 6.52246514228552e+004
    
    // Assuming you have defined an Access class
    LinkedList<Access> accesses = new LinkedList<Access>();
    for(int i = 0; i < numberOfAccesses; i++) {
        // Assuming this is the constructor for the Access class
        accesses.add(new Access(s.nextInt(), s.nextDouble(), s.nextDouble()));
    }
    

    Then you can add all the data you actually want into a list of "PointNumber" and then print or do whatever from it.