2 Программная часть
Данный раздел включает в себя описание программного кода с комментариями.
unit UCeh2;
interface
uses Dialogs, SysUtils, Grids;
type
TCeh2 = class
private
{ Private declarations }
sGroup, // Название группы
sPrep: String; // Преподаватель
iKolDol: Integer; // Кол-во задолжников
Pnext, Pprev:TCeh2; //указатели на следующий и предыдуший элементы
public
{ Public declarations }
// Перегружаем конструкторы
constructor Create(); overload; // конструктор без параметров
constructor Create(n,b: String; kr: Integer); overload; // конструктор c параметрами
destructor Destroy(); // Деструктор
procedure Set_prev(pp: TCeh2);
procedure Set_next(pn: TCeh2);
procedure Set_Group(n: String); // установка
procedure Set_Prep(b: String); // полей
procedure Set_KolDol(kr: Integer); // класса
function Get_prev():TCeh2;
function Get_next():TCeh2;
function Get_Group():String; // чтение
function Get_Prep():String; // полей
function Get_KolDol():Integer; // класса
// Определяем СВОЙСТВА класса
property next: TCeh2 read Get_next write Set_next;
property prev: TCeh2 read Get_prev write Set_prev;
property Group: string read Get_Group write Set_Group; // Имя
property Prep: string read Get_Prep write Set_Prep; // Начальник
property KolDol: Integer read Get_KolDol write Set_KolDol; //Кол-во работающщих
end;
TSpisok=class
private
{ Private declarations }
FCount: integer; //кол-во элементов
PFirst, //указатель на первый элемент
PLast, //на последний
PNow: TCeh2; //на текущий
public
constructor Create();
procedure AddFirst(sGroup:String; sPrep:String; iKolDol: Integer); // добавить в начало
procedure AddLast(sGroup,sPrep: String; iKolDol: Integer); //добавить в конец
procedure AddNext(sGroup,sPrep: String; iKolDol: Integer); //добавить после текущего
procedure AddPrev(sGroup,sPrep: String; iKolDol: Integer); //добавить перед текущим
procedure ToGrid(Grid: TStringGrid); //вывест в стринггрид
procedure ToFile(Fname: String); //запись в файл
procedure FromFile(Fname: String); //из файла
procedure DeleteCurrent(); //удалить текущий
function GetFirst():TCeh2; //навигация: первый элемент списка
function GetLast():TCeh2; // навигация: последний элемент списка
function GetNext():TCeh2; //навигация: следующий элемент
function GetPrev():TCeh2; //предыдущий элемент
function Search(Value: String; field: Integer):TCeh2; //поиск
procedure SearchWhereKolDolMore(value: integer; Grid: TStringGrid);
procedure SearchWhereKolDolLess(value: integer; Grid: TStringGrid);
procedure SearchForSubstrPreps(value: string; Grid: TStringGrid);
procedure SearchForSubstrGroup(value: string; Grid: TStringGrid);
function GetMaxColDol(): TCeh2;
function GetMinColDol(): TCeh2;
function GetAVGColDol(): integer;
function GetKolDolCount(): integer;
procedure GetEmptyPrep(Grid: TStringGrid);
procedure GetEmptyGroup(Grid: TStringGrid);
end;
implementation
constructor TSpisok.Create();
begin
FCount:=0;
PFirst:=nil;
PLast:=nil;
PNow:=nil;
end;
procedure TSpisok.AddFirst(sGroup,sPrep: String; iKolDol: Integer);
var
p:TCeh2; //хранит адрес новой созданой переменой
begin
if FCount=0 then
begin
PFirst:=TCeh2.Create(sGroup,sPrep, iKolDol); //cоздается новый элемент
PLast:= PFirst;
FCount:= FCount+1;
end
else // если > нуля
begin
p:= TCeh2.Create(sGroup,sPrep, iKolDol); //создание нового элемнта
p.next:= PFirst;
PFirst.prev:= p;
PFirst:=p;
FCount:= FCount+1;
end;
end;
//удаление текущего элемента
procedure TSpisok.DeleteCurrent();
begin
if PNow=nil then //если текущий не задан
else
begin
if PNow.next=nil then //если текущий - это последний
begin
PLast:=PNow.Pprev; //переводим указатель PLast на предпоследний
PLast.Pnext:= nil; //делаем его последним
end
else
PNow.next.prev:=PNow.prev;//иначе, устанавливаем указатель со следующего от текущего на предыдущий от текущего
if PNow.Pprev=nil then //если текущий - это первый
begin
PFirst:=PNow.next; //смещаем указатель PFirst на второй
PFirst.Pprev:= nil; //делаем его первым
end
else
PNow.prev.next:=PNow.next;//иначе, устанавливаем указатель...
end;
PNow.Destroy; //освобождение памяти
PNow:=nil;
FCount:=FCount - 1;
end;
function TSpisok.GetFirst():TCeh2; // навигация: первый элемент
begin
PNow:=PFirst; //текущий элемент - первый элемент
result:=PNow; //стрелочка, как результат, перемещается на первый элемент
end;
function TSpisok.GetLast():TCeh2; //навигация: последний элемент
begin
PNow:=PLast; //текущий - последний
result:=PNow; //стрелочка, как результт, перемещается на последний элемент
end;
function TSpisok.GetNext():TCeh2; //навигация: следующий элемент
begin
if PNow=nil then //если нет указателя на текущий
begin
result:=PNow; // ничего не делается (стрелка не бегает)
end
else // если же есть указатель на текущий, то
begin
PNow:=PNow.next; // текущий - тот, который следующий
result:=PNow; // стрелка переместилась вниз
end;
end;
function TSpisok.GetPrev():TCeh2;// навигация: предыдущий элемент
begin
if PNow=nil then
begin
result:=PNow;
end //аналогично, как и для следующего элемента
else
begin
PNow:=PNow.prev;
result:=PNow;
end;
end;
//добавление в конец
procedure TSpisok.AddLast(sGroup,sPrep: String; iKolDol: Integer);
var
p:TCeh2; //хранит адрес новой созданой переменой
begin
if FCount=0 then //если всего один элемент
begin
PFirst:=TCeh2.Create(sGroup,sPrep, iKolDol);
PLast:= PFirst; //этот же элемент и первый и последний
FCount:= FCount+1;
end
else
begin //если были другие элементы
p:= TCeh2.Create(sGroup,sPrep, iKolDol);
p.prev:= PLast; //тот, что был последним, теперь предпоследний
PLast.next:= p;//указатель с предпоследнего на последний
PLast:=p; //новый элемент стал последним в списке
FCount:= FCount+1;
end;
end;
//добавление поле текущего
procedure TSpisok.AddNext(sGroup,sPrep: String; iKolDol: Integer);
var
p:TCeh2; //хранит адрес новой созданой переменой
begin
if PNow = nil then//если нет указателя на текущий
else //ничего не делаем
begin
p:= TCeh2.Create(sGroup,sPrep, iKolDol);
p.prev:= PNow; //предыдущий для нового - это текущий
p.next:= PNow.next; //следующий для текущего - следующий для нового
if PNow.next = nil then //если добавляем после последнего
PLast:=p //новый - стал последним
else
PNow.next.prev:= p; //новый стал предыдущим для следующего
PNow.next:= p; //новый - теперь следующий для текущего
FCount:= FCount+1;
end;
end;
//добавление перед текущим
procedure TSpisok.AddPrev(sGroup,sPrep: String; iKolDol: Integer);
var
p:TCeh2; //хранит адрес новой созданой переменой
begin
if PNow = nil then //если нет указателя на текущий
else //ничего не делаем
begin
p:= TCeh2.Create(sGroup,sPrep, iKolDol);
p.next:=PNow; //следующий для нового - текущий
p.prev:= PNow.prev; //предыдущий для текущего - предыдущий для нового
if PNow.prev = nil then //если добавляем перед первым
PFirst:=p //новый - стал первым
else
PNow.prev.next:= p; //новый стал следующим для предыдущего
PNow.prev:= p; //новый - теперь предыдущий для текущего
FCount:= FCount+1;
end;
end;
procedure TSpisok.ToGrid(Grid: TStringGrid); //вывод в стринггрид
var // и навигация
i: Integer;
p:TCeh2;
begin
Grid.RowCount:= FCount + 1;
Grid.ColCount:= 5;
Grid.Cells[1,0]:='№';
Grid.Cells[2,0]:= 'Преподаватель';
Grid.Cells[3,0]:= 'Группа';
Grid.Cells[4,0]:= 'Кол-во задолжников';
Grid.ColWidths[0]:= 25;
Grid.ColWidths[1]:= 25;
Grid.ColWidths[2]:= 225;
Grid.ColWidths[3]:= 110;
Grid.ColWidths[4]:= 150;
p:= PFirst;
for i:= 1 to FCount do
begin
if PNow = p then
Grid.Cells[0,i]:= '*'
else
Grid.Cells[0,i]:= '';
Grid.Cells[1,i]:= IntToStr(i);
Grid.Cells[2,i]:= p.sPrep;
Grid.Cells[3,i]:= p.sGroup;
Grid.Cells[4,i]:= IntToStr(p.iKolDol);
p:= p.next;
end;
end;
//поиск
function TSpisok.Search(Value: string; field: Integer): TCeh2;
var
i:integer;
begin
Result:= nil;
PNow:= PFirst;
case field of
1:
for i:= 0 to FCount - 1 do
if Value = PNow.Prep then
begin
Result:= PNow;
break;
end
else
PNow:= PNow.next;
2:
for i:= 0 to FCount - 1 do
if Value = PNow.Group then
begin
Result:= PNow;
break;
end
else
PNow:= PNow.next;
3:
for i:= 0 to FCount - 1 do
if Value = IntToStr(PNow.KolDol) then
begin
Result:= PNow;
break;
end
else
PNow:= PNow.next;
end;
end;
procedure TSpisok.ToFile(Fname: string);
var
FL:TextFile;
i: integer;
p: TCeh2;
begin
AssignFile(FL, Fname); // работаем с конкретным файлом
Rewrite(FL); //отчищаем файл
p:= PFirst;
for i:= 0 to FCount - 1 do
begin
Writeln(FL, p.Group);
Writeln(FL, p.Prep);
Writeln(FL, inttostr(p.KolDol));
p:= p.next;
end;
CloseFile(FL);
end;
procedure TSpisok.FromFile(Fname: string);
var
FL:TextFile;
tGroup: String;
tprep: String;
tkol: String;
i: Integer;
p: TCeh2;
begin
PNow:= PFirst;
for i:= 0 to FCount - 1 do
begin //удаление списка
p:= PNow.next;
PNow.Destroy();
PNow:= p;
end;
FCount:= 0;
AssignFile(FL, Fname); // работаем с файлом
Reset(FL);
while not EOF(FL) do
begin
Readln(FL, tgroup);
Readln(FL, tprep);
Readln(FL, tkol);
AddFirst(tgroup, tprep, StrToInt(tkol));
end;
CloseFile(FL);
end;
///////////////////////////
//10 функций
//среднее количество задолжников
function TSpisok.GetAVGColDol;
var
a:integer;
p:TCeh2;
begin
a:=0;
p:=PFirst;
while (p = nil) = false do
begin
a:= a + p.iKolDol;//сумма всех количеств задолжников
p:= p.next;
end;
if(FCount = 0) then
result:= 0
else
result:= round(a/FCount);
end;
//количество всех задолжников
function TSpisok.GetKolDolCount;
var
a:integer;
p:TCeh2;
begin
a:=0;
p:=PFirst;
while (p = nil) = false do
begin
a:= a + p.iKolDol;
p:= p.next;
end;
result:= a;
end;
//поиск группы с максимальным количеством задолжников
function TSpisok.GetMaxColDol;
var
a:TCeh2;
p:TCeh2;
begin
a:=PFirst;
p:=PFirst;
while (p = nil) = false do
begin
if a.iKolDol < p.iKolDol then
a:= p;
p:= p.next;
end;
result:= a;
end;
//поиск группы с минимальным количеством задолжников
function TSpisok.GetMinColDol;
var
a:TCeh2;
p:TCeh2;
begin
p:=PFirst;
a:=p;
while (p = nil) = false do
begin
if a.iKolDol > p.iKolDol then
a:= p;
p:= p.next;
end;
result:= a;
end;
//вывод в таблицу групп с количеством задолжников больше введенного значения
procedure TSpisok.SearchWhereKolDolMore(value: Integer; Grid: TStringGrid);
var
i: Integer;
a: integer;
p:TCeh2;
begin
Grid.RowCount:= FCount + 1;
Grid.ColCount:= 5;
Grid.Cells[1,0]:='№';
Grid.Cells[2,0]:= 'Преподаватель';
Grid.Cells[3,0]:= 'Группа';
Grid.Cells[4,0]:= 'Кол-во задолжников';
Grid.ColWidths[0]:= 25;
Grid.ColWidths[1]:= 25;
Grid.ColWidths[2]:= 225;
Grid.ColWidths[3]:= 110;
Grid.ColWidths[4]:= 150;
p:= PFirst;
a:= 1;
for i:= 1 to FCount do
begin
Grid.Cells[0,i]:= '';
Grid.Cells[1,i]:= '';
Grid.Cells[2,i]:= '';
Grid.Cells[3,i]:= '';
Grid.Cells[4,i]:= '';
p:= p.next;
end;
p:= PFirst;
for i:= 1 to FCount do
begin
if p.iKolDol > value then
begin
Grid.Cells[0,a]:= '';
Grid.Cells[1,a]:= IntToStr(i);
Grid.Cells[2,a]:= p.sPrep;
Grid.Cells[3,a]:= p.sGroup;
Grid.Cells[4,a]:= IntToStr(p.iKolDol);
a:= a + 1;
end;
p:= p.next;
end;
end;
//вывод в таблицу групп с количеством задолжников меньше введенного значения
procedure TSpisok.SearchWhereKolDolLess(value: Integer; Grid: TStringGrid);
var
i: Integer;
a: integer;
p:TCeh2;
begin
Grid.RowCount:= FCount + 1;
Grid.ColCount:= 5;
Grid.Cells[1,0]:='№';
Grid.Cells[2,0]:= 'Преподаватель';
Grid.Cells[3,0]:= 'Группы';
Grid.Cells[4,0]:= 'Кол-во задолжников';
Grid.ColWidths[0]:= 25;
Grid.ColWidths[1]:= 25;
Grid.ColWidths[2]:= 225;
Grid.ColWidths[3]:= 110;
Grid.ColWidths[4]:= 150;
p:= PFirst;
a:= 1;
for i:= 1 to FCount do
begin
Grid.Cells[0,i]:= '';
Grid.Cells[1,i]:= '';
Grid.Cells[2,i]:= '';
Grid.Cells[3,i]:= '';
Grid.Cells[4,i]:= '';
p:= p.next;
end;
p:= PFirst;
for i:= 1 to FCount do
begin
if p.iKolDol < value then
begin
Grid.Cells[0,a]:= '';
Grid.Cells[1,a]:= IntToStr(i);
Grid.Cells[2,a]:= p.sPrep;
Grid.Cells[3,a]:= p.sGroup;
Grid.Cells[4,a]:= IntToStr(p.iKolDol);
a:= a + 1;
end;
p:= p.next;
end;
end;
//вывод в таблицу цехов с именем преподавателя, содержащего введенную строку
procedure TSpisok.SearchForSubstrPreps(value: string; Grid: TStringGrid);
var
i: Integer;
a: integer;
p:TCeh2;
begin
Grid.RowCount:= FCount + 1;
Grid.ColCount:= 5;
Grid.Cells[1,0]:='№';
Grid.Cells[2,0]:= 'Преподаватель';
Grid.Cells[3,0]:= 'Группа';
Grid.Cells[4,0]:= 'Кол-во задолжников';
Grid.ColWidths[0]:= 25;
Grid.ColWidths[1]:= 25;
Grid.ColWidths[2]:= 225;
Grid.ColWidths[3]:= 110;
Grid.ColWidths[4]:= 150;
p:= PFirst;
a:= 1;
for i:= 1 to FCount do
begin
Grid.Cells[0,i]:= '';
Grid.Cells[1,i]:= '';
Grid.Cells[2,i]:= '';
Grid.Cells[3,i]:= '';
Grid.Cells[4,i]:= '';
p:= p.next;
end;
p:= PFirst;
for i:= 1 to FCount do
begin
if Pos(value, p.sPrep) > 0 then
begin
Grid.Cells[0,a]:= '';
Grid.Cells[1,a]:= IntToStr(i);
Grid.Cells[2,a]:= p.sPrep;
Grid.Cells[3,a]:= p.sGroup;
Grid.Cells[4,a]:= IntToStr(p.iKolDol);
a:= a + 1;
end;
p:= p.next;
end;
end;
//вывод в таблицу групп с именем группы, содержащего введенную строку
procedure TSpisok.SearchForSubstrGroup(value: string; Grid: TStringGrid);
var
i: Integer;
a: integer;
p:TCeh2;
begin
Grid.RowCount:= FCount + 1;
Grid.ColCount:= 5;
Grid.Cells[1,0]:='№';
Grid.Cells[2,0]:= 'Преподватель';
Grid.Cells[3,0]:= 'Группа';
Grid.Cells[4,0]:= 'Кол-во задолжников';
Grid.ColWidths[0]:= 25;
Grid.ColWidths[1]:= 25;
Grid.ColWidths[2]:= 225;
Grid.ColWidths[3]:= 110;
Grid.ColWidths[4]:= 150;
p:= PFirst;
a:= 1;
for i:= 1 to FCount do
begin
Grid.Cells[0,i]:= '';
Grid.Cells[1,i]:= '';
Grid.Cells[2,i]:= '';
Grid.Cells[3,i]:= '';
Grid.Cells[4,i]:= '';
p:= p.next;
end;
p:= PFirst;
for i:= 1 to FCount do
begin
if Pos(value, p.sGroup) > 0 then
begin
Grid.Cells[0,a]:= '';
Grid.Cells[1,a]:= IntToStr(i);
Grid.Cells[2,a]:= p.sPrep;
Grid.Cells[3,a]:= p.sGroup;
Grid.Cells[4,a]:= IntToStr(p.iKolDol);
a:= a + 1;
end;
p:= p.next;
end;
end;
//вывод в таблицу групп с пустым именем группы
procedure TSpisok.GetEmptyGroup(Grid: TStringGrid);
var
i: Integer;
a: integer;
p:TCeh2;
begin
Grid.RowCount:= FCount + 1;
Grid.ColCount:= 5;
Grid.Cells[1,0]:='№';
Grid.Cells[2,0]:= 'Преподаватель';
Grid.Cells[3,0]:= 'Группа';
Grid.Cells[4,0]:= 'Кол-во задолжников';
Grid.ColWidths[0]:= 25;
Grid.ColWidths[1]:= 25;
Grid.ColWidths[2]:= 225;
Grid.ColWidths[3]:= 110;
Grid.ColWidths[4]:= 150;
p:= PFirst;
a:= 1;
for i:= 1 to FCount do
begin
Grid.Cells[0,i]:= '';
Grid.Cells[1,i]:= '';
Grid.Cells[2,i]:= '';
Grid.Cells[3,i]:= '';
Grid.Cells[4,i]:= '';
p:= p.next;
end;
p:= PFirst;
for i:= 1 to FCount do
begin
if p.sGroup = '' then
begin
Grid.Cells[0,a]:= '';
Grid.Cells[1,a]:= IntToStr(i);
Grid.Cells[2,a]:= p.sPrep;
Grid.Cells[3,a]:= p.sGroup;
Grid.Cells[4,a]:= IntToStr(p.iKolDol);
a:= a + 1;
end;
p:= p.next;
end;
end;
//вывод в таблицу групп с пустым именем преподавателя
procedure TSpisok.GetEmptyPrep(Grid: TStringGrid);
var
i: Integer;
a: integer;
p:TCeh2;
begin
Grid.RowCount:= FCount + 1;
Grid.ColCount:= 5;
Grid.Cells[1,0]:='№';
Grid.Cells[2,0]:= 'Преподватель';
Grid.Cells[3,0]:= 'Группа';
Grid.Cells[4,0]:= 'Кол-во задолжников';
Grid.ColWidths[0]:= 25;
Grid.ColWidths[1]:= 25;
Grid.ColWidths[2]:= 225;
Grid.ColWidths[3]:= 110;
Grid.ColWidths[4]:= 150;
p:= PFirst;
a:= 1;
for i:= 1 to FCount do
begin
Grid.Cells[0,i]:= '';
Grid.Cells[1,i]:= '';
Grid.Cells[2,i]:= '';
Grid.Cells[3,i]:= '';
Grid.Cells[4,i]:= '';
p:= p.next;
end;
p:= PFirst;
for i:= 1 to FCount do
begin
if p.sPrep = '' then
begin
Grid.Cells[0,a]:= '';
Grid.Cells[1,a]:= IntToStr(i);
Grid.Cells[2,a]:= p.sPrep;
Grid.Cells[3,a]:= p.sGroup;
Grid.Cells[4,a]:= IntToStr(p.iKolDol);
a:= a + 1;
end;
p:= p.next;
end;
end;
constructor TCeh2.Create(); // конструктор без параметров
begin
Pnext:=nil;
Pprev:=nil;
sGroup:='Empty';
sPrep:='Empty';
iKolDol:=0;
end;
constructor TCeh2.Create(n,b: String; kr: Integer); // конструктор c параметрами
begin
Pnext:=nil;
Pprev:=nil;
sGroup:=n;
sPrep:=b;
iKolDol:=kr;
end;
destructor TCeh2.Destroy(); // Деструктор
begin
// Деструктор
end;
// Процедуры установки параметров класса
procedure TCeh2.Set_prev(pp: TCeh2);
begin
Pprev:=pp;
end;
procedure TCeh2.Set_next(pn: TCeh2);
begin
Pnext:=pn;
end;
procedure TCeh2.Set_Group(n: String);
begin
sGroup:=n;
end;
procedure TCeh2.Set_Prep(b: String);
begin
sPrep:=b;
end;
procedure TCeh2.Set_KolDol(kr: Integer);
begin
iKolDol:=kr;
end;
// Функции чтения параметров класса
function TCeh2.Get_prev():TCeh2;
begin
Result:=Pprev;
end;
function TCeh2.Get_next():TCeh2;
begin
Result:=Pnext;
end;
function TCeh2.Get_Group():String;
begin
Result:=sGroup;
end;
function TCeh2.Get_Prep():String;
begin
Result:=sPrep;
end;
function TCeh2.Get_KolDol():Integer;
begin
Result:=iKolDol;
end;
end.