Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.08.06;
Скачать: CL | DM;

Вниз

Добавление записи в динамический массив   Найти похожие ветки 

 
XeON ©   (2006-07-12 23:45) [0]

Здравствуйте уважаемые мастера. Прошу вашей помощи! Подскажите пожалуйста, как добавить запись в динаммический массив в опреденный индекс. При этом остальные записи дожны сместиться вниз на 1у. Надеюсь мой вопрос понятен. Всем спасибо за внимание!


 
XeON ©   (2006-07-12 23:54) [1]

Если это как-то относиться к делу, то массив состоит из записей (TRecord).


 
Rial ©   (2006-07-13 03:16) [2]

За одно действие - никак.
Используй TList, что даст видимость этого действа.

И лучше всего, сделать двусторонний список.

Type ptRec=^TRec;
       TRec=record
        Next, Prev : ptRec;
        Data : Pointer;
       end;


 
Loginov Dmitry ©   (2006-07-13 07:53) [3]

> Подскажите пожалуйста, как добавить запись в динаммический
> массив в опреденный индекс.


Самый простой способ: увеличиваешь размер динамического массива, затем смещаешь все элементы, начиная с позиции ставки, на 1у (эту операцию лучше реализовать поэлементным присваиванием), затем на место вставки записываешь новый элемент.

Этот способ простой, но работает медленно. Для ускорения работы используй концепцию списков.


 
evvcom ©   (2006-07-13 08:34) [4]

> (эту операцию лучше реализовать поэлементным присваиванием)

чем это лучше Move и FillChar?

> Этот способ простой, но работает медленно.

Потому и медленно, что поэлементно.


 
XeON ©   (2006-07-13 08:50) [5]

Спасибо. Пойду попробую что-нибудь сделать!


 
SergP ©   (2006-07-13 10:04) [6]

> Добавление записи в динамический массив
> [D6, D2005, XP, 2003]
>
>
> [0] XeON ©   (12.07.06 23:45)


Тут где-то был топик про удаление записи из массива,

так вот: при вставке нужно сделать все в обратном порядке


 
XeON ©   (2006-07-13 13:28) [7]

Про удаление - это мой топик. С удалением всё понятно. Я просто забыл указать размер массива в самом начале - поэтому не удалялось! А вот со вставкой совсем косяк. У меня есть процедура готовая:
procedure addElem( var A: TRectArray; Index: integer;
                                      ANew: TRect );
var Len : integer;
begin
  Len:= Length( A );
  if Index > = Len then Index := Len+1;
  setLength( A, Len+1);
  move( A[Index], A[ Index+1 ],
        (Len-Index) * sizeof( A[Index] ));
  A[Index] := ANew;
end;


Но она отказывается работать! И самому что-то в голову ничего не лезет по этому поводу!


 
Sapersky   (2006-07-13 14:26) [8]

if Index > Len then Index := Len;
И перевыделять память по одному элементу не есть хорошо.


 
XeON ©   (2006-07-13 14:37) [9]

Мне не важно, что там с памятью! Главное, что бы работало. Если я до конца недели не сделаю эту ерунду - то накроется моя работа "медным тазом".


 
Loginov Dmitry ©   (2006-07-13 14:56) [10]

> чем это лучше Move и FillChar?


Если используются обычные типы, то ничем, а если типы с управляемым временем жизни, то - Х.З. Зачем рисковать?


> Потому и медленно, что поэлементно.


Неправда! Медленно не потому, что поэлементно, а потому, что размер массива каждый раз увеличивается на 1 (без применения "концепции" списков).


> Но она отказывается работать!


Её право! При извользовании Move нельзя допускать пересечение буфера источника и буфера приемника.


 
XeON ©   (2006-07-13 15:09) [11]

Всё! Разобрался, мать его! Функция move загребала. Пришлось сделать так:
A: Array of XXX;
...
A[i+1]:=A[i];
...
end;

Так элементы стали переносится по нормальному. И Цикл While пришлось заменить на For при рекурсии массива.
Кстати! У меня всё работает быстро. Т.к. величина массива думаю не будет увеличиваться больше чем на 999 элементов. Думаю, что там даже 100 элементов не наберётся... И вообще, ProgressBar - рулит! Пусть там хоть 1 000 000 000 элементов втыкают! Это уже не мои проблемы.

Всем огромное спасибо за внимание. Осталось только перенести всю эту байду на Visual C++ 6 и придумать, как это сделать... :)

