Как удалить строку из массива c
Перейти к содержимому

Как удалить строку из массива c

  • автор:

удаление строк в двумерном массиве

Удаление строки в двумерном массиве
Как удалить строку в двумерном массиве ?

Удаление нулевого стобца в двумерном массиве
Дана целочисленная матрица из n строк и m столбцов (1<n<=100, 1<m<=50). Задача — удалить каждый.

Удаление строки k в динамическом двумерном массиве
Привет всем. Столкнулся с неприятностью в выполнении лабораторной работы. По заданию нужно.

Удаление столбца в двумерном динамическом массиве
Необходимо удалить столбец, содержащий хотя бы один ноль, из двумерного динамического.

1505 / 968 / 812
Регистрация: 30.04.2016
Сообщений: 3,334

Лучший ответ

Сообщение было отмечено Margrau как решение

Решение

Margrau, здравствуйте! Совсем недавно занимался этим вопросом. Вот код для удаления строк, которые содержат хотя бы один нулевой элемент. Я иcпользовал дополнительный массив для хранения индексов удаляемых строк:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
#include using namespace std; void DeleteRow(int** X, int k, int N, int M) { for (int i = k; i  N - 1; i++) { for (int j = 0; j  M; j++) { X[i][j] = X[i+1][j]; } } } void MatrixInput(int** X, int N, int M) { for (int i = 0; i  N; i++) { for (int j = 0; j  M; j++) { cin >> X[i][j]; } } } void MatrixOutput(int** X, int N, int M) { for (int i = 0; i  N; i++) { for (int j = 0; j  M; j++) { cout  [i][j]  <" "; } cout  ; } } int main() { int N, M, k, p; cout  <"Введите размеры матрицы:"  ; cout  <"N = "; cin >> N; cout  <"M = "; cin >> M; int** A = new int*[N]; for (int i = 0; i  N; i++) { A[i] = new int[M]; } int* X = new int[N]; cout  <"Введите матрицу:"  ; MatrixInput(A, N, M); p = 0; for (int i = 0; i  N; i++) { k = 0; for (int j = 0; j  M; j++) { if (A[i][j] == 0) k++; } if (k > 0) { X[p] = i; p++; } } k = 0; while (k  p) { DeleteRow(A, X[k] - k, N, M); k++; } if (p == 0) cout  <"Ни одна строка не удалена!"  ; else if (p == N) cout  <"Все строки удалены!"  ; else { cout  <"Матрица после удаления:"  ; MatrixOutput(A, N - k, M); } for (int i = 0; i  N; i++) { delete[] A[i]; } delete[] X; system("pause"); return 0; }

Регистрация: 16.04.2019
Сообщений: 22

По сути удалить строку из матрицы нельзя, но если кому то нужно, то можно еще вот так сделать.
Здесь просто удаление нужной строки.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
#include #include #include #include #include #include main()  printf("Введите кол-во столбцов\n"); scanf("%d", &m); while(m1 || m>maxC) { printf("Некорректный ввод, попробуйте еще раз\n"); scanf("%d", &m);// уточняем необх кол-во столбцов(кол-во элементов строки) } srand(time(0)); //заполнение матрицы for(i=0;in; i++){ // внешний цикл перебирает индексы всех строк for(j=0; jm; j++) // внутренний цикл перебирает индексы элементов { a[i][j]=rand()%101-50; // заполнение случайн числами // для ввода с клавиатуры // printf("Введите %d эл-т %d строки\n", j+1, i+1); // scanf("%d", &a[i][j]); } } printf("Исходная матрица\n"); // вывод двумерного массива for(i=0; in; i++){ for(j=0; jm; j++) { printf("%4d", a[i][j]); } printf("\n"); } printf("\nВведите номер строки для удаления из массива \n"); scanf("%d",&stroka); for(i=stroka-1; in; i++){ // просматриваем массив с начала и до конца for(j=0;jm;j++){ a[i][j]=a[i+1][j]; } } n--; printf("\nМассив после удаления \n"); for(i=0; in; i++){ for(j=0; jm; j++) { printf("%4d", a[i][j]); } printf("\n"); } getch(); }

