Задание
Для ведомости составить программу для определения времени наибольшей производительности бригады. Указанное время определить за всю неделю. Расширить функциональность этого задания и обеспечить следующие возможности:
- Индексация элементов списка.
- Абсолютное и относительное позиционирование (сдвиг по индексу относительно начального текущего элемента абсолютный сдвиг относительно текущие).
- Поиск по заданному критерию.
Примечание: обеспечить мониторинг памяти, класс управления выделить в отдельный модуль.
Выбор алгоритма решения задачи
Для решения данной задачи мы сообщаем объект: ob.
Также сообщаем один список:
Первый:
trec=record
prev:tp;
nomer:word;
fam:string;
smena:byte;
zachas:array[1..8]of byte;
vsego:integer;
prostoj:byte;
proizv:real;
next:tp;
Описание решения задачи
В полях мы объявляем процедуры и функции:
В начале программы должен запускаться конструктор для инициализации списка. А деструктор должен запускаться при выходе из программы.
constructor init; - конструктор инициализации
destructor done; - деструктор. Вызывается при конце программы.
procedure vvod; - процедура ввода списка.
procedure vivod; - процедура вывода списка
procedure sozdanie(rec:trec); - процедура создания списка
procedure append(rec:trec); - процедура добавления к списку
function elem(first:tp;pos:integer):tp; - функция принимает значение первого указателя и номер того, на который нужно попасть. Функция возвращает указатель на номер pos.
procedure udalenie; - процедура удаления списка
procedure vivelem(pos:word); - процедура вывода элемента
procedure poz; - процедура просмотра списка
procedure poisk; - процедура поиска
Текст программы
1 Главная программа
program lab10;
uses
crt,u1;
var
obj:tob;
p:pointer;
BEGIN
mark(p);
clrscr;
writeln('Free memory=[',memavail,']b'); {проверка свободной памяти}
readln;
randomize;
clrscr;
repeat
clrscr;
writeln('1-sozdat spisok'); {информационное меню}
writeln('2-dobavit novij element spiska');
writeln('3-udalit element spiska');
writeln('4-pokazat spisok');
writeln('5-pokazat element spiska');
writeln('6-poisk elementa');
writeln('7-ochistit spisok');
writeln('8-vihod');
n:=readkey; {ввод числа n}
case n of {переход по номеру n, который мы введи}
'1':begin
obj^.vvod;
obj^.sozdanie(rr);
end;
'2':begin
obj^.vvod;
obj^.append(rr);
end;
'3':obj^.udalenie;
'4':obj^.vivod;
'5':obj^.poz;
'6':obj^.poisk;
'7':begin
release(p); {процедура возврата кучи}
ctr:=0;
writeln('Spisok ochischen');
readln;
end;
'8':begin
release(p); {процедура возврата кучи}
clrscr;
writeln('Free memory=[',memavail,']b'); {проверка свободной памяти}
readln;
exit;
end;
end
until n='8';
END.
2 Модуль программы
unit u1;
interface
uses
crt;
type
tp=^trec;
trec=record {объявление списка}
prev:tp;
nomer:word;
fam:string;
smena:byte;
zachas:array[1..8]of byte;
vsego:integer;
prostoj:byte;
proizv:real;
next:tp;
end;
tob=^ob; {указатель на объект}
ob=object
constructor init; {конструктор инициализации }
destructor done; {деструктор. Вызывается при окончании программы}
procedure vvod; { процедура ввода списка.}
procedure vivod; {процедура вывода списка}
procedure sozdanie(rec:trec); { процедура создания списка }
procedure append(rec:trec); {процедура добавления в список}
function elem(first:tp;pos:integer):tp; {функция, которая находит указатель на элемент pos и возвращает его}
procedure udalenie; {процедура удаления списка}
procedure vivelem(pos:word); {}
procedure poz; {}
procedure poisk; {процедура поиска}
end;
var
first,glavn:tp;
i,j:integer;
rr:trec;
ctr,pos:word;
n:char;
implementation
constructor ob.init; {выполнение конструктора}
begin
end;
destructor ob.done; {выполнение деструктора}
begin
end;
procedure ob.vvod; {процедура ввода}
var
s:string;
begin
clrscr;
rr.vsego:=0;
writeln('Familija rabochego?'); {мы вводим фамилию рабочего. Все остальное заполняется}
readln(s); {случайными числами}
rr.fam:=s;
rr.smena:=random(8)+1;
rr.prostoj:=8-rr.smena;
for i:=1 to rr.smena do
begin
rr.zachas[i]:=random(9)+1;
rr.vsego:=rr.vsego+rr.zachas[i];
end;
rr.proizv:=rr.vsego/rr.smena;
end;
procedure ob.vivod; {процедура вывода}
var
i,j:word;
t:tp;
begin
clrscr;
t:=first;
writeln('-------------------------------------------------------------------------------');
writeln('| | | Rabochih | Vypusk produkcii | Vremia | Proizvoditelnost|');
writeln('|# | Rabotnik | chasov | za edinicu vremeni | prostoya| detalej za |');
writeln('| | | za smenu |-----------------------| | 1 chas |');
writeln('| | | | 1| 2| 3| 4| 5| 6| 7| 8| | |');
writeln('-------------------------------------------------------------------------------');
if ctr>=1 then {если мы ввели вывод рабочих больше 1}
begin
for i:=ctr downto 1 do
begin
write('|',t^.nomer:2,'|'); {вывод информации о рабочих}
write(t^.fam:10,'|');
write(t^.smena:6,'|':5);
for j:= 1 to t^.smena do write(t^.zachas[j]:2,'|');
write(t^.prostoj:29-3*t^.smena);
write('|':5);
write('':6);
write(t^.proizv:5:2);
writeln('|':8);
writeln('-------------------------------------------------------------------------------');
t:=t^.next;
end;
end;
writeln('Free memory=[',memavail,']b'); {показ свободной памяти}
readln
end;
procedure ob.vivelem(pos:word); {процедура вывода элемента списка под номером pos}
begin
clrscr;
write('|',elem(first,pos)^.nomer:2,'|');
write(elem(first,pos)^.fam:10,'|');
write(elem(first,pos)^.smena:6,'|':5);
for j:= 1 to elem(first,pos)^.smena do write(elem(first,pos)^.zachas[j]:2,'|');
write(elem(first,pos)^.prostoj:29-3*elem(first,pos)^.smena);
write('|':5);
write('':6);
writeln(elem(first,pos)^.proizv:5:2);
writeln('');
writeln('1-pred'); {подсказки какую цифру нужно нажать, чтобы получить необходимый}
writeln('2-sled'); {результат. Если мы нажмем 5, мы выйдем в главное меню}
writeln('3-smeschenie');
writeln('4-vvesti nomer');
writeln('5-glavnoe menu');
end;
procedure ob.sozdanie(rec:trec); {процедура создания списка}
begin
new(glavn); {выделение памяти}
ctr:=1;
rec.nomer:=ctr; {это первая запись}
rec.prev:=nil; {указатели в списке принимают значение нуля}
rec.next:=nil; {указатели в списке принимают значение нуля}
glavn^:=rec;
first^:=glavn^;
end;
procedure ob.append(rec:trec); {процедура добавление в список}
var
tec:tp;
begin
if ctr=0 then {если список еще не создан}
begin
sozdanie(rec);
halt; {выход из процедуры}
end;
new(tec); {если список уже существует, то выделяем память под следующий элемент}
inc(ctr); {инкрементируем номер списка}
rec.prev:=glavn; {указатель на предыдущий элемент принимает это значение }
rec.nomer:=ctr; {переменная nomer принимает значение номера списка }
rec.next:=nil; {указатель на следующий элемент равен нулю}
tec^:=rec; {список добавляется к динамическому списку}
glavn^.next:=tec; {указатель next принимает значение указателя на этот заполненный список}
if ctr=2 then first:=glavn; {если это уже 2-й элемент списка, тогда first = glavn}
glavn:=tec; {glavn принимает значение указателя tec}
end;
function ob.elem(first:tp;pos:integer):tp; {функция перемещения до элемента pos}
var
tec:tp;
i:integer;
begin
tec:=first;
for i:=1 to pos-1 do tec:=tec^.next;
elem:=tec; {возвращаемое значение указателя по элементу pos}
end;
procedure ob.udalenie; {процедура удаления}
var
tec,x:tp;
pos:byte;
begin
clrscr;
writeln('Vvedite nomer udalyaemogo elementa');
readln(pos); {мы вводим номер элемента, который хотим удалить}
tec:=first;
if pos=1 then {если этот элемент первый}
begin
first:=tec^.next; {тогда указатель на первый элемент принимает значение второго}
tec^.prev:=nil; {а предыдущий равен нулю}
end;
if pos<>ctr then {если удаляемый элемент не равен текущему}
begin
tec:=elem(first,pos); {tec принимает указатель на тот элемент, который нам нужно удалить}
x:=tec^.prev; {сохранение указателя}
tec:=tec^.next;
x^.next:=tec;
dispose(tec^.prev); {удаление элемента под номером pos}
tec^.prev:=x; {возвращение указателя, который мы сохраняли}
end;
if pos=ctr then {если значения pos равно последнему}
begin
tec:=elem(first,pos); {tec принимает указатель на тот элемент, который нам нужно удалить }
glavn:=tec^.prev; {текущий указатель принимает значение предыдущего}
tec^.next:=nil; {указатель на следующий принимает значение ноль}
end;
dec(ctr); {декрементирование значения ctr}
tec:=first;
for i:=1 to ctr do {цикл выравнивания списка}
begin
tec^.nomer:=i;
tec:=tec^.next;
end;
end;
procedure ob.poz; {процедура просмотра списка}
var
a:integer;
begin
clrscr;
writeln('Nomer elementa dla prosmotra');
readln(pos); {номер элемента списка, который мы хотим посмотреть}
repeat
vivelem(pos);
n:=readkey; {необходимо нам ввести число n}
case n of
'1':begin
if pos=1 then {если это первый элемент}
begin
clrscr;
writeln('Elementa net. press Enter to return');
readln;
end
else dec(pos); {иначе вывод предыдущего}
end;
'2':begin
if pos=ctr then {если это последний элемент}
begin
clrscr;
writeln('Elementa net. press Enter to return');
readln;
end
else inc(pos); {иначе вывод следующего элемента списка}
end;
'3':begin
writeln('Na skolko smestit?');
readln(a); {необходимо ввести смещение, относительно нашего найденного элемента}
if ((pos+a)<1) or ((pos+a)>ctr) then {если число выходит за пределы списка}
begin
writeln('Elementa net. press Enter to return');
readln
end
else pos:=pos+a; {иначе вывод этого элемента}
end;
'4':begin
clrscr;
writeln('Nomer elementa dla prosmotra');
readln(pos); {ввод номера элемента для просмотра}
end;
end;
until n='5'; {5 это вход на главное меню}
end;
procedure ob.poisk; {процедура поиска}
var
st:string;
t:tp;
begin
clrscr;
writeln('1-po famillii');
writeln('2-po proizvoditelnosti');
n:=readkey; {ввод числа 1 или 2}
case n of
'1':begin {если 1, то осуществляется поиск по фамилии}
clrscr;
writeln('Vvedite familiju dlya poiska');
readln(st);
t:=first;
for i:=1 to ctr do
begin
if t^.fam=st then
begin
write('|',t^.nomer:2,'|');
write(t^.fam:10,'|');
write(t^.smena:6,'|':5);
for j:= 1 to t^.smena do write(t^.zachas[j]:2,'|');
write(t^.prostoj:29-3*t^.smena);
write('|':5);
write('':6);
write(t^.proizv:5:2);
writeln('|':8);
writeln('-------------------------------------------------------------------------------');
end;
t:=t^.next;
end;
readln;
end;
'2':begin {если нажата число 2, то поиск осуществляется по производительности}
end;
end;
end;
end.
Результат работы программы