![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Ребята как переделать вот этот код - под чтение построчно. Что бы не загружать в память.
Код:
var
s: TStringList;
z, p, q: Integer;
begin
s := TStringList.Create;
s.LoadFromFile('C:\text.txt');
z := 50;
while (z > 0) do begin
p := random(s.Count); q := random(s.Count);
s.Exchange(p, q);
dec(z);
end;
s.SaveToFile('c:\text.txt');
s.Free;
end;Начал переделывать вот так (но вот в регуляровкой рандом не дружу): Код:
var
z, p, q: Integer;
ft, ft2: TextFile;
s:string;
begin
if OpenDialog1.Execute then begin
AssignFile(ft, OpenDialog1.FileName);
Reset(ft);
AssignFile(ft2, ExtractFileDir(OpenDialog1.FileName)+'\rez.txt');
Rewrite(ft2); // чтобы создался новый, если нету, или перезаписался с нуля
Append(ft2); // чтобы можно было добавлять строки, а не перезаписывать каждый раз
begin
while not eof(ft) do
begin
readln(ft,s);
//////////////////////////////////////
Вот тут не знаю что дописать ?
//////////////////////////////////////
writeln(ft2,s)
end;
closefile(ft);
closefile(ft2);
end;
end;
end;Подскажите кто сможет ? |
|
#2
|
||||
|
||||
|
http://www.delphisources.ru/forum/sh...ad.php?t=26859
Небольшое размышление: рандомное перемешивание может вызвать забавную ситуацию - некоторые строки могут быть "посланы" в результирующий файл несколько раз, а другие остаться даже неупомянутыми в нём, такова специфика системного "блендера", решение видится в таком варианте - предварительно собрать рандомный массив индексов строк с проверкой на дубляж/отсутствие их в нём и лишь после его формирования произвести перенос исходных строк в конечный файл посредством seek > readln > writeln простым проходом по элементам этого массива с последовательным считыванием их значений, по-другому вроде решение не наблюдается З.Ы. Поскольку текстовый файл допускает лишь одностороннее чтение, только вперёд, вариант получился довольно медленным т.к. при переходе на нужную строчку необходимо каждый раз возвращаться в начало файла, много циклов, но к сожалению, иначе никак Код:
var
i, j, b: integer;
ft, ft2: TextFile;
s: string;
sc: array of integer;
begin
Randomize;
AssignFile(ft, '1.txt');
Reset(ft);
i:= 0;
// Подсчёт количества строк в файле
while not Eof(ft) do
begin
Readln(ft);
Inc(i);
end;
SetLength(sc, i);
// Заполнение массива индексами строк
for i := Low(sc) to High(sc) do sc[i]:= i;
// Перемешивание индексов
for i := High(sc) downto Low(sc) do
begin
b:= Random(i);
j:= sc[b];
sc[b]:= sc[i];
sc[i]:= j;
end;
AssignFile(ft2, '2.txt');
Rewrite(ft2);
for i := Low(sc) to High(sc) do
begin
// Имитация seek
Reset(ft);
for j:= 0 to sc[i] do Readln(ft, s);
Writeln(ft2, s);
end;
CloseFile(ft);
CloseFile(ft2);
end;Последний раз редактировалось Alegun, 08.03.2018 в 12:42. |
| Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Taras2020 (21.03.2018)
| ||
|
#3
|
|||
|
|||
|
Ну, если исходные файлы большие, то можно сделать алгоритм, который будет читать/писать блоками в несколько итераций.
Примерно так: 1. Считаем солько строк всего в файле. Пусть получили N. 2. Создаем массив длинной N. 3. В цикле от 1 до N генерируем случайную позицию для i-ой строки и помещаем ее в массив. Если место уже занято, то сдвигаем по циклу пока не найдем свободное место. 4. Берем K первых элементов массива, проходимся по файлу и собираем нужные строки, пишем их в выходной файл. 5. Повторяем 4 пока не будут записаны все блоки. 6. Profit... Получается, что для файла длинной N строк и размера блока K строк у нас будет N%K+2 проходов по файлу. Т.е. для примера N=1005, K=20 получаем 52 прохода. |
|
#4
|
||||
|
||||
|
Цитата:
|
|
#5
|
|||
|
|||
|
Не совсем так.
Тут идея уменьшения проходов по файлу. Работает, конечно, только для больших файлов. Т.е., если брать твою аналогию, то тесто ты месишь все, а вот в половник наливаешь почуть-чуть из разных мест для одного блина. Кстати, есть еще вариант. Т.к. кол-во строк все-равно надо узнавать, то при первом проходе можно просто построить карту файла и дальше открыть его как бинарный и пользовать seek. Но карта тоже места займет в памяти. |