Есть некая таблица из нулей и единиц
{1, 1, 0, 0, 0, 0, 0, 0},
{1, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 0},
{1, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 1, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 1, 1}
Из неё нужно удалить:
То есть, на примере таблицы выше, нужно было удалить следующее:
{1, 1, 0, 0, 0, 0, 0, 0},
{1, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 0},
{1, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 1, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 1, 1}
Что должно остаться:
{0},
{1},
{1}
Реализовывал при помощи ArrayList. Изначально, хотел удалить все столбцы через ArrayName.get(i).remove(j);, но, по непонятным мне причинам, работало всё крайне некорректно.
Решил реализовать небольшим костылём: удаляю строки, которые нужно удалить, транспонирую, удаляю столбцы, ставшие строками. В общем виде это рабочая схема, но когда я дошёл до конкретики (миллион условий для удаления и поиска этих строк и столбцов), опять начались проблемы.
Я, естественно, вынес проблемный момент в отдельный проект и начал искать ошибку, доводя код до простейшего варианта. И заметил вот что:
Допустим, у меня есть двумерный List
List<List<Integer>> FirstTableInt = new ArrayList<>();
И есть некая "маска" - массив вида {1, 0, 0, 0, 1, 1, 1}, в котором единицам соответствуют те строки, которые нужно удалить из двумерного массива. Возможно, глупый вариант, но так уж я придумал :)
Все проверки проходят правильно, туда записывается верная "маска". Пробую удалить строки следующим образом:
for (int i = 0; i < stolbci_removeL.size(); i++)
if (stolbci_removeL.get(i).equals(1)) {
FirstTableInt.remove(i);
stolbci_removeL.remove(i);
}
Где, соответственно, FirstTableInt - двумерный List, откуда нужно удалить строки, а stolbci_removeL - массив с "маской". Что я наблюдаю в работе?
Имеется исходная "маска": {1, 1, 1, 1, 0, 1, 1, 1}
При прохождении условия stolbci_removeL.get(i).equals(1) должны выбраться следующие индексы строк: {0, 1, 2, 3, 5, 6, 7}, но выбираются, почему-то, {0, 1, 3, 4}, и, что самое интересное, если я поменяю условие на stolbci_removeL.get(i).equals(0), то всё выберется верно - будет только {4}.
Почему и при условии .equals(1) и при условии .equals(0) выбирается эта ячейка? Что за магическое сравнение данных?
Для справки: stolbci_removeL имеет тип Integer, его ячейки я сравниваю через equals, хотя через == результат тот же.
В чём проблема? Я пробовал экспериментировать с типами int и Integer, и знаю, что индексы в List и ArrayList всегда типа int, и это я учёл. Но я не понимаю, почему происходит неправильное сравнение, и при взаимоотрицающих условиях результат пересекается?! Результаты условий !stolbci_removeL.get(i).equals(0) и stolbci_removeL.get(i).equals(1) совпадают.
for (int i = 0; i < stolbci_removeL.size(); i++)
if (stolbci_removeL.get(i).equals(1)) {
FirstTableInt.remove(i);
stolbci_removeL.remove(i);
}
Не делайте так никогда. Вы идете по списку с итератором i, и в цикле удаляете элементы сразу же. Что будет? У вас на каждой операции удаления будет изменяться размер списка, по которому вы проходите, вы будете пропускать элементы, которые нужно проверить.
Рассмотрим примитивный пример, у вас есть список чисел, вам нужно удалить все нечетные:
1 2 5 7 9 14 13 16
for (int i = 0; i < list.size(); i++)
if (list.get(i) % 2 == 1) {
list.remove(i);
}
Итак, по шагам:
исходный массив: 1 2 5 7 9 14 13 16, поехали
i = 0:
По индексу 0 у нас число 1, нечетное, удаляем, остается:
2 5 7 9 14 13 16
i = 1
по индексу 1 у нас 5, удаляем (на двойку мы даже не глянули, она теперь с индексом 0):
2 7 9 14 13 16
i = 2
по индексу 2 у нас 9, удаляем (прозевали 7):
2 7 14 13 16
i = 3
по индексу 3 у нас 13, удаляем:
2 7 14 16
list.size() == 4, i == 4, выходим из цикла.
Надеюсь поняли проблему? Обычно в таких случаях делается дополнительный массив, в который пишутся все индексы, по которым нужно осуществить операцию удаления, и затем в другом цикле уже удаляется все что нужно.
По вашему заданию удалять нужно всю матрицу ?!!!
(почему то gif-ка не анимируется ;(()
Продвижение своими сайтами как стратегия роста и независимости