Как удалить строку из 2D-массива в C?
Как удалить определенную строку из матрицы, сохранив тот же порядок? Пример:
Скажем, мне нужно удалить строку со всеми четными элементами, поэтому после удаления она должна выглядеть так:
Я сам пробовал писать код (условие не такое, как я упоминал выше!), Но на самом деле он не работает должным образом:
4 ответа
Ваш метод не работает, потому что вы изменяете матрицу на месте, соответственно обновляете индекс i и количество строк no_of_rows , но не можете обновить отдельный массив prosjeci . Когда строка соответствует фильтру, все последующие строки в матрице удаляются.
Вы можете решить эту проблему, используя отдельный индекс для матрицы и массива фильтров:
В качестве альтернативы, если вы можете обновить массив фильтрации, вы можете сделать это:
Я пытался сделать то, что вы имели в виду ..
Я не вижу ничего плохого в вашем коде.
В комментариях кто-то попросил вас опубликовать «Минимальный, полный и поддающийся проверке пример». Вот что это значит. Я усовершенствовал вашу программу, добавив объявление и инициализацию вашего массива matrica и других переменных, изменив условие в соответствии с вашим примером и распечатав массив в конце. В итоге я получил вот что:
Так что было бы лучше, если бы вы вообще опубликовали что-то подобное.
Но когда я компилирую и запускаю эту программу, она работает отлично. (Я не удивлен — как я уже сказал, я не вижу в этом ничего плохого.)
Итак, какова бы ни была ваша проблема, она в том, чего вы нам не показали. Что вы имели в виду, когда сказали «на самом деле это не работает должным образом»? Что вы ожидали увидеть, а что вместо этого?
[P.S. Есть еще одна проблема с вашим вопросом. Пока вы не спросите лучше, я даже не должен на него отвечать. Этот мой ответ был отклонен, чтобы напомнить мне об этом факте. Я не жалуюсь; Я этого ожидал. Но, пожалуйста, в следующий раз задайте более полный и ответственный вопрос.]
Во-первых, вы не можете удалять элементы из массива без создания новой копии массива. Вы можете только перезаписать их некоторыми другими значениями и сохранить количество фактически используемых элементов в массиве.
Вот наглядная программа, которая показывает, как это можно сделать. Переменная с именем n используется для хранения количества фактически используемых строк элементов в массиве.
Что касается вашего подхода, то он неэффективен, потому что для каждой итерации с проверкой условия вы копируете все строки массива после данной строки вместо копирования только одной строки.
Также плохой практикой является одновременное изменение управляющих переменных цикла for в его теле и в самом операторе for. Это затрудняет чтение кода.
Как эффективно удалить элементы из массива

Задача удаления заданных элементов из массива на первый взгляд кажется весьма простой. И на самом деле так оно и есть, однако зачастую начинающие программисты используют более сложный и тяжёлый с точки зрения производительности вариант алгоритма, из-за чего и кода становится больше и эффективность программы страдает. В учебных программах, когда количество элементов массива мало (порядка 10-100 элементов) оба алгоритма выполняются практически мгновенно. Однако при попытке написать наивный вариант в проекте, в котором работают с гигантскими массивами, приложение будет тратить ужасно много времени или вовсе надолго зависнет.
Как удалить одно значение из массива?
Начнём с более простого алгоритма — удаления одного элемента по индексу. Его отлично знают все начинающие разработчики: все элементы правее заданного индекса сдвинуть влево на 1 и уменьшить размер массива на единицу:
Этот алгоритм весьма простой и эффективный. К нему никаких претензий.
Наивный алгоритм удаления значений из массива
Когда же нужно удалить не один элемент из массива, а сразу несколько, в первую очередь в голову приходит мысль вызвать удаление по индексу несколько раз. Выглядеть это будет примерно следующим образом:
В такой версии может показаться, что всё хорошо и алгоритм имеет линейную сложность. Но давайте заменим вызов функции RemoveAt на её тело:
В таком виде всё куда очевиднее: при каждом удалении элемента выполняется вложенный цикл, из-за чего сложность удаления элеметнов равных заданному значению становится квадратичной. Можно ли как-то избавиться от вложенного цикла? Оказывается, можно, и, что самое главное, просто необходимо!
Эффективный алгоритм удаления элементов из массива
Наиболее проблемным местом наивного алгоритма является вложенный цикл. Именно от него мы и будем избавляться. Для этого заведём перед циклом переменную j , в которой будем хранить индекс для вставки элемента массива. Изначально значение этой переменной должно будет быть равно нулю.
В цикле по всем элементам от начала до конца будем проверять, надо ли удалять значение или нет. Если значение нужно оставить в массиве, то будем помещать его в массив по индексу j и увеличивать значение этого индекса. Пройдя весь массив, в переменной j будет находиться количество элементов массива после удаления, а потому нужно присвоить это значение размеру массива.
Такой алгоритм имеет линейную сложность, поскольку проходит по массиву всего один раз, не выполняя внутри никаких «длительных» действий.
Пример работы данного алгоритма:
Пусть требуется удалить из массива [1, 2, 3, 1, 5, 1, 7] значения, равные 1. Рассмотрим состояние массива на каждой из итераций:
Вместо заключения
В результате нам удалось превратить квадратичный алгоритм в линейный и значительно повысить производительность программы, в которой требуется удалять несколько элементов из массива. Сравнивая наивную реализацию и итоговую, кажется, что этот алгоритм даже проще, чем исходная версия с двумя циклами, по крайней мере по количеству операторов.

Программист, сооснователь programforyou.ru, в постоянном поиске новых задач и алгоритмов
Языки программирования: Python, C, C++, Pascal, C#, Javascript
Выпускник МГУ им. М.В. Ломоносова
Programforyou — это сообщество, в котором Вы можете подтянуть свои знания по программированию, узнать, как эффективно решать те или иные задачи, а также воспользоваться нашими онлайн сервисами.
C ++ Как удалить конкретную строку или столбец в динамически размещенном 2d массиве?
Если это не имеет смысла для вас напрямую, попробуйте прочитать мой 2D динамический массив (C) . Сосредоточиться на фигуре:

Я знаю, что моя ссылка на C, но то, что вы пытаетесь сделать, напоминает мне о C. В C ++, вы можете использовать std::vector<int> вместо.
Я предполагаю, что вы знаете, что вы можете написать:
Пример удаления первой строки в матрице из двух строк.
Другие решения
Вы можете удалить строку, просто позвонив
Вы не можете удалить столбцы, так как столбцы не выстроены в линию, как строки.
Например, допустим, у нас есть двумерный массив, подобный этому:
В компьютере данные на самом деле выстроены так:
Удалить ряд легко, так как компьютер выстроил их рядом друг с другом. Но поскольку строки создаются динамически, они НЕ должны располагаться рядом друг с другом. Они размещены везде, где есть свободное место.
Таким образом, столбцы не выстроены в очередь, и нет смысла «освобождать».
С 2D массивом векторов это просто.
Просто используйте функцию стирания для строк.
Для столбцов выполните итерации по строкам и удалите каждый элемент: