2

My professor gave out a review question for our midterm this week that I'm confused on:

Write a method that is given a two-dimensional (ragged) array of String objects and returns a two-dimensional (ragged) array of String objects where all the null entries have been removed. For example, if the original array has the data (NULL represents a null reference):

{"John", null, "Mary", "George", null},{null, "Pete", "Rick"},{null, null, null}};

the result generated by your method will be a two-dimensional array with three rows.

{"John", "Mary", "George"},{"Pete", "Rick"},{}}; // last row will be empty

The code I have is:

public static String[][] removeNull2D(String[][] ragged) {
    int counter = 0;
    int nullCounter = 0;
    String[][] array; // isn't initialized

    // doesn't work I tested in debugger, need a way to shorten each row by the amount of null values it has
    for (int i = 0; i < ragged.length; i++) {
        for (int j = 0; j < ragged[i].length; j++) {
            if (ragged[i][j] == null) {
                nullCounter++;
                for (j = 0; j < ragged[i].length; j++) {
                    array = new String[ragged.length][ragged[i].length - nullCounter];
                }
            }
        }
    }
    // based off 1D array approach
    for (int i = 0; i < ragged.length; i++) {
        for (int j = 0; j < ragged[i].length; j++) {        
            if (ragged[i][j] != null) {
                array[i][counter++] = ragged[i][j];
            }
        }
    }
    return ragged;
}

I understand I need to count the amount of null values in each row and subtract that from the total length of each row for the String array "array" (bad name I know). I thought maybe if I made a method for a 1D array, it would help me understand the logic a little better:

public static String[] removeNull1D(String[] a) {
    String[] array = new String[a.length - 1];
    int counter = 0;

    for (int i = 0; i < a.length; i++) {
        if (a[i] != null) {
            array[counter++] = a[i];
        }
    }
    a = array;
    return array;
}

Still confused how the logic applies to the 2D ragged array method, any clarification would be appreciated! Also, I don't believe I can import anything (are not supposed to at least), and once again this is just a review question, so I'm not stressing about getting an answer, just trying to understand the logic behind it.

derpt34
  • 39
  • 5
  • So what's your problem? If you remove the nulls, you don't need to count anything as long as you use an ArrayList rather than an array. If you do use an array, process all the rows and find the largest number of non-null values. – Neil Masson Dec 15 '15 at 15:48
  • Take a look at this: http://stackoverflow.com/q/4150233/1743880 – Tunaki Dec 15 '15 at 15:49

1 Answers1

2

You could try it like this:

public static void main(String[] args) {
    String[][] ragged = { { "John", null, "Mary", "George", null }, { null, "Pete", "Rick" }, { null, null, null } };

    String[][] cleaned = new String[ragged.length][];
    for (int i = 0; i < ragged.length; i++) {
        cleaned[i] = clean(ragged[i]); // Apply clean method to each sub array.
    }

    System.out.println(Arrays.deepToString(cleaned));
}

private static String[] clean(String[] dirty) {
    int nonNullCount = 0;
    for (String string : dirty) {
        if (string != null) {
            nonNullCount++; // Count non-null Strings.
        }
    }
    String[] clean = new String[nonNullCount]; // Create array for non-null Strings.
    int cleanIndex = 0;
    for (String string : dirty) {
        if (string != null) {
            clean[cleanIndex] = string; // Insert only non-null String at index.
            cleanIndex++; // Only then update index.
        }
    }
    return clean;
}

Seems a little bit inelegant to me, but at the moment I can't think of a way to prevent the double loop in clean(String[] dirty)

Nevertheless, it outputs [[John, Mary, George], [Pete, Rick], []] as desired.

Edit: Updated some commentary.

QBrute
  • 4,405
  • 6
  • 34
  • 40