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

Вниз

Перемешать рендомно строки TStringList   Найти похожие ветки 

 
WebSQLNeederr   (2008-02-18 13:05) [0]

Есть ли какой то простой способ перемешать в случайном порядке строки TStringList?


 
Сергей М. ©   (2008-02-18 13:19) [1]

Конечно есть - написать простейшую процедуру.


 
Savek   (2008-02-18 13:22) [2]

StringList.Exchange(Random(StringList.Count-1),Random(StringList.Count-1));
и так много раз


 
WebSQLNeederr   (2008-02-18 13:26) [3]

Спасибо


 
WebSQLNeederr   (2008-02-18 13:53) [4]

А еще такой вопрос. Как сделать что бы пока програма будет менять строки (у меня их много) то что бы не подвисала а на это время курсор становился как часики.


 
Сергей М. ©   (2008-02-18 13:55) [5]

Добавь в тело цикла Application.Processmessages


 
Skyle ©   (2008-02-18 14:00) [6]

Сделай рядом массив индексов и перемешивай его. И доступайся через него же.


 
palva ©   (2008-02-18 14:13) [7]

Должно работать быстро.
Может быть StringList отображается в каком-то визуальном контроле? Тогда лучше на время обработки отображение как-то отключить.


 
WebSQLNeederr   (2008-02-18 14:13) [8]

то есть так?

for i:=1 to 10 do
begin
 StringList.Exchange(Random(StringList.Count-1),Random(StringList.Count-1));
 Application.Processmessages;
end;


 
WebSQLNeederr   (2008-02-18 14:14) [9]


> Должно работать быстро.
> Может быть StringList отображается в каком-то визуальном
> контроле? Тогда лучше на время обработки отображение как-
> то отключить.


У меня просто в нем 86 кб загнано и нужно перемешать все.


 
Джо ©   (2008-02-18 14:18) [10]

> [9] WebSQLNeederr   (18.02.08 14:14)
> У меня просто в нем 86 кб загнано и нужно перемешать все.

86 кб — это несерьезно.


 
WebSQLNeederr   (2008-02-18 14:24) [11]

много?


 
WebSQLNeederr   (2008-02-18 14:30) [12]

Я сделал так

for i:=0 to j do
 begin
   tempstr.Exchange(Random(tempstr.Count-1),Random(tempstr.Count-1));
   Application.Processmessages;
   Application.MainForm.Cursor:=crHourGlass;
 end;

Но часики так и не появились. Может я не верно делаю?


 
palva ©   (2008-02-18 14:31) [13]


> то есть так?
>
> for i:=1 to 10 do
> begin
>  StringList.Exchange(Random(StringList.Count-1),Random(StringList.
> Count-1));
>  Application.Processmessages;
> end;

Скорее так:

for i := StringList.Count-1 down 1 do
begin
StringList.Exchange(i, Random(i + 1));
Application.Processmessages;
end;


 
Palladin ©   (2008-02-18 14:34) [14]

Var
 tmp:TStringList;
 n:Integer;

Begin
 tmp:=TStringList.Create;
 Try
  tmp.AddStrings(list);
  list.Clear;
  While tmp.Count>0 Do
   Begin
    n:=Random(tmp.Count);
    list.Add(tmp[n]);
    tmp.Delete(n);
   End;
 Finally
  tmp.Free;
 End;
End;


 
WebSQLNeederr   (2008-02-18 14:40) [15]

palva, Palladin - красиво вы сделали!! По красоте! Спасибо за варианты! Ато у меня примитивный вариант перемешивания был.

Ну так а с часиками что? Как их впихнуть в процесс перемешивания?


 
Amoeba ©   (2008-02-18 14:50) [16]


> Ну так а с часиками что? Как их впихнуть в процесс перемешивания?
>
>

Даю подсказку. У TScreen и TControl есть такое замечательное св-во: Cursor


 
Джо ©   (2008-02-18 14:50) [17]

> [15] WebSQLNeederr   (18.02.08 14:40)

> Ну так а с часиками что? Как их впихнуть в процесс перемешивания?

Screen.Cursor := crHourglass;
try
 // перемешиваем...
finally
 Screen.Cursor := crDefault
end


 
WebSQLNeederr   (2008-02-18 14:59) [18]

Есть еще два вопроса:

1. Application.Processmessages - зачем оно вообще надо, что оно делает?

2. и если надо то куда его пихать? Вот у меня есть оброботчик кнопки там есть цикл, который вызывает функцию в которой есть тоже цикл. Так вот этот процессмеседж впихивать в цикл внутри функции или в цикл обработчика кнопки?


 
Palladin ©   (2008-02-18 15:04) [19]


> Application.Processmessages - зачем оно вообще надо, что
> оно делает?

приказывает приложению обработать все поступившие к нему, но еще не обработанные (сидящие в очереди) сообщения...


 
Сергей М. ©   (2008-02-18 15:04) [20]


> зачем оно вообще надо, что оно делает?
>


Как раз то что тебе нужно - что бы не подвисала


> куда его пихать?


В тело цикла, сказано же.

Если не лезет, воспользуйся смазкой)


 
WebSQLNeederr   (2008-02-18 15:20) [21]

То есть в моем случае его нужно впихнуть как в тело цикла в обработчики кнопки так и в тело цикла функции, которая вызывается из обработчика кнопки.


 
Сергей М. ©   (2008-02-18 15:25) [22]


> цикла функции


Это еще куда ?)


 
WebSQLNeederr   (2008-02-18 16:02) [23]

ну внутри функции есть цикл, пример

