Перейти к содержимому

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

  • автор:

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

Здравствуйте, vim, Вы писали:

vim>есть char* line;
vim>как удалить некоторое количество символов с конца

line[pos] = '\0';

Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Как удалить символ с конца в символьном массиве

От: Кодт
Дата: 22.08.06 16:31
Оценка:

Здравствуйте, vim, Вы писали:

vim>есть char* line;
vim>как удалить некоторое количество символов с конца

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

В Си нет примитивного типа «строка», он эмулируется с помощью массива символов — начало массива известно по указателю, а конец — элемент со значением ‘\0’ (он же 0).
Поэтому самый дубовый способ — это
— найти длину строки, l = strlen(p), wcslen(p), _tcslen(p) если строка байтовая, юникодная или tchar’овая соответственно
— отсчитать «некоторое количество» t, новая длина nl = l-t
— пометить соответствующий элемент как концевой p[nl] = 0
Хвост массива становится бесполезным, но никуда из памяти не девается до тех пор, пока ты не выполнишь определённые действия. Это зависит от того, как массив был размещён:
— в статическом или автоматическом хранилище (т.е. локальная или глобальная переменная), а также как член структуры или класса — поменять размер невозможно, да и не нужно
— с помощью malloc() — можно сделать p = realloc(p, (nl+1)*sizeof(*p)) где +1 — учитываем концевой ноль, sizeof(*p) — размер элемента массива (char, WCHAR, wchar_t, TCHAR)
— с помощью new CharType[N] — легального способа нет
— в vector — vec.resize(nl+1)
— в string, wstring — незачем применять дубовый способ

Если же исходный массив трогать нельзя, то дубовый способ номер два — это
— разместить новый массив np размера nl+1
— скопировать туда первые nl элементов строки — strncpy, strcpy_s, lstrcpyn, memcpy, std::copy
— не забыть записать маркер конца np[nl] = 0 (функция lstrcpyn делает это сама)

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

Я только недавно познакомился с массивами, поэтому и вопрос дилетантский. Итак, я разбиваю строку «Hello, World!» на символьный массив, допустим, мне нужно убрать пробел. Я думал использовать Esc-последовательность ‘\b’, но почему-то она затирает 2 символа.

using namespace std; int main() < char arr[13]< 'H','e','l','l', 'o', ',', ' ', 'W', 'o','r', 'l', 'd', '!' >; int i, j; for (i = 0; i < 13; i++) < if (arr[i] == ' ') arr[i] = '\b'; >for (j = 0; j

После этого в консоли получается «HelloWorld!». Не понимаю, почему удалились сразу ‘ ‘ и ‘,’ . Подскажите пожалуйста, как универсально и эффективно затирать символы из массива?

Отслеживать

задан 18 июн 2021 в 14:09

Makar Kosenko Makar Kosenko

27 5 5 бронзовых знаков

Как удалить элемент массива?

Доброго времени суток! Задача следующая:
1) Сформировать одномерный массив целых чисел, используя датчик случайных чисел.
2) Распечатать полученный массив.
3) Удалить элемент с номером К.
4) Добавить после каждого четного элемента массива элемент со значением 0.
5) Распечатать полученный массив.
Первые два пункта получилось сделать,но я не могу понять,как сделать 3 и 4 пункты. Векторы еще не изучал,так что,если не составит труда,объясните пожалуйста человеческим языком,какой алгоритм нужен для решения задач подобного рода.Спасибо)

  • Вопрос задан более трёх лет назад
  • 51900 просмотров

Комментировать
Решения вопроса 1

gbg

Армянское Радио @gbg Куратор тега C++
Любые ответы на любые вопросы

Третий пункт решается просто — вам нужно передвинуть элементы в массиве: присвоить a[i]=a[i+1] в цикле.
Я думаю, вам запрещено использовать STL, так что пишите циклы.

Формат данного сайта запрещает совмещать кучу вопросов в один, так что постарайтесь разделить темы.

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

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

Задача удаления заданных элементов из массива на первый взгляд кажется весьма простой. И на самом деле так оно и есть, однако зачастую начинающие программисты используют более сложный и тяжёлый с точки зрения производительности вариант алгоритма, из-за чего и кода становится больше и эффективность программы страдает. В учебных программах, когда количество элементов массива мало (порядка 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 не будет опубликован. Обязательные поля помечены *