Консультация № 173862
31.10.2009, 19:15
0.00 руб.
0 7 1
Доброго времени суток, передо мной встала следущая задача:
имеются большие списки в таком формате:
1
2
3
4
и тд, задача с максимальной скоростью эти списки перемешать, делаю это так:
for i:=0 to RandList2.Count-1 do begin
Randomize;
p3:=random(Randlist2.Count-1);
outRandlist2.Add(Randlist2[p3]);
Randlist2.Delete(p3);
end;
но это занимает ужасно много времени, есть ли способ ускорить данный процесс?

Обсуждение

давно
Профессионал
153662
1070
31.10.2009, 19:27
общий
Для начала из этого кода уберите RandList2.Count-1, присвоив это значение какой-нибудь переменной типа integer, после чего посмотрите на сколько увеличится скорость обработки цикла. Здесь при каждом проходе вызывается количество строк списка, это тормозит работу цикла.
Код:
var
j: integer;
begin
j:= Randlist2.Count-1;
for i:=0 to j do begin
Randomize;
p3:=random(j);
outRandlist2.Add(Randlist2[p3]);
Randlist2.Delete(p3);
j:= j-1;
end;
end;
Об авторе:
Мои программы со статусом freeware для Windows на моём сайте jonix.ucoz.ru

Неизвестный
31.10.2009, 19:38
общий
[q=153662][/q]
Идея Genia007 имеет некотории смисъл, но 100% будет RangeCheck Error (delete уменшает count)
наверное
Randomize;
for i:=0 to RandList2.Count-1 do begin
outRandlist2.Insert(random(outRandlist2.Count-1),Randlist2[i]);
end;
будет бьистрее.
Неизвестный
31.10.2009, 19:39
общий
Akahaos:
можно еще просто работать со StringList и потом, "скопом" грузить новые значения в ваш список..
Да и вообще, компоненты визуализации предназначены для отображения данных а не для манипулирования алгоритмами над ними - от этого не только медленно но и часто не красиво (может что-то моргать и т.д.).
А потому, получите значение вашего компонента RandList2 в переменную, и просто случайным порядком из неё либо сразу вставляйте в другой компонент, либо во второй список и потом просто загрузите эти значения.
Неизвестный
31.10.2009, 19:58
общий
Victor Pyrlik, это не визуальные компоненты
Неизвестный
31.10.2009, 20:28
общий
Akahaos:
Цитата: 223975
это не визуальные компоненты

а откуда мне это знать?
Тогда Вы бы уточняли что используете, какой класс..
Неизвестный
31.10.2009, 20:29
общий
Bochvarov NikB:
Цитата: 2563
но 100% будет RangeCheck Error

ну дак переменную то можно уменьшать...
Неизвестный
02.11.2009, 09:27
общий
это ответ
Здравствуйте, Akahaos.

Совсем необязательно создавать два списка. ведь при таком подходе на каждый новый добавленный элемент будет происходить следующее:
1. выделяется новый обем памяти (count + 1) на добавление нового элемента.
2. копируется ВЕСЬ объем данных которые уже храняться в списке
3. добавляется новый элемент

Т.о. при очень больших размерах быстродействие будет все сильнее и сильнее проседать.

Поэтому мой вариант таков:
1. заполняем один раз список (желательно сначала задав количество элементов через outRandlist2.Count := NN)
2. Заполняем в цикле
for i := 0 to outRandlist2.Count - 1 do
begin
outRandlist2[i] := i;// на какуюто случайную позицию ставим элемент который гарантировано будет возрастать
end;
3. перемешиваем
for i := 0 to outRandlist2.Count - 1 do
begin
j := random(outRandlist2.Count) // иначе никогда не будет переставляться самый последний элемент

t := outRandlist2[i]; // меняем элементы местами (тасуем)
outRandlist2[i] := outRandlist2[j];
outRandlist2[j] := t;
end;
Форма ответа