Удалить строку в массиве через указатель Си

Необходимо удалить из массива строку, в которой заданная буква встречается наибольшее количество раз. Проблема заключается в удалении строки по указателю. То есть, при присвоении строке NULL и при дальнейшем ее выводе через указатель, она не выводится. А при выводе массива целиком, она выводится, словно с ней ничего и не произошло. Вопрос — что тогда меняется по указателю?

#include #include #include #define N 80 #define M 5 void main(void)< char *abc[M]=,*p,**str,**cur,letter; int i=0,buf=0,max=0; str=abc; while(i printf("Enter the letter: "); scanf("%c", &letter); i=0; for(i=0;iwhile(*p!='\0'); if(buf>max) < p=abc[i]; max=buf; cur=&p; buf=0; >buf=0; > *cur=NULL; str=abc; i=0; while(i > 

Отслеживать
Whiskey Motel
задан 14 янв 2018 в 19:42
Whiskey Motel Whiskey Motel
108 1 1 серебряный знак 11 11 бронзовых знаков
Вы хотя бы отформатируйте код, смотрится вырвиглазно.
14 янв 2018 в 20:27
@MrBin отформатировал.
14 янв 2018 в 20:41

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

cur = &p; . *cur = NULL; 

обнуляет лишь какую-то локальную переменную p . На массив abc это обнуление никакого воздействия не оказывает. Потому вы и не видите никаких изменений в массиве abc .

Когда вы искали строку, вам надо было делать

а не какое-то непонятно зачем нужное cur = &p; .

Однако передавать нулевой указатель напрямую в puts нельзя — поведение не определено. Все просто упадет. Некоторые реализации может быть и заметят это и напечатают что-нибудь вроде (null) , но это не повод так поступать.

Отслеживать
ответ дан 14 янв 2018 в 21:44
AnT stands with Russia AnT stands with Russia
69k 3 3 золотых знака 62 62 серебряных знака 139 139 бронзовых знаков

Честно говоря, я по итогу сделал проще — просто избавился от указателя первого порядка, оставив только второй.

15 янв 2018 в 7:23

Честно говоря, разбираться в мельтешении вашего кода откровенно лень 🙂 Если это то, о чём я думаю (то есть просто обнулить указатель на строку в исходном массиве), то как-то так, например:

#include #include /* ---------------------------------------------------------- */ static size_t chars_count( const char *string, char c ) < size_t count = 0; while( string && *string ) < if( *string == c ) ++count; ++string; >return count; > /* ---------------------------------------------------------- */ static int del_strings( char *data[], size_t data_size, char c, size_t n ) < int removed = 0; for( size_t i = 0; i < data_size; ++i ) < size_t count = chars_count( data[i], c ); if( count >= n ) < ++removed; data[i] = NULL; >> return removed; > /* ---------------------------------------------------------- */ static void print_strings( const char *prefix, char *data[], size_t data_size ) < printf( "%s:\n", prefix ); for( size_t i = 0; i < data_size; ++i ) < printf( "[%zu] %s\n", i, data[i] ); >printf( "\n" ); > /* ---------------------------------------------------------- */ int main( void ) < char *abc[] = < "do you", "know de way", "my ugandian warrior", "just follow me", "in aarmy of ugaanda" >; #define ABC_SIZE (sizeof(abc) / sizeof(abc[0])) int rc; print_strings( "Before", abc, ABC_SIZE ); rc = del_strings( abc, ABC_SIZE, 'a', 2 ); print_strings( "After", abc, ABC_SIZE ); return rc; > 

Но имейте в виду, что это потенциально опасный подход.

Как удалить строку из массива c

Сообщения: 188
Благодарности: 0