function func:string;
begin
for i:=1 to 10 do
begin
СЮДА Application.Processmessages; ???
end;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
for i:=1 to 10 do
begin
a:=func;
ИЛИ СЮДА Application.Processmessages; ???
end;


 
Сергей М. ©   (2008-02-18 16:41) [24]


> WebSQLNeederr   (18.02.08 16:02) [23]


Да куда хочешь, туда и "пихай")

Правило одно - чем чаще вызывается ProcessMessage, тем оперативнее программа реагирует на события польз.интерфейса, но и тем больше программа отнимает у системы квантов процессорного времени.


 
KilkennyCat ©   (2008-02-18 20:46) [25]

мда. на перемешивание 86 кбайт часики могут действительно не появиться. неуспеють...


 
WebSQLNeederr   (2008-02-18 21:07) [26]

У меня на 35-40 секунд подвисает комп ...


 
WebSQLNeederr   (2008-02-18 21:14) [27]

Правда у меня предварительно еще разбивает текст каждой строки на предложения и заносит в СтрингЛист, а потом уже этот стринглист перемешивает.

Вот пример:

function rech(st:string):string;
var s,s1:string;stop:bool;i,j:integer;tempstr,res:TStringList;
begin
 stop:=false; s:=st; j:=0;
 tempstr:=TStringList.create;
 res:=TStringList.create;
 repeat
   i:=pos(".",s); if i<=0 then stop:=true;
   s1:=copy(s,0,i);
   if length(s1)>5 then begin tempstr.Add(s1);j:=j+1;end;
   s:=copy(s,i+2,length(s)-i);
 until stop=true;
// Выше мы находили в тексте первое нахождение точки и закидывали в стринглист tempstr предложение.
 for i:=1 to strtoint(Form1.counttext.text) do
 begin
   res.Add(tempstr.Strings[Random(tempstr.Count-1)]);
 end;
// А это мы перемешали все предложения.
 rech:=res.text;
 tempstr.Free; res.Free;
end;

Функция выдает уже текст, где предложения перемешаны. Вот когда я эту функцию вызываю раз 10-15 то и возникает задержка в где то 40 секунд. Может можно как то оптимизировать?


 
KilkennyCat ©   (2008-02-18 22:28) [28]

> Может можно как то оптимизировать?

Да. Хотя бы по-человечески написать. Точнее, по-паскалевски. по-венгерски.


 
KilkennyCat ©   (2008-02-18 22:32) [29]

function rech(st : string): string;
var
s, s1 : string;
stop : bool;
i, j : integer;
tempstr, res : TStringList;
begin
 stop := false;
 s := st;
 j := 0;
 tempstr := TStringList.create;
 res := TStringList.create;
 repeat
   i := pos(".", s);
   if i <= 0 then stop := true;
   s1 := copy(s, 0, i);
   if length(s1) > 5 then begin
     tempstr.Add(s1);
     j := j+1;
   end;
   s := copy(s, i+2, length(s) - i);
 until stop = true;
// Выше мы находили в тексте первое нахождение точки и закидывали в стринглист tempstr предложение.
 for i := 1 to strtoint(Form1.counttext.text) do begin
   res.Add(tempstr.Strings[Random(tempstr.Count - 1)]);
 end;
// А это мы перемешали все предложения.
 rech := res.text;
 tempstr.Free;
 res.Free;
end;



 
KilkennyCat ©   (2008-02-18 22:53) [30]

> stop := false;

нафиг не надо.

> if i <= 0 then stop := true;
until stop = true;

кто вас такому учил?

и вообще, все мрак.

ща напишу.


 
sniknik ©   (2008-02-19 01:03) [31]

function FoolerySort(List: TStringList; Index1, Index2: Integer): Integer;
begin
 result:= Random(2000)-1000;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 tmp: TStringList;
begin
 Randomize;
 tmp:= TStringList.Create;
 try
   tmp.Assign(Memo1.Lines);
   tmp.CustomSort(FoolerySort);
   Memo1.Lines.Assign(tmp);
 finally
   tmp.Free;
 end;
end;


 
palva ©   (2008-02-19 10:16) [32]


> sniknik ©   (19.02.08 01:03) [31]

Неправильно реализована функция FoolerySort. Функция обязана возвращать результат соответствующий правилам больше-меньше: рефлексивность, антисимметричность, транзитивность. Кроме того при многократном обращении к этой функции с одними и теми же параметрами результат должен быть один и тот же. Не знаю, приведет ли данный код к потере данных - это зависит от алгоритма сортировки, - но возможно сильно увеличенное время сортировки, а то и зацикливание. Алгоритм может многократно менять местами одни и те же строки, поскольку для них функция возвращает то минус, то плюс. Опять таки можно придумать такой алгоритм, на котором это не проявится.


 
sniknik ©   (2008-02-19 10:47) [33]

> Опять таки можно придумать такой алгоритм, на котором это не проявится.
легко, вообщето первоначально хотел использовать рандомные значения сохраненные в свойстве tmp.Objects, но както "заломало" поэтому просто наименовал процедуру FoolerySort вместо RandomSort...



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

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

Наверх




Память: 0.55 MB
Время: 0.011 c
2-1203279731
Jimmy
2008-02-17 23:22
2008.03.16
Печать на принтере


2-1203318623
aistto
2008-02-18 10:10
2008.03.16
что с лейблом?


2-1202993472
Свой
2008-02-14 15:51
2008.03.16
Не могу открыть базу под IIS


2-1203152996
Rakurs
2008-02-16 12:09
2008.03.16
Сортировка TStringList при OEM тексте


15-1202241472
Human
2008-02-05 22:57
2008.03.16
IRC