Форум: "Прочее";
Текущий архив: 2012.02.26;
Скачать: [xml.tar.bz2];
ВнизУдаление элемента со сдвигом из массива array of record Найти похожие ветки
← →
xss22 © (2011-11-09 18:19) [0]Здравствуйте!
Есть массив:Player : array of record
Addr : TSockAddrIn;
Nick :string[15];
PosX: Single;
PosY: Single;
PosZ: Single;
IdMap : string[4];
end;
Как удалить элемент со сдвигом?
← →
Jeer © (2011-11-09 18:20) [1]Связанный список вместо array.
← →
xss22 © (2011-11-09 18:21) [2]
> Jeer © (09.11.11 18:20) [1]
>
> Связанный список вместо array.
Ответ не понятен.
← →
Jeer © (2011-11-09 18:23) [3]Гугл не знает о тебе, но знает о структуре данных "связанный список":
http://ru.wikipedia.org/wiki/%D0%A1%D0%B2%D1%8F%D0%B7%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA
Можно и через array, тогда изволь копировать самостоятельно рекорды по цепочке.
А потом еще захочешь вставку :)
← →
DVM © (2011-11-09 18:28) [4]
> Как удалить элемент со сдвигом?
Move + SetLength() вероятно тебе помогут, если нужен именно массив.
Но Move будет затратная операция при большом массиве.
← →
xss22 © (2011-11-09 18:29) [5]у меня есть:
Player : array of record
Addr : TSockAddrIn;
Nick :string[15];
PosX: Single;
PosY: Single;
PosZ: Single;
IdMap : string[4];
end;
Я могу добавлять новый элемент, присваивать и считывать значения.
Мне необходима процедура, которая бы удаляла элемент со сдвигом.
Нужен конкретный пример, без высокомерия и посылания в гугл.
Я прошу о помощи здесь, а не на гугле.
← →
Rouse_ © (2011-11-09 18:39) [6]Процедура называется move(), но связанный список лучше и оптимальней...
← →
Sha © (2011-11-09 18:39) [7]> Я могу добавлять новый элемент, присваивать и считывать значения.
ну так повторяй в циклеa[i]:=a[i+1];
← →
Inovet © (2011-11-09 18:50) [8]Тебе подсказывают, а ты ещё и нос воротишь. Не кажется что из-за собственной ограниченности?
← →
xss22 © (2011-11-09 19:10) [9]
> Sha © (09.11.11 18:39) [7]
>
> > Я могу добавлять новый элемент, присваивать и считывать
> значения.
>
> ну так повторяй в цикле
> a[i]:=a[i+1];
спасибо!!!
← →
Ega23 © (2011-11-09 19:35) [10]
unit Unit12;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm12 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
strict private type
TMyRecord = record
Field1: Integer;
Field2: string;
end;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form12: TForm12;
implementation
{$R *.dfm}
procedure TForm12.Button1Click(Sender: TObject);
var
arr: array of TMyRecord;
i, Index, arrLen: Integer;
begin
arrLen := StrToInt(Edit1.Text);
Index := StrToInt(Edit2.Text);
SetLength(arr, arrLen);
for i := 0 to arrLen - 1 do
begin
arr[i].Field1 := i + 1;
arr[i].Field2 := IntToStr(i + 1);
end;
for i := 0 to Length(arr) - 1 do
Memo1.Lines.Add(arr[i].Field2);
Memo1.Lines.Add("------");
// Удаляем элемент Index
if (Index >= 0) and (Index < (arrLen - 1)) then
begin
Dec(arrLen);
System.Move(arr[Index + 1], arr[Index],
(arrLen - Index) * SizeOf(TMyRecord));
SetLength(arr, arrLen);
end;
for i := 0 to Length(arr) - 1 do
Memo1.Lines.Add(arr[i].Field2);
Memo1.Lines.Add("------");
end;
end.
← →
Ega23 © (2011-11-09 19:38) [11]эээ, косячок...
if (Index >= 0) and (Index < arrLen) then
begin
Dec(arrLen);
if Index < arrLen - 1 then
System.Move(arr[Index + 1], arr[Index],
(arrLen - Index) * SizeOf(TMyRecord));
SetLength(arr, arrLen);
end;
← →
Sha © (2011-11-09 19:41) [12]> Ega23
как насчет утечек?
← →
CRLF (2011-11-09 19:42) [13]У меня несоздаёца Unit12 у меня Unit1 што делать!!!11111
← →
Dennis I. Komarov © (2011-11-09 20:00) [14]
> Процедура называется move(),
А в массиве лучше хранить не запись, а указатель
> но связанный список лучше и оптимальней...
← →
Ega23 © (2011-11-09 20:08) [15]
> как насчет утечек?
хм... Кстати да, не подумал.
if (Index >= 0) and (Index < arrLen) then
begin
Dec(arrLen);
if Index < arrLen - 1 then
begin
arr[Index].Field2 := "";
System.Move(arr[Index + 1], arr[Index],
(arrLen - Index) * SizeOf(TMyRecord));
end;
SetLength(arr, arrLen);
end;
Я вообще этот код с TList содрал, там строк и всяких интерфейсов нет.
← →
Ega23 © (2011-11-09 20:10) [16]Да, в TInterfaceList так и сделано
procedure TInterfaceList.Delete(Index: Integer);
begin
with FList.LockList do
try
Self.Put(Index, nil);
Delete(Index);
finally
Self.FList.UnlockList;
end;
end;
← →
Sha © (2011-11-09 20:22) [17]> Ega23
Теперь с "дыркой" порядок,
а последний элемент все еще показывает в космос.
← →
Ega23 © (2011-11-09 20:24) [18]
> а последний элемент все еще показывает в космос.
Чё это?
if (Index >= 0) and (Index < arrLen) then
begin
Dec(arrLen); // <--- Уменьшили на 1
if Index < arrLen - 1 then
System.Move(arr[Index + 1], arr[Index],
(arrLen - Index) * SizeOf(TMyRecord));
SetLength(arr, arrLen); // <--- выкинули последний
end;
← →
Kerk © (2011-11-09 20:28) [19]Одно удовольствие на такие ветки со скриптом подсветки синтаксиса смотреть :)
Сорри за оффтоп.
← →
Sha © (2011-11-09 20:34) [20]> Ega23 © (09.11.11 20:24) [18]
Неа. Не это.
Когда создал последнюю строку у нее RefCt=1.
Потом Move() скопировал указатель, но RefCt остался тем же.
Потом SetLength() финализировал строку, ее нет в ОП,
память стала доступна для повторного использования.
Но указатель последней записи выставлен на эту грязь.
← →
Ega23 © (2011-11-09 20:38) [21]
> Но указатель последней записи выставлен на эту грязь.
Ну и что? У меня же уже нет этой последней записи, я про неё ничего не знаю.
← →
Sha © (2011-11-09 20:48) [22]Новая последняя запись, которая раньше была предпоследней,
теперь содержит указатель на память, где раньше хранилась строка,
которая в данный момент уже финализирована.
← →
Ega23 © (2011-11-09 21:25) [23]А, вон ты о чём...
Вот по этому давно предпочитаю класс создать... :)
← →
Sha © (2011-11-09 21:42) [24]Дело тут не в классе,
а в корректном использовании Move() типами, подсчитавающими ссылки.
← →
Sha © (2011-11-09 21:45) [25]* подсчитывающими
← →
Омлет © (2011-11-09 23:01) [26]> Kerk © (09.11.11 20:28) [19]
> Одно удовольствие на такие ветки со скриптом подсветки синтаксиса смотреть :)
Да! :)
← →
Бездомный (2011-11-10 11:34) [27]
> Sha © (09.11.11 20:48) [22]
А решение?
а) не использовать для этих целей move;
b) финализировать удаляемый элемент самостоятельно и nil-ить "хвост" перед обрезанием (как звучит то);
c) или еще чего нить? :)
← →
RWolf © (2011-11-10 11:47) [28]заменить array of record на TObjectList.
← →
Romkin © (2011-11-10 14:03) [29]
> А, вон ты о чём...Вот по этому давно предпочитаю класс создать.
> .. :)
Move со сложными типами почти всегда засада, не тот уровень абстракции.
Класс создается с выбором "внутренностей" под конкретную задачу, с учетом набора возможных операций. Можно насоздавать контейнеров заранее, но не так просто предугадать что понадобится.
← →
Sha © (2011-11-10 15:19) [30]> Бездомный (10.11.11 11:34) [27]
На мой взгляд, лучше всего a),
если совсем приперло, то c) - отдельные процедуры финализации и зачистки,
и ни в коем случае или с кучей комментариев и оправданий b).
← →
Sha © (2011-11-10 19:53) [31]> Бездомный
В качестве альтернативы c) еще чего-нить:
код [15] становится почти работающим, если, например, заменить
arr[Index].Field2 := "";
на
arr[Index].Field2 := arr[arrLen - 1].Field2;
Предостережение. Не пробуйте повторить это.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2012.02.26;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.005 c