Лабораторная работа №5
.docМинистерство образования и науки Российской Федерации
ФГАОУ ВПО «Уральский федеральный университет
имени первого Президента России Б.Н.Ельцина»
Кафедра «Информационные технологии и автоматизации проектирования»
Оценка
ЛАБОРАТОРНАЯ РАБОТА №5.
Работа с файлами и алгоритмы сортировки
По дисциплине: «Информационные технологии»
Студент: Мишкин Кирилл Олегович
Группа: ММ-121102
Преподаватель: Склярова Наталья Сергеевна
г. Екатеринбург
2012
Постановка задачи
Основная задача.
1. Написать функцию Load для считывания из текстового файла (например, Workers.txt) информации о работниках и заработной плате. В первой строке файла находится количество рабочих дней в месяце. Далее для каждого работника в файле записано по две строки: в первой – фамилия работника, во второй – два числа – количество отработанных дней и месячный оклад. После загрузки файла вывести на экран количество считанных записей.
2. Написать функцию Calc для вычисления зарплаты каждого работника по формуле
с округлением значения до двух десятичных знаков. Функция должна также подсчитать итоговую зарплату.
3. Написать функцию Save для выгрузки в файл ведомости заработной платы в виде следующей таблицы.
+----------------------+---+----------+----------+
| Фамилия |Дни| Оклад | Зарплата |
+----------------------+---+----------+----------+
|Петров | 15| 6300.00| 3937.50|
|Иванов | 24| 5600.00| 5600.00|
| ... |...| ... | ... |
+----------------------+---+----------+----------+
|Итого | 23687.50|
+-------------------------------------+----------+
Ширина колонок: «Фамилия» – 40 символов, «Дни» – 3 символа, «Оклад» и «Зарплата» – по 10 символов. Фамилию необходимо выравнивать по левому краю, цифры – по правому. Зарплату выводить с двумя десятичными знаками.
4. Написать функцию SortByName для сортировки списка работников по алфавиту методом пузырьковой сортировки.
5. В основной программе: загрузить список из файла Workers.dat, рассчитать зарплату, выгрузить ведомость в файл Pay.txt, отсортировать список по алфавиту, выгрузить ведомость в файл ByName.txt.
Дополнительные задачи.
1. Добавить функцию SortByPay для сортировки списка по зарплате. В основной программе отсортировать список еще и по зарплате, выгрузить ведомость в файл ByPay.txt.
2. Добавить в функции сортировки подсчет и вывод на экран количества сравнений. Выполнить программу для трех различных списков с количеством 5, 10 и 15 сотрудников соответственно. Записать для каждого списка максимальное количество сравнений из полученных при сортировке по имени и зарплате. Построить график зависимости количества сравнений от длины списка.
Математическая модель
Формула расчета заработной платы:
.
Для сортировки списка будем применять алгоритм пузырьковой сортировки, который в общем виде записывается так:
1. Повторять:
А. Для всех элементов списка, кроме последнего, повторять:
1. Если текущий элемент больше следующего, то поменять их местами
Б. Конец цикла.
2. Конец цикла при условии, что ни одной замены не произошло.
Описание алгоритма
Алгоритм Lab5.
А. Начать исполнение.
1. Загрузить список работников из файла "Workers.dat".
2. Рассчитать зарплату.
3. Выгрузить ведомость в файл "Pay.txt".
4. Отсортировать список по алфавиту.
5. Выгрузить ведомость в файл "ByName.txt".
6. Отсортировать список по зарплате.
7. Выгрузить ведомость в файл "ByPay.txt".
Б. Закончить исполнение.
Текст программы
program Lab5;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
Worker=record
Name:string;
Days:Integer;
Salary,Pay:Real;
end;
var
Days:Integer;
W:array [0..1000] of Worker;
n:Integer;
Total:Real;
procedure Load(const Name:string);
var
F:Text;
begin
Assign(F,Name);
reset(f);
Readln(F,Days);
n:=0;
while not Eof(F) do
begin
Inc(n);
Readln(F,W[n].Name);
Readln(F,W[n].Days,W[n].Salary);
end;
Close(F);
Writeln('schitano strok: ',n);
end;
procedure Calc;
var
i:Integer;
begin
Total:=0;
for i:=1 to n do
begin
W[i].Pay:=Round(W[i].Salary*W[i].Days/Days*100)
/100;
Total:=Total+W[i].Pay;
end;
end;
procedure Save(const Name:string);
var
F:Text;
i:Integer;
begin
Assign(F,Name);
Rewrite(F);
Writeln(F,'+-------…-------+---+---…------+---…------+');
Writeln(F,'| family |Дни| Оклад | Зарплата |');
Writeln(F,'+-------…-------+---+---…------+---…------+');
for i:=1 to n do
Writeln(F,'|',W[i].Name,'':15-Length(W[i].Name),
'|',W[i].Days:3,'|',W[i].Salary:10:2,
'|',W[i].Pay:10:2,'|');
Writeln(F,'+-------…-------+---+---…------+---…------+');
Writeln(F,'|itogo |',
Total:10:2,'|');
Writeln(F,'+-------…-------+---+---…------+---…------+');
Close(F);
end;
procedure SortByName;
var
Stop:Boolean;
Last,Cmp,i:Integer;
Temp:Worker;
begin
Last:=n;
Cmp:=0;
repeat
Stop:=True;
Dec(Last);
for i:=1 to Last do
begin
Inc(Cmp); {Подсчет количества сравнений}
if W[i].Name>W[i+1].Name then
begin
Temp:=W[i];
W[i]:=W[i+1];
W[i+1]:=Temp;
Stop:=False;
end;
end;
until Stop;
Writeln('sravneniy pri sortirovke po imeni: ',Cmp);
end;
procedure SortByPay;
var
Stop:Boolean;
Last,Cmp,i:Integer;
Temp:Worker;
begin
Last:=n;
repeat
Stop:=True;
Dec(Last);
for i:=1 to Last do
begin
Inc(Cmp); {Подсчет количества сравнений}
if W[i].Pay>W[i+1].Pay then
begin
Temp:=W[i];
W[i]:=W[i+1];
W[i+1]:=Temp;
Stop:=False;
end;
end;
until Stop;
Writeln('sravneniy pri sortirovke po zarplate:',Cmp);
end;
begin
Load('Workers.txt');
Calc;
Save('Pay.txt');
SortByName;
Save('ByName.txt');
SortByPay;
Save('ByPay.txt');
Readln; {Задержка для консольных приложений}
end.
Тест
Исходный файл со списком работников и информацией о заработной плате Workers.txt:
24
Мишкин
16 18000
Мошкин
5 25000
Шишкин
23 32000
Книжкин
10 11000
Мышкин
12 15000
Машкин
24 50000
Расчет зарплаты и выгрузка файла «Pay.txt»
+-------…-------+---+---…------+---…------+
| family |Дни| Оклад | Зарплата |
+-------…-------+---+---…------+---…------+
|Мишкин | 16| 18000.00| 12000.00|
|Мошкин | 5| 25000.00| 5208.33|
|Шишкин | 23| 32000.00| 30666.67|
|Книжкин | 10| 11000.00| 4583.33|
|Мышкин | 12| 15000.00| 7500.00|
|Машкин | 24| 50000.00| 50000.00|
+-------…-------+---+---…------+---…------+
|itogo | 109958.33|
+-------…-------+---+---…------+---…------+
Зарплата рассчитана корректно.
Сортировка списка по алфавиту и выгрузка файла «ByName.txt»:
+-------…-------+---+---…------+---…------+
| family |Дни| Оклад | Зарплата |
+-------…-------+---+---…------+---…------+
|Книжкин | 10| 11000.00| 4583.33|
|Машкин | 24| 50000.00| 50000.00|
|Мишкин | 16| 18000.00| 12000.00|
|Мошкин | 5| 25000.00| 5208.33|
|Мышкин | 12| 15000.00| 7500.00|
|Шишкин | 23| 32000.00| 30666.67|
+-------…-------+---+---…------+---…------+
|itogo | 109958.33|
+-------…-------+---+---…------+---…------+
Сортировка выполнена корректно.
Сортировка списка по зарплате и выгрузка файла «ByPay.txt»:
+-------…-------+---+---…------+---…------+
| family |Дни| Оклад | Зарплата |
+-------…-------+---+---…------+---…------+
|Книжкин | 10| 11000.00| 4583.33|
|Мошкин | 5| 25000.00| 5208.33|
|Мышкин | 12| 15000.00| 7500.00|
|Мишкин | 16| 18000.00| 12000.00|
|Шишкин | 23| 32000.00| 30666.67|
|Машкин | 24| 50000.00| 50000.00|
+-------…-------+---+---…------+---…------+
|itogo | 109958.33|
+-------…-------+---+---…------+---…------+
Сортировка выполнена корректно.
Проверка алгоритма сортировки для списков с различным количеством элементов:
Количество элементов в списке |
Количество сравнений при сортировке по имени |
Количество сравнений при сортировке по зарплате |
Максимальное количество сравнений |
5 |
10 |
10 |
10 |
10 |
39 |
42 |
42 |
15 |
102 |
95 |
102 |
По графику зависимости количества произведенных при сортировке сравнений от длины списка виден резкий, похожий на квадратичный, характер возрастания количества сравнений, что как раз является характерным для применяемого в работе алгоритма пузырьковой сортировки, имеющего