P.S. Тема закрыта.


 
Рамиль ©   (2006-07-13 15:17) [12]

> И вообще, ProgressBar - рулит! Пусть там хоть 1 000 000
> 000 элементов втыкают! Это уже не мои проблемы.

*завуалированный мат*


 
Loginov Dmitry ©   (2006-07-13 15:19) [13]

> У меня всё работает быстро


Если элементы массива не менее 4-х байт (лучше, если они кратны 4-м байтам), то чувствительной разницы между Move и использованием цикла не будет.


 
Sapersky   (2006-07-13 15:34) [14]

Если используются обычные типы, то ничем, а если типы с управляемым временем жизни, то - Х.З. Зачем рисковать?

См. TStringList.InsertItem.


 
begin...end ©   (2006-07-13 15:44) [15]

> Loginov Dmitry ©   (13.07.06 14:56) [10]

> При извользовании Move нельзя допускать пересечение буфера
> источника и буфера приемника.

Можно.


 
Rial ©   (2006-07-13 16:04) [16]


> Loginov Dmitry ©   (13.07.06 14:56) [10]
> Её право! При извользовании Move нельзя допускать пересечение
> буфера источника и буфера приемника.


Ан нет.
Посмотри код этой процедуры.
Там ясно сказано, что
       CMP     EDI,ESI
       JA      @@down
И копирутся это дело с конца начиная.


 
Loginov Dmitry ©   (2006-07-13 19:18) [17]

> Там ясно сказано, что
>       CMP     EDI,ESI
>       JA      @@down


УУУУ... Я китайский не изучал...

;-)


 
SergP.   (2006-07-13 20:51) [18]

> procedure addElem( var A: TRectArray; Index: integer;
>                                      ANew: TRect );
> var Len : integer;
> begin
>  Len:= Length( A );
>  if Index > = Len then Index := Len+1;
>  setLength( A, Len+1);
>  move( A[Index], A[ Index+1 ],
>        (Len-Index) * sizeof( A[Index] ));
>  A[Index] := ANew;
> end;


Ошибка однако...

 if Index >= Len then Index := Len;


 
Суслик ©   (2006-07-13 20:56) [19]

мой опыт - не заморачивайся и:
1. увеличивай размер на 1
2. смещай все что после (обычным циклом)
3. в новое место вставляй свое.

можно сделать производительней, но это зависит от задачи.
может и не стоит с этим возиться.


 
evvcom ©   (2006-07-13 23:08) [20]

> [10] Loginov Dmitry ©   (13.07.06 14:56)
> а если типы с управляемым временем жизни, то - Х.З. Зачем
> рисковать?

Никакого риска. Move + FillChar будет однозначно быстрее, компактнее и пр., чем циклы.
> > Потому и медленно, что поэлементно.
>
> Неправда! Медленно не потому, что поэлементно, а потому,

И поэтому тоже. Причем поэлементное копирование все-таки тем большие тормоза будет создавать в сравнении с тормозами по единичному увеличению размера массива, чем больше будет размер данных типов с управляемым временем жизни.

> При извользовании Move нельзя допускать пересечение буфера
> источника и буфера приемника

Ну, уже ответили в [15] и [16].

> [11] XeON ©   (13.07.06 15:09)
> И вообще, ProgressBar - рулит!

Да, прогресбар вообще очень универсальный компонент. Ему под силу все! И данные копировать, и файлы из интернета выкачивать, и чего там еще в орешнике он умеет? :-)

> [13] Loginov Dmitry ©   (13.07.06 15:19)

Ой, не понимаешь ты того, о чем говоришь. :(

> [17] Loginov Dmitry ©   (13.07.06 19:18)

Китайский учить все же полезно. Многое ясным становится.



Страницы: 1 вся ветка

Текущий архив: 2006.08.06;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.058 c
1-1150393322
Urvin
2006-06-15 21:42
2006.08.06
Цвет выделения в ListView


2-1152689581
Mamed
2006-07-12 11:33
2006.08.06
Osvejit ekran


4-1145148582
Ку Ку
2006-04-16 04:49
2006.08.06
Консольное приложение, глюки с кодировкой


15-1152129267
Ketmar
2006-07-05 23:54
2006.08.06
Килт Пречлер "Белые ночи Полидевка"


2-1152889248
Megabyte
2006-07-14 19:00
2006.08.06
Компонент ClientDataSet