Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.05.2011, 10:27   #1
mrCloud
Пользователь
 
Аватар для mrCloud
 
Регистрация: 13.05.2011
Сообщений: 42
По умолчанию Удаление элемента динамического массива

Есть тип например
Код:
TValues = record
   Price,term:integer;
 end;
и по нему создан динамический массив
Код:
var
Valies:array of TValues
Вопрос: как удалить элемент с заданным индексом?
mrCloud вне форума Ответить с цитированием
Старый 14.05.2011, 11:41   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Пусть надо удлить элемент с индексом K
в цикле сдвигаете все элементы K+1 на место предыдущего.
после чего изменяете размер массива.
Код:
for i:=K+1 to Length(Valies)-1 do
   Valies[i-1] := Valies[i];
SetLength(Valies, Length(Valies) - 1);
Внимание. Вообще операции изменения размера динамического массива ресурсоёмкие. А тут ещё и цикл (представьте, Вы удаляете 2-й элемент в массиве из миллиона элементов. Надо 999998 элементов переместить в памяти. Это весьма не быстро.

Поэтому рекомендую посмотреть в сторону связных динамиских списков. Там опреция удаления сводится к изменению ссылки(или пары ссылок) и очистке памяти одного элемента. Это практически мгновенно происходит (т.е. не затрагивает остальные элементы этой динамической структуры)

Последний раз редактировалось Serge_Bliznykov; 14.05.2011 в 12:34.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 14.05.2011, 11:42   #3
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

если порядок не важен, вместо сдвига можно менять местами с последним элементом

Код:
Length(Valies)
возвращает количество элементов в массиве, а нумеруются они с 0. Так что или - 1 добавить, или лучше использовать high().
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось veniside; 14.05.2011 в 11:47.
veniside вне форума Ответить с цитированием
Старый 14.05.2011, 12:34   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Length(Valies)
возвращает количество элементов в массиве, а нумеруются они с 0. Так что или - 1 добавить, или лучше использовать high().
согласен. важное замечание. Это я ошибся.
исправил в исходном сообщении

Цитата:
если порядок не важен, вместо сдвига можно менять местами с последним элементом
и с этим согласен. Хотя мне связные списки всё равно как-то больше нравятся
Serge_Bliznykov вне форума Ответить с цитированием
Старый 14.05.2011, 14:48   #5
chertovich
Форумчанин
 
Аватар для chertovich
 
Регистрация: 26.07.2009
Сообщений: 489
По умолчанию

Цитата:
Сообщение от mrCloud Посмотреть сообщение
Есть тип например
Код:
TValues = record
   Price,term:integer;
 end;
и по нему создан динамический массив
Код:
var
Valies:array of TValues
Вопрос: как удалить элемент с заданным индексом?
Удалить из массива элемент просто так нельзя (потому что элементы массива всегда хранятся в соседних ячейках памяти), это делается при помощи того, что заново перераспределяют память на массив, но как было сказано, это сильно влияет на производительность.
Но лучшим (по производительности, но не по размеру памяти) сделать поле флаг, который будет означать, обрабатывать или нет этот элемент массива
Код:
TValues = record
  Price,term:integer;
  Exist: Boolean;
end;
...
for I := 0 to High(Valies) do
begin
  if Valies[I].Exist then
  begin
    // Обработка
  end;
end;
И для "удаления" (исключения из обработки) присваиваем Valies[I].Exist := False;

Но если все-таки хочешь удаление, то
Код:
  TValues = record
    Price, Term:integer;
  end;
  TValuesArr = array of TValues;

var
  Form1: TForm1;
  V: TValuesArr;

function DeleteEl(V: TValuesArr; Index: Integer): TValuesArr;

implementation

{$R *.dfm}

function DeleteEl(V: TValuesArr; Index: Integer): TValuesArr;
var
  NewSize: Integer;
  I, Ind: Integer;
begin
  NewSize := Length(V) - 1;
  if Index > NewSize {Length(V) - 1} then
    raise Exception.Create('Указанный элемент не существует');
  SetLength(Result, NewSize);

  Ind := 0;
  for I := 0 to High(V) do
  begin
    if I <> Index then
    begin
      Result[Ind] := V[I];
      Inc(Ind);
    end;
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetLength(V, 5);
  V := DeleteEl(V, 4);
end;
Если в глубине души вы программист, то, следуя своим наклонностям, вы захотите написать кусок кода.

Последний раз редактировалось chertovich; 14.05.2011 в 15:04.
chertovich вне форума Ответить с цитированием
Старый 14.05.2011, 18:20   #6
mrCloud
Пользователь
 
Аватар для mrCloud
 
Регистрация: 13.05.2011
Сообщений: 42
По умолчанию

Спасибо огромное получилось
mrCloud вне форума Ответить с цитированием
Старый 03.11.2012, 10:24   #7
Sёker
Пользователь
 
Регистрация: 30.09.2011
Сообщений: 27
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Пусть надо удлить элемент с индексом K
в цикле сдвигаете все элементы K+1 на место предыдущего.
после чего изменяете размер массива.
Код:
for i:=K+1 to Length(Valies)-1 do
   Valies[i-1] := Valies[i];
SetLength(Valies, Length(Valies) - 1);
Внимание. Вообще операции изменения размера динамического массива ресурсоёмкие. А тут ещё и цикл (представьте, Вы удаляете 2-й элемент в массиве из миллиона элементов. Надо 999998 элементов переместить в памяти. Это весьма не быстро.

Поэтому рекомендую посмотреть в сторону связных динамиских списков. Там опреция удаления сводится к изменению ссылки(или пары ссылок) и очистке памяти одного элемента. Это практически мгновенно происходит (т.е. не затрагивает остальные элементы этой динамической структуры)
А что, если использовать функцию move? Я бы сделал так. Спрашиваю, потому что: "Вдруг нельзя"

Ни решает ли процедура функции Move проблему затрат времени при удалении элемента из массива?

Последний раз редактировалось Stilet; 03.11.2012 в 12:30.
Sёker вне форума Ответить с цитированием
Старый 03.11.2012, 12:31   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

В принципе решает.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
удаление элемента из массива Dmitry73 Помощь студентам 3 02.12.2010 09:10
Удаление строки из двумерного динамического массива hidraulik Общие вопросы C/C++ 0 08.12.2009 10:48
Удаление динамического массива Сергей089 Общие вопросы C/C++ 3 08.03.2009 13:13
Удаление элементов из динамического массива dashulka Общие вопросы Delphi 4 31.10.2008 14:03
Удаление элемента динамического массива Dogmat Помощь студентам 6 13.07.2008 14:33