Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Добавление записи в динамический массив [D6, D2005, XP, 2003]


XeON ©   (2006-07-12 23:45:00) 

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


evvcom   (2006-07-13 23:08:00) [1]

> [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)

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


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

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

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


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

> 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;


Loginov Dmitry   (2006-07-13 19:18:00) [4]

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


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

;-)


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


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


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


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

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

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

Можно.


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

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

См. TStringList.InsertItem.


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

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


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


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

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

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


XeON   (2006-07-13 15:09:00) [10]

Всё! Разобрался, мать его! Функция 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. Тема закрыта.


Loginov Dmitry   (2006-07-13 14:56:00) [11]

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


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


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


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


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


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


XeON   (2006-07-13 14:37:00) [12]

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


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

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


XeON   (2006-07-13 13:28:00) [14]

Про удаление - это мой топик. С удалением всё понятно. Я просто забыл указать размер массива в самом начале - поэтому не удалялось! А вот со вставкой совсем косяк. У меня есть процедура готовая:
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;


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


SergP   (2006-07-13 10:04:00) [15]

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


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

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


XeON   (2006-07-13 08:50:00) [16]

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


evvcom   (2006-07-13 08:34:00) [17]

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

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

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

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


Loginov Dmitry   (2006-07-13 07:53:00) [18]

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


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

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


Rial   (2006-07-13 03:16:00) [19]

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

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

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


XeON   (2006-07-12 23:54:00) [20]

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


Наверх

Титульная страница Поиск, карта сайта Написать письмо