Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.03.16;
Скачать: [xml.tar.bz2];

Вниз

Перемешать рендомно строки 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.007 c
11-1186120923
Alexey_k
2007-08-03 10:02
2008.03.16
Нужен файл KOL_unicode.inc


2-1203378891
Artem
2008-02-19 02:54
2008.03.16
Вопрос по colordialog1.Color


15-1202372045
Iam
2008-02-07 11:14
2008.03.16
RAdmin


15-1202375660
@!!ex
2008-02-07 12:14
2008.03.16
Компиляция двух вариантов


2-1203420371
mishkas
2008-02-19 14:26
2008.03.16
Как из DataTimePicker получить переменные Year/Month/day





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский