Форум: "Начинающим";
Текущий архив: 2006.08.06;
Скачать: [xml.tar.bz2];
ВнизДобавление записи в динамический массив Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.056 c