Удаление строки из рваного массива 2D строк и сокращение массива в процессе
На этой неделе мой профессор дал обзорный вопрос для нашего среднесрочного периода, в котором я запутался:
Напишите метод, который получает двумерный (разорванный) массив объектов String и возвращает двумерный (разорванный) массив объектов String, в котором все нулевые записи были удалены. Например, если исходный массив содержит данные (NULL представляет пустую ссылку):
{"John", null, "Mary", "George", null},{null, "Pete", "Rick"},{null, null, null}};
результат, сгенерированный вашим методом, будет двухмерным массивом с тремя строками.
{"John", "Mary", "George"},{"Pete", "Rick"},{}}; // last row will be empty
Код у меня есть:
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;
}
Я понимаю, что мне нужно посчитать количество нулевых значений в каждой строке и вычесть это из общей длины каждой строки для массива String "массив" (плохое имя, которое я знаю). Я подумал, может быть, если бы я создал метод для одномерного массива, это помогло бы мне немного лучше понять логику:
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;
}
Все еще запутанный, как логика применяется к методу 2D рваной матрицы, любые разъяснения будут оценены! Кроме того, я не верю, что могу импортировать что-либо (по крайней мере, не предполагается), и опять же, это всего лишь вопрос обзора, поэтому я не подчеркиваю получение ответа, просто пытаюсь понять логику, стоящую за ним.
1 ответ
Вы можете попробовать это так:
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;
}
Мне кажется, это немного не элегантно, но в настоящий момент я не могу придумать, как предотвратить двойной цикл в clean(String[] dirty)
Тем не менее, это выводит [[John, Mary, George], [Pete, Rick], []]
по желанию.
Редактировать: обновлены некоторые комментарии.