Конфигурация компьютера
Процессор: Intel Pentium G3420 3.20GHz
Материнская плата: MSI B85-G41 PC Mate
Память: Kingston KVR1333D3N9/1G PC3-10600 1Gb (2x)
HDD: Seagate ST1000DM003-1CH162 (1Tb)
Видеокарта: ATI Radeon HD5670 1Gb DDR3
Звук: Realtek ALC887
Блок питания: FSP Group Inc. ATX-450PNF (450W)
Монитор: Samsung SA300 22» 1920×1080
ОС: Windows 7 Professional x86
Индекс производительности Windows: 5,5 Слабое место — RAM

Здравствуйте!
Теперь новая проблема. Нужно написать программу, принимающую на вход размер квадратного динамического массива и элементы массива. Программа должна удалить строки, содержащие особое число (под особым числом подразумевается число Фибоначчи, сумма цифр которого является простым числом (то есть, делится только на 1 и на само себя)). До этого с динамическими массивами дел не имел. Есть оператор free, но массив остаётся неизменным. Да и как я понимаю, чистится не вся строка, а только, почему то первые два элемента. Вообщем, помогите, пожалуйста. К теме прилагаю скрин с результатами.

#include #include int main() < int n, i, j, k, fib, fib1, fib2, cel, ost, sum, count; int **a; printf("Type size of matrix\n"); scanf("%d", &n); a=(int**)malloc(n*sizeof(int*)); if(a==NULL) printf("\nERROR"); for(i=0;ifor(i=0;i for(k=1;k <=sum;k++) if(sum%k==0) count++; >else continue; > if(count==2) < free (a[i]); break; >else continue; > printf("\nResult is\n"); for(i=0;i free (a); getch(); return 0; >

Сообщения: 4458
Благодарности: 994

alexprom65, раз пошла повторная задачка, оставляйте комментарий к логическим кускам кода.
Опять лезть в отладчик и делать реверс-инженеринг не тянет. Поймите правильно.

——-
— Я не разрешаю тебе быть плохой! Потому что плохие люди совершают плохие поступки. А это нехорошо!
(Из наставлений 5 летней девочки своей младшей сестре)

Как эффективно удалить элементы из массива

Превью к эффективному удаления значений из массива

Задача удаления заданных элементов из массива на первый взгляд кажется весьма простой. И на самом деле так оно и есть, однако зачастую начинающие программисты используют более сложный и тяжёлый с точки зрения производительности вариант алгоритма, из-за чего и кода становится больше и эффективность программы страдает. В учебных программах, когда количество элементов массива мало (порядка 10-100 элементов) оба алгоритма выполняются практически мгновенно. Однако при попытке написать наивный вариант в проекте, в котором работают с гигантскими массивами, приложение будет тратить ужасно много времени или вовсе надолго зависнет.

Как удалить одно значение из массива?

Начнём с более простого алгоритма — удаления одного элемента по индексу. Его отлично знают все начинающие разработчики: все элементы правее заданного индекса сдвинуть влево на 1 и уменьшить размер массива на единицу:

// удаление из массива array элемента по индексу index void RemoveValueAt(int *array, int &n, int index) < n--; // уменьшаем размер массива // сдвигаем элементы правее index влево for (int i = index; i < n; i++) < array[i] = array[i + 1]; >>

Этот алгоритм весьма простой и эффективный. К нему никаких претензий.

Наивный алгоритм удаления значений из массива

Когда же нужно удалить не один элемент из массива, а сразу несколько, в первую очередь в голову приходит мысль вызвать удаление по индексу несколько раз. Выглядеть это будет примерно следующим образом:

// удаление из массива array элементов равных value void RemoveValues(int *array, int &n, int value) < for (int i = n - 1; i >= 0; i--) < if (array[i] == value) < // если нужно удалить элемент RemoveAt(array, n, i); // удаляем его по текущему индексу >> >

В такой версии может показаться, что всё хорошо и алгоритм имеет линейную сложность. Но давайте заменим вызов функции RemoveAt на её тело:

// удаление из массива array элементов равных value void RemoveValues(int *array, int &n, int value) < for (int i = n - 1; i >= 0; i--) < if (array[i] == value) < // если нужно удалить элемент n--; // уменьшаем размер массива // сдвигаем элементы правее i влево for (int j = i; j < n; j++) < array[j] = array[j + 1]; >> > >

В таком виде всё куда очевиднее: при каждом удалении элемента выполняется вложенный цикл, из-за чего сложность удаления элеметнов равных заданному значению становится квадратичной. Можно ли как-то избавиться от вложенного цикла? Оказывается, можно, и, что самое главное, просто необходимо!

Эффективный алгоритм удаления элементов из массива

Наиболее проблемным местом наивного алгоритма является вложенный цикл. Именно от него мы и будем избавляться. Для этого заведём перед циклом переменную j , в которой будем хранить индекс для вставки элемента массива. Изначально значение этой переменной должно будет быть равно нулю.

В цикле по всем элементам от начала до конца будем проверять, надо ли удалять значение или нет. Если значение нужно оставить в массиве, то будем помещать его в массив по индексу j и увеличивать значение этого индекса. Пройдя весь массив, в переменной j будет находиться количество элементов массива после удаления, а потому нужно присвоить это значение размеру массива.

// удаление из массива array элементов равных value void RemoveValues(int *array, int &n, int value) < int j = 0; // новое положение в массиве for (int i = 0; i < n; i++) < if (array[i] != value) < // если не нужно удалять элемент array[j++] = array[i]; // помещаем элемент в новое место >> n = j; // обновляем размер массива >

Такой алгоритм имеет линейную сложность, поскольку проходит по массиву всего один раз, не выполняя внутри никаких «длительных» действий.

Пример работы данного алгоритма:

Пусть требуется удалить из массива [1, 2, 3, 1, 5, 1, 7] значения, равные 1. Рассмотрим состояние массива на каждой из итераций:

i = 0: j = 0, array = [(1), 2, 3, 1, 5, 1 7], 1 == 1 // пропускаем i = 1: j = 0, array = [1, (2), 3, 1, 5, 1 7], 2 != 1 // выполняем array[0] = array[1] => j = 1, array = [2, 2, 3, 1, 5, 1, 7] i = 2: j = 1, array = [2, 2, (3), 1, 5, 1 7], 3 != 1 // выполняем array[1] = array[2] => j = 2, array = [2, 3, 3, 1, 5, 1, 7] i = 3: j = 2, array = [2, 3, 3, (1), 5, 1 7], 1 == 1 // пропускаем i = 4: j = 2, array = [2, 3, 3, 1, (5), 1 7], 5 != 1 // выполняем array[2] = array[4] => j = 3, array = [2, 3, 5, 1, 5, 1, 7] i = 5: j = 3, array = [2, 3, 5, 1, 5, (1) 7], 1 == 1 // пропускаем i = 6: j = 3, array = [2, 3, 5, 1, 5, 1 (7)], 1 == 1 // выполняем array[3] = array[6] => j = 4, array = [2, 3, 5, 7, 5, 1, 7] j = 4 // количество элементов массива после удаления

Вместо заключения

В результате нам удалось превратить квадратичный алгоритм в линейный и значительно повысить производительность программы, в которой требуется удалять несколько элементов из массива. Сравнивая наивную реализацию и итоговую, кажется, что этот алгоритм даже проще, чем исходная версия с двумя циклами, по крайней мере по количеству операторов.

Фото Перминова Андрея, автора этой статьи

Программист, сооснователь programforyou.ru, в постоянном поиске новых задач и алгоритмов

Языки программирования: Python, C, C++, Pascal, C#, Javascript

Выпускник МГУ им. М.В. Ломоносова

Programforyou — это сообщество, в котором Вы можете подтянуть свои знания по программированию, узнать, как эффективно решать те или иные задачи, а также воспользоваться нашими онлайн сервисами.

Copyright © 2017 — 2023 Programforyou — помощь с программированием | programforyou.ru

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *