views:

57

answers:

2

Hello, I'm new to Stack Overflow, and this is my first question/post! I'm working on a project for school using Java. The first part I'm having trouble with inolves:

  1. Read each line in a file (listed at the end of my post) one time
  2. Create a "ragged" array of integers, 4 by X, where my 4 rows will be the "region number" (the number found in the Nbr of Region) column, and fill each column with the state population for that region.

So, for example, Row 1 would hold the state populations of Region 1 resulting in 6 columns, Row 2 represents Region 2 resulting in 7 columns, and so on resulting in a "ragged" array.

My question is how to populate, or what would be the best way to populate my array with the results of my file read? I know how to declare the array, initialize the array and create space in the array, but I'm not sure of how to write my method in my State class to populate the results of my file read into the array. Right now I'm getting an "out of bounds" error when I try to compile this code using Netbeans.

Here is my code for Main and State. my input file is listed beneath it:

import java.util.*;
import java.io.*;

public class Main
{
    public static void main(String[] args) throws IOException
    { 
        // create new jagged array obj and fill it with some
        // initial "dummy" values
        int[][] arrPopulation =
        {
            {0,1,2,3,4,5},
            {0,1,2,3,4,5,6},
            {0,1,2,3,4,5,6,7,8,9},
            {0,1,2,3,4,5,6,7,8,9,10}
        };//end array declaration

        // read in file States.txt, instantiate BufferedReader object,
        // set new BufferedReader object to variable @newLine
        FileReader f = new FileReader("States.txt");
        BufferedReader br = new BufferedReader(f);
        String newLine = br.readLine();

        for (int rows = 0; rows < arrPopulation.length; rows++)
        {
            for (int col = 0; col < arrPopulation[col].length; col++) {
                System.out.print(arrPopulation[rows][col] + " ");
            }
            // display on new lines; print out in a "table" format
            System.out.println();
        } // end for

        State newState = new State(newLine);
        int count = 0;
        while(newLine != null)
        {
            newLine = br.readLine();
            System.out.println(newState.getRegionNum());
        }// end while
        br.close();//close stream
    } // end public static void main
} // end main

This is what I have for my State class so far:

import java.util.*;

public class State
{
    private String statePop, stateNum, regionNum;

    public State(String fileRead)
    {
        statePop = fileRead.substring(32,39);
        regionNum = fileRead.substring(55,fileRead.length());
    } // end constructor

    public int getStatePop()
    {
        int population = Integer.parseInt(statePop);
        return population;
    } // @method getStatePop end method

    public int getRegionNum()
    {
        int numOfRegion = Integer.parseInt(regionNum);
        return numOfRegion;
    }// end getRegionNum

    public int getAvgPop()
    {
        int average = 2+2;
        return average;
        // total number of populations
        // divide number of populations
    }// @return the average population of states

    public int getStateTotal()
    {
        //initialize static variable
        int totalPopulation = 0;
        int stateTotal = this.getStatePop() + totalPopulation;
        return stateTotal;
    } // @return stateTotal

    public String toString()
    {
        return statePop + " " + stateNum + " ";
    } // @method end toString method
} // end State class

The names of the columns (not used in the file read, just for explaining purposes) are:

State Capital Abbrev Population Region Nbr of Region

Washington     Olympia        WA 5689263West           6
Oregon         Salem          OR 3281974West           6
Massachusetts  Boston         MA 6147132New_England    1
Connecticut    Hartford       CT 3274069New_England    1
Rhode_Island   Providence     RI  988480New_England    1
New_York       Albany         NY18146200Middle_Atlantic2
Pennsylvania   Harrisburg     PA12001451Middle_Atlantic2
New_Jersey     Trenton        NJ 8115011Middle_Atlantic2
Maryland       Annapolis      MD 5134808Middle_Atlantic2
West_Virginia  Charleston     WV 1811156Middle_Atlantic2
Delaware       Dover          DE  743603Middle_Atlantic2
Virginia       Richmond       VA 6791345Middle_Atlantic2
South_Carolina Columbia       SC 3835962South          3
Tennessee      Nashville      TN 5430621South          3
Maine          Augusta        ME 1244250New_England    1
Vermont        Montpelier     VT  588632New_England    1
New_Hampshire  Concord        NH 1185048New_England    1
Georgia        Atlanta        GA 7642207South          3
Florida        Tallahassee    FL14915980South          3
Alabama        Montgomery     AL 4351999South          3
Arkansas       Little_Rock    AR 2538303South          3
Louisiana      Baton_Rouge    LA 4368967South          3
Kentucky       Frankfort      KY 3936499South          3
Mississippi    Jackson        MS 2752092South          3
North_Carolina Raleigh        NC 7546493South          3
California     Sacramento     CA32182118West           6
Idaho          Boise          ID 1228684West           6
Montana        Helena         MT  880453West           6
Wyoming        Cheyenne       WY  480907West           6
Nevada         Carson_City    NV 1746898West           6
Utah           Salt_Lake_City UT 2099758West           6
Colorado       Denver         CO 3970971West           6
Alaska         Juno           AK  614010West           6
Hawaii         Honolulu       HI 1193001West           6

Am I on the right track here?

Thanks for any help in advance, and sorry for the long post!

A: 

The collections package would be useful here.

  1. Create Map < Integer, List < < Integer > >
  2. As you scan the file one line at a time, grab the region number and population.
    1. Is the region number a key in the map?
      1. No. Then create a new List < Integer > and add it to the map. Now it is.
    2. Add the population to the list.
  3. Now, the map should have four entries. Create the outer array like: int [ ] [ ] array = new int [ 4 ] [ ] ;
  4. Then iterate over the lists in the map and populate the outer array like: array[i]=new int[list.size()];
  5. Then iterate over the list and populate the inner array like: array[i][j]=list.get(j);
emory
A: 

Hi Emory, thanks for your quick response.

My professor hasn't gone over the Collections package yet (looking at some of the classes in the package, I think we'll go over those things next semester) so I'm not too familiar with the Map interface. Also, I think he wants us to use arrays specifically, although he did say that we could use ArrayList...

Up until I read your post, I was re-writing my code in another attempt to solve the problem. I'm going to look at the Map interface, but out of curiosity am I close with the following code? Seems like I just need to fix one line to correct my out of bounds error...

import java.util.*;
import java.io.*;

public class Main
{
    public static void main(String[] args) throws IOException
    {
        // read in file States.txt, instantiate BufferedReader object,
        // set new BufferedReader object to variable @newLine
        FileReader f = new FileReader("States.txt");
        BufferedReader br = new BufferedReader(f);
        String newLine = br.readLine();

        //declare jagged array
        int[][] arrPopulation;
        arrPopulation = new int[4][];

        //create state object, and get 
        State newState = new State(newLine);      

        //read file
        int col = 0;

        arrPopulation[0] = new int[col];
        arrPopulation[1] = new int[col];
        arrPopulation[2] = new int[col];
        arrPopulation[3] = new int[col];

        int stateRegion = newState.getRegionNum();

        while (newLine != null)
        {
            switch (stateRegion)
            {
                case 1:

                    arrPopulation[0][col] = newState.getStatePop();
                    System.out.println("Population added:" +
                            arrPopulation[0][col]);//test if col was created
                    col++; //increment columns
                    break;
                case 2:

                    arrPopulation[1][col] = newState.getStatePop();
                    col++; //increment columns
                    break;
                case 3:

                    arrPopulation[2][col] = newState.getStatePop();
                    col++;
                    break;
                case 6:
                    arrPopulation[3][col] = newState.getStatePop();
                    System.out.println("Population added:" +
                            arrPopulation[3][col]);
                    col++; //increment columns
                    break;
            }
            br.readLine();
        }//endwhile
        br.close();//close stream
    } // end public static void main
} // end main

Sorry if I'm supposed to place all this in the Comments section, however, I hit my character limit and couldn't post my code. Thanks again for your help!

carlos
It looks bad. (1) col = 0 so arrPopulation[0,1,2,3] = new int[0]. The program needs to calculate the size of the different arrays. (2) The variables newState, stateRegion are constant throught the while loop (newState=Washington and stateRegion=6). You need too add code to update these variables for every line you read from the file.I think fixing problem 1 will be harder than fixing problem 2.
emory
Questions to help you solve this: **1)** What line is your out of bounds exception on? (You can tell this by reading the exception). **2)** What do you think they exceptions is being caused by? (Here is a hint, your array is only 10 things long and you do myarry[50] then this will not be valid. Remember that arrays start at 0 so 10 will be out of bounds). Good luck
sixtyfootersdude
For #2, you can change your while loop to "for(String newLine=br.readLine();newLine!=null;newLine=br.ReadLine())". Then move the part where you define newState and stateRegion inside the for loop.
emory
For #1 - if you can use ArrayList then create ArrayList<ArrayList<Integer>> instead of int[][]. After you populate it with data then you can convert it into an int[][].
emory
@sixtyfootersdude:1) the error is occurring in Case 6, specifically this line:arrPopulation[3][col] = newState.getStatePop();2) This tells me that my code is possibly getting the correct region number (it's 6 in the first line of the txt file). My ragged array is:arrPopulation = new int[4][];I think I see, my array is initially defined as arrPopulation = new int[4]; but in my switch statement I'm only setting values up to arrPopulation[3], so I must be short one index, correct? I may be confused..@emory: thanks, the for loop is much more efficient! still working on problem 1...
carlos
@emory:I'm going to give ArrayList a shot when I get home tonight and post what happens either tonight or tomorrow.Thanks everyone for your help thusfar!
carlos