Информатика_всем
.pdf196 |
8.3 Файлы последовательного доступа |
ПРИМЕР
Найти среднее арифметическое положительных компонент файла. вход:
выход: SrA = (3+8+1+9)/4= 21/4 = 5,25.
Приведем здесь блок-схему только основного алгоритма без ввода файла, который был расписан ранее. Мы читаем файл от начала до конца и анализируем прочитанные компоненты. Если компоненты оказываются большими нуля, то их добавляем в сумму S, не забывая при этом увеличивать счетчик k. Среднее арифметическое SrA существует лишь тогда, когда в файле есть положительные элементы. Блок-схема описанного процесса показана на Рисунок 8.8. Листинг приводить не будем.
Далее еще один пример на последовательную обработку.
ПРИМЕР
Переписать отрицательные компоненты файла F в файл G.
вход:
выход:
Сначала руками вводим файл F, далее проходим по нему в прямом направлении и встретившиеся отрицательные компоненты копируем последовательно в файл G. Здесь следует обратить внимание на процедуру связки файла G: Assign(G, ‘G.dat’), и не написать случайно в качестве параметра отвечающего за имя физического файла файл F, т.е. ‘F.dat’, а то получится, что переменные F и G, будут ссылаться на оду и ту же область диска и, соответственно, никакого копирования не произойдет. Эта задача решена полностью (Рисунок 8.9).
Такова реализация решения средствами Pascal: program FtoG;
var F,G: file of integer; buf:integer;
begin Assign(F,'F.dat'); rewrite(F);
writeLn('введите первую компоненту файла'); readLn(buf);
while buf<>999 do begin
write(F,buf);
writeLn('введите следующую компоненту:'); readLn(buf);
end;
8. Файлы |
197 |
Рисунок 8.9 Переписывание отрицательных компонент одного файла в другой файл |
8. Файлы |
199 |
ПРИМЕР
Ввести файл действительных чисел. Найти в нем среднее арифметическое каждой второй компоненты. Далее все компоненты, чей модуль меньше модуля найденного среднего арифметического, удвоить. Файл до и после преобразования вывести на экран.
Начинаем, как обычно, с тестового примера:
Следующий этап – это составление блок-схемы алгоритма. Можно сначала записать общий алгоритм, а далее каждый шаг детализировать. Общая последовательность действий решения представлена на Рисунок 8.11 а). Здесь шаги 1-2, 2-3 и 5-6 уже были описаны ранее (см. Рисунок 8.4, Рисунок 8.5). Потому есть смысл детализировать шаги 3-4 и 4-5. Их детализация изображена на Рисунок 8.11 б) и . Следует отметить, что доступ к каждой второй компоненте файла осуществляется прямым обращением. Из детализации шага 3-4 видно, что есть возможность «проскочить» конец файла и поставить указатель на несуществующую позицию. Однако это не вызовет ошибки поскольку такие действия возможны. Даже можно записать значение в компоненту далеко за границей файла. В этом случае компоненты между последней компонентой и вновь введенной будут не определены (скорее всего они будут заняты нулями, однако не факт, т.к. это зависит от версии компилятора Pascal). Самое главное не пытаться читать с позиции указателя выходящей за границы файла, поскольку это приведет к ошибке.
По составленным блок-схемам можно написать программу на языке
Pasccal:
program Files_1;
type Tfl = file of real; var F : Tfl;
buf, SrA : real; k : byte;
begin
{начало ввода файла (шаг 1-2)} assign(F,‘GoodFile1.dt’); rewrite(F);
k:=0;
writeLn(‘999 – окончание ввода’);
200 |
8.4 Файлы произвольного доступа |
Шаг 3-4 Главная программа
k := 0
Начало
1 |
seek (F, 1) |
|
|
|
|
Ввод файла F |
SrA := 0 |
|
|
|
|
2 |
|
|
Вывод файла F |
|
|
3 |
NOT EOF(F) |
|
Подсчет SrA |
|
|
(ср. арифметического) |
|
|
4 |
buf ← F |
|
Изменение файла F |
SrA := SrA + buf |
|
|
|
|
5 |
|
|
Вывод измененного |
k := k + 1 |
|
файла F |
|
|
|
|
|
6 |
seek (F, filePos(F)+1) |
|
|
|
|
Конец |
|
|
а) |
SrA := 0 |
б) |
Рисунок 8.11 Главная программа – а)
и поиск среднего арифметического каждой второй компоненты – б)
writeLn(‘Вводим файл F:’); write(‘1-я комп. файла = ’); readLn(buf);
while buf <> 999 do begin
write(F, buf); k:=k+1;
write(k,‘-я комп. файла = ’); readLn(buf);
end;
202 |
8.4 Файлы произвольного доступа |
Шаг 4-5
seek (F, 0)
NOT EOF(F)
buf ← F
|buf| < |SrA|
seek (F, filePos(F)-1)
buf := 2*buf
F← buf
Рисунок 8.12 Удвоение компонент удовлетворяющих условию
Поскольку файлы своей структурой напоминают одномерные массивы, то и задачи при их обработке возникают схожие. При решении этих задач практически всегда идейно используются одинаковые алгоритмы как для файлов, так и для массивов. Несмотря на идейную схожесть, все-таки имеются различия в реализации. Самое главное отличие, как отмечалось ранее, в том, что для доступа к компонентам файла используется указатель, в отличии от индекса в массиве.
Задачи могут быть на сортировку, циклический сдвиг, различные перестановки, поиск определенных элементов и т.д. Далее приведем без пояснений возможные алгоритмы поиска максимальной и минимальной компоненты в файле и их позиций (Рисунок 8.13), а также алгоритм сортировки элементов по возрастанию (Рисунок 8.14). Прочие алгоритмы здесь приводить не будем.