|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
вывод рандома из файла
меня интересует два типа вывода рандом
случайная строка и с разделителем случайная строка разделитель Цитата:
Код:
N:= -1; S:= TStringList.Create; S.LoadFromFile(extractfilepath(paramstr(0))+'файл.txt'); listS:=TStringList.Create; for i:=0 to S.Count-1 do if(S.Strings[i] = '#') then begin inc(N); listS.Add(inttostr(I)); end; k:=random(N); for i:=(strToint(listSpam.Strings[k])+1) to (strToint(listSpam.Strings[k+1])-1) do result:=result+spamS.Strings[i]+#13#10; просто случайная строка Цитата:
Код:
S:= TStringList.Create; S.LoadFromFile(extractfilepath(paramstr(0))+'файл.txt'); a:=random(s.Count); Result:=xtazkont.Strings[a]; так вот хотел бы узнать как можно это сделать иначе, так как посылается команда с именем файла и надо сразу все это сделать, но это нормально если файл маленький а вот если там 10мб... |
#2
|
||||
|
||||
Получаешь рандомом номер разделителя, построчно читаешь файл, пропускаешь N разделителей, выводишь до N+1-го. Юзается AssignFile, Reset, ReadLn, CloseFile и var f:text;
Можно предварительно посчитать число разделителей, также читая построчно. Чтобы все сразу не грузить. Хотя работать оно будет заметно медленнее. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 13.01.2012 в 21:30. |
#3
|
||||
|
||||
файл мне не известен соотвественно число разделителей тоже в нем
|
#4
|
||||
|
||||
Цитата:
Насчет "число разделителей" - я ж написал: можно предварительно прочитать файл построчно и определить это число. jmp $ ; Happy End! The Cake Is A Lie. |
#5
|
||||
|
||||
я имею заранее не известен известен становится тогда когда надо сразу получить рандомный ответ
ну собственно мне понятно, а сколько это по времени вот будет? и не дергает ли сильно винт? Последний раз редактировалось ALexandr555, 13.01.2012 в 22:48. |
#6
|
||||
|
||||
Файл становится известен, когда нужно получить ответ? Ну так и делать. В момент, когда нужно получить ответ, построчно прочитать файл, узнать кол-во разделителей и заодно их позиции, получить рандом, и построчно считать с позиции нужного разделителя до следующего. Вообщем на месте этого кода:
Код:
N:= -1; S:= TStringList.Create; S.LoadFromFile(extractfilepath(paramstr(0))+'файл.txt'); listS:=TStringList.Create; for i:=0 to S.Count-1 do if(S.Strings[i] = '#') then begin inc(N); listS.Add(inttostr(I)); end; k:=random(N); for i:=(strToint(listSpam.Strings[k])+1) to (strToint(listSpam.Strings[k+1])-1) do result:=result+spamS.Strings[i]+#13#10; jmp $ ; Happy End! The Cake Is A Lie. |
#7
|
||||
|
||||
не проверял пока но вроде должно работать
винт не будет сильно дергать? если это вызывается около 200 раз в минуту случайная строка Код:
function TMyThread.random1(Myfile: string; nomer: integer): string; var f:TextFile; n,r: integer; begin n:=0; AssignFile(f,MyFile+'.txt'); Reset(f); While not EOF(f) do begin inc(n); end; CloseFile(f); r:=random(n)+1; Reset(f); While not EOF(f) do begin inc(n); if n=r then begin readln(f,result); break; end; end; end; с разделителем '#' Код:
function TMyThread.random2(Myfile: string; nomer: integer): string; var f:TextFile; buf: string; n,r: integer; begin n:=-1; AssignFile(f,MyFile+'.txt'); Reset(f); While not EOF(f) do begin readln(f,buf); if trim(buf)='#' then inc(n); end; CloseFile(f); r:=random(n)+1; n:=0; Reset(f); While not EOF(f) do begin readln(f,buf); if n=r then begin if trim(buf)='#' then inc(n); if n=r then result:=result+#13#10+buf else break; end else if trim(buf)='#' then inc(n); end; end; |
#8
|
||||
|
||||
Дергать хард будет сильно, и работать довольно медленно. Надо быстро - надо грузить целиком.
jmp $ ; Happy End! The Cake Is A Lie. |
#9
|
||||
|
||||
понятно, сделаю тогда уж предварительную загрузку
|