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

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
Sunspot
Сообщения: 2
Зарегистрирован: 04 сен 2006, 09:09
Контактная информация:

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


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;

В конец массива добавляется без проблем, а вот в любое другое место не получается. Что не так???
Аватара пользователя
LAngel
Сообщения: 277
Зарегистрирован: 30 мар 2005, 08:19
Откуда: Ульяновск
Контактная информация:

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

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;
(извиняюсь, подправился немного :) )
С уважением, Lost Angel...
Sunspot
Сообщения: 2
Зарегистрирован: 04 сен 2006, 09:09
Контактная информация:

Спасибо, очень помог.
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

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 гораздо быстрее, хоть и менее понятен.
It's a long way to the top if you wanna rock'n'roll
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

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 байт меньше, чем нужно?
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Нет, имелось ввиду, что Нужно = (Length(X)-Index) * sizeof(Integer), дабы обратить внимание на ненужное добавление единицы.
Выразился, конечно, непонятно - признаю ...
It's a long way to the top if you wanna rock'n'roll
Ответить