Страница 1 из 1

Динамические массивы. Вставка элементов.

Добавлено: 04 сен 2006, 09:31
Sunspot
Господа специалисты, пожалуйста, помогите добавить новые элементы в середину динамического массива.
Делаю следующим образом:


type
TArrayString = array of integer;
...
Procedure InArrayIndex( var X: TArrayString; Index: integer; ANew: integer );
begin
if Index >= Length(X) then Index := Length( X );
setLength(X, Length(X)+1);
move(X[Index], X[Index+1], (Length(X)-Index) * sizeof(Integer)+1);
X[Index] := ANew;
end;

В конец массива добавляется без проблем, а вот в любое другое место не получается. Что не так???

Добавлено: 04 сен 2006, 14:50
LAngel

Код: Выделить всё

Procedure InsertValue(var X: TArrayString; Index: Integer; Anew: Integer);
var
  i: Integer;
begin
  if (Index < Low(X)) or (Index > High(X)) then
    Raise Exception.Create('Range check error');
  SetLength(X, Length(X)+1);
  i := High(X);
  while i > Index do begin X[i] := X[i-1]; dec(i); end;
  X[Index] := ANew;
end;
(извиняюсь, подправился немного :) )

Добавлено: 05 сен 2006, 07:19
Sunspot
Спасибо, очень помог.

Добавлено: 06 сен 2006, 15:06
somewhere
move(X[Index], X[Index+1], (Length(X)-Index) * sizeof(Integer)+1);
Уважаемый SunSpot, вообщем-то все правильно, но только 1 не там должна быть.

move(X[Index], X[Index+1], (Length(X)-Index+1) * sizeof(Integer));

а иначе переместиться на 1 байт больше, чем надо и массив попортиться
Реализация предложенная LAngel работает ГОРАЗДО медленее, и с точки зрения оптимизации работы с МАССИВАМИ непригодна.
Ваш вариант через move гораздо быстрее, хоть и менее понятен.

Добавлено: 06 сен 2006, 15:34
BBB
somewhere писал(а):
move(X[Index], X[Index+1], (Length(X)-Index) * sizeof(Integer)+1)]

Уважаемый SunSpot, вообщем-то все правильно, но только 1 не там должна быть.

move(X[Index], X[Index+1], (Length(X)-Index+1) * sizeof(Integer));

а иначе переместиться на 1 байт больше....
Исключительно формальный подсчет:

В первом варианте перемещается QTY1 = (Length(X)-Index) * sizeof(Integer)+1 байт

Во втором случае:
QTY2 = (Length(X)-Index+1) * sizeof(Integer) =
(Length(X)-Index) * sizeof(Integer) + 1 * sizeof(Integer) =
(QTY1 - 1) + sizeof(Integer) = QTY1 + (sizeof(Integer) - 1)


Поскольку, все-таки, sizeof(Integer) > 1, то получаем, что QTY2 > QTY1
То есть, во втором приведенном примере байт переместится БОЛЬШЕ, чем в первом.

Наверное, имелось в виду, что в первом случае переместится на 1 байт меньше, чем нужно?

Добавлено: 06 сен 2006, 16:06
somewhere
Нет, имелось ввиду, что Нужно = (Length(X)-Index) * sizeof(Integer), дабы обратить внимание на ненужное добавление единицы.
Выразился, конечно, непонятно - признаю ...