Program Osszegfokozatok;{MEGOLDÁS}
{
Feladat:
Az alábbi szerkezetű file beolvasása és
kilistázása úgy, hogy
közben a megfelelő "struktúraváltásokkor"
ki kell egészíteni
az ún. összegfokozat rekorddal. Vagyis egy új
tanszék indulásakor
a lezárult tanszék összegfokozata zárja a
tanszéki sorokat; egy új
kar esetében nemcsak az lezárult tanszék,
hanem a kar összegfokozat
rekordja is generálandó. Azaz a "záró"
rekordok száma vagy 1, vagy
2, vagy 3.
Mind a nyitó, mind az aktuális strukturához
tartozó összegfokozati
rekord egy lapon kell megjelenjen.
(Feltesszük, hogy ez lehetséges.)
Összegfokozat tartalmazza:
Az aktuális struktúrát azonosító mezők
értékeit (de csak azokat)
és az ebbe a struktúrába tartozó elemek
számát v. összegét ...
(hogy mit, az feladatfüggő).
Bevezető, "előfeladatok":
1. Síma, lapozott lista.
kiférjenek egy lapra (a tanszék
nyitórekorddal együtt).
Ef: nincs tanszék, ahol többen
dolgoznának, mint a képernyősorok
száma-1.
File-szerkezet:
1. szint: EGYETEM
szintkód, név, rektori hivatal cím,
tel.szám
karok
2. szint: KAR
szintkód, név, dékáni hivatal cím,
tel.szám
tanszékek (tanszéki egységek)
3. szint: TANSZÉKEK
szintkód, név, tanszékcím, tel.szám
dolgozók
4. szint: DOLGOZÓ
szintkód, név, lakcím, tel.szám, fizetés,
...
Feltételezés:
A file strukturálisan helyes,
tanszékenként nem üres, de
az adott listázási feladatban kikötött
számút nem haladja
meg.
Megjegyzés:
A file csupa azonos típusú elemből áll.
Ezért a struktúra-
nyitó elemek kiegészülnek
--"tartalom nélküli"-- mezőkkel,
amelyeket föl lehet használni az összegfokozatok
utólagos
tárolására.
}
Uses
Newdelay,Crt;
{$i Randnev.inc}
Type
TSzint=(Dolgozo,Tanszek,Kar,Egyetem,Ures);
Const KSzint:Array [TSzint] of String=(' ','T','K','E','');{kiirandó}
szintKodH=1;
nevH=28; cimH=26; telH=9; fizuH=6; {kiíráshossz}
Type
TElem=Record
szintKod:TSzint;
fiz:LongInt;
End;
Type
TFile=File of TElem;
TMegnyitasMod=(Letrehozas,Olvasas);
Const LaphOssz=20;
{$i osszfok.inc --
ebben találhatók a lényeg szemponjából
kevésbé fontos
általános konstansok, változók,
eljárások, függvények.
Pl. Var sor:Byte, ami a képernyőre kiirt
sorok számát tartalmazza
Procedure ElemKi kiír egy elemet a
fejléchez igazodva (izlésesen)
Procedure Lapoz, ami lapot töröl, és
fejlécet ír ki, sor-t nulláz
Procedure BillreVar, ami
billenytyű-lenyomásra vár
Procedure Megnyit file-t, megfelelo
modon
Procedure General adatfile-t a fenti
szerkezetben
Procedure Lezar file-t
Procedure Inic, ami inicalizßlja a
kiÝrßst (~MegnyitLista)
}
{
Listázó rutinok:
1. Listaz
-- egyszerü (természetes) virtális típus
bevezetésével
2. ListazMaskent
-- (általánosítható) virtális típus
bevezetésével
(útban a tanszékenkétni listázás felé)
3. TanszTordListaz
-- listázás 'tanszék dologozók együtt
maradásával' feltétellel
}
Procedure Listaz(Var f:TFile);
(*
Virtuális típusok:
Input:
TBeLap=TFile
BeNyit,BeVége?,Beolvas,Bezár
(A reprezentáció egyszerüsége
miatt:)
* BeNyit=Megnyitas,
* BeVége?=Eof,
* Beolvas=Read,
* Bezár=Lezar
Output:
TKiLap="Rekord"(sor:Egész,képernyö:TKépernyö)
=sor:Egész
KiNyit,Kiir,Kizár
* KiNyit=Lapoz,
* Kiir=ElemKi,
* Kizár=BillreVar, ha kell;
képernyöt töröl
*)
{
Típus-reprezentációk:
Var sor:Byte; <-- osszfok.inc
}
{
Típus-implementációk:
}
Procedure Kizar{képernyö:TKilap};
Begin
If sor>0
then BillreVar;
ClrScr
End;
{
A megoldás:
}
Var
elem:TElem;
Begin{Listaz}
Megnyit(f,Olvasas);
Lapoz{képernyö};
While not Eof(f) do
Begin
Read(f,elem);
ElemKi({képernyö,}elem);
End;
Lezar(f); Kizar{képernyö}
End{Listaz};
(*
----------------------------------------------------------------- *)
Procedure ListazMaskent(Var f:TFile);
(*
Virtuális típusok:
Input:
TBeLap=Rekord(db:Egész, sorok:Tömb(1..LapHossz:TElem))
BeNyit,BeVége?,BeOlvas,BeZár
* BeNyit=
a) Megnyitas+belap-puffer
inicializálás,
b) Megnyitas+semmi
* BeVége?=Eof,
* BeOlvas=
a) pufferbe olvasás betelésig,
b) pufferbe olvasás 1-től, amíg
lehet
* BeZár=Lezar
Output:
TKiLap="Rekord"(sor:Egész,képernyö:TKépernyö)
=sor:Egész
KiNyit,KiIr(belap-puffer!),KiZár
* KiNyit=Lapoz,
* KiIr=
a) belap-puffer kiírása
+ várakozás
+ Lapoz
+ puffer inicializálása
b) belap-puffer kiírása
+ várakozás
+ Lapoz
+ (a puffert nem változtatja
meg!)
* KiZár=Várakozás (ha kell) +
ClrScr
*)
{
Típus-reprezentációk:
}
Type TBeLap=Record
db:Byte;
sorok:Array [1..LapHossz] of TElem;
End;
Var
egyTanszek:TBeLap;
{sor:Byte; <-- osszfok.inc}
{
Típus-implementációk:
}
Procedure BeNyit(Var f:TFile);
Begin
Megnyit(f,Olvasas);
egyTanszek.db:=0;
End;
Procedure Beolvas(Var f:TFile {;Var egyTanszek:TBeLap});
Begin
While Not Eof(f) and (egyTanszek.db<LapHossz) do
Begin
Inc(egyTanszek.db);
Read(f,egyTanszek.sorok[egyTanszek.db]);
End;
End;
Procedure Kiir{Var
képernyö:TKépernyö, Var egyTanszek:TBelap};
Var i:Integer;
Begin
For i:=1
to egyTanszek.db do
Begin
ElemKi({képernyö,}egyTanszek.sorok[i]); {nem használom ki, hogy
figyeli a sorok számát}
End;
egyTanszek.db:=0;
BillreVar; Lapoz;
End;
{
A megoldás:
}
Begin{ListazMaskent}
Benyit(f); Lapoz{képernyö};
While not Eof(f) do
Begin
Beolvas(f{,egyTanszek});
Kiir{képernyö,egyTanszek};
End;
Lezar(f); ClrScr
End{ListazMaskent};
(*
----------------------------------------------------------------- *)
Procedure TanszTordListaz(Var f:TFile);
(*
Virtuális típusok:
Input:
bemeneti egység vagy egy tanszék összes dolgozója a nyitóval
vagy valami más
elem
a bementi eleme határát csak
előreolvasási technikával
tudjuk megtalálni
TBeEgyseg=Rekord(db:Egész,
e:TElem [az
elöreolvasott],
sorok:Tömb(1..MaxTszDolg+1:TElem))
Elöfeltétel =>
MaxTszDolg+1=LapHossz
BeNyit,BeVége?,Beolvas,Bezár
* BeNyit=Megnyitas+belap-puffer
inicializálás+elöreolvasás
* BeVége?=Eof,
* Beolvas=egységolvasás
elöreolvasással,
* Bezár=Lezar
Output:
TKiLap="Rekord"(sor:Egész,képernyö:TKépernyö)
=sor:Egész
KiNyit,Kiir(belap-puffer!),Kizár
* KiNyit=Lapoz,
* Kiir=belap-puffer kiírása+sor-állítás,
ha még kifér
ha nem fér ki, akkor
+ várakozás
+ Lapoz
+ puffer inicializálása
* Kizár= várakozás + ClrScr
*)
{
Típus-reprezentációk:
}
Type TBeEgyseg=Record
db:Byte;
e:TElem;{az elöreolvasott}
elemek:Array [1..LapHossz] of TElem;
End;
Var
egyTanszek:TBeEgyseg;
{sor:Byte; <-- osszfok.inc}
{
Típus-implementációk:
}
Procedure BeNyit(Var f:TFile);
Begin
Megnyit(f,Olvasas);
egyTanszek.db:=0;
Read(f,egyTanszek.e);
End;
Procedure Beolvas(Var f:TFile {;Var egyTanszek:TBeLap});
{Ef: NOT Eof(f) AND e=elöreolvasott
elem}
Begin
egyTanszek.db:=1;
egyTanszek.elemek[1]:=egyTanszek.e;
Read(f,egyTanszek.e);
While Not Eof(f) and (egyTanszek.e.szintKod=Dolgozo) do
Begin
Inc(egyTanszek.db);
egyTanszek.elemek[egyTanszek.db]:=egyTanszek.e;
Read(f,egyTanszek.e);
End;
{Uf: Eof(f) => egyTanszek[1..egyTanszek.db]+e=egy
egység AND
NOT Eof(f) => e=következö nem
dolgozó elem}
If Eof(f)
then
Begin
Inc(egyTanszek.db);
egyTanszek.elemek[egyTanszek.db]:=egyTanszek.e;
End;
{Uf: egyTanszek[1..egyTanszek.db]=egy
egység AND
Eof(f) => e=üres AND
NOT Eof(f) => e=következö nem
dolgozó elem}
End;
Procedure Kiir{Var
képernyö:TKépernyö, Var egyTanszek:TBelap};
Var i:Integer;
Begin
If sor+egyTanszek.db>LapHossz
then
Begin
BillreVar;
Lapoz;
End;
For i:=1
to egyTanszek.db do
Begin
ElemKi({képernyö,}egyTanszek.elemek[i]); {nem használom ki, hogy
figyeli a sorok számát,
csak, hogy kiírja és a
sor-t növeli}
End;
egyTanszek.db:=0;
End;
Procedure Kizar{képernyö:TKilap};
Begin
If sor>0
then BillreVar;
ClrScr
End;
{
A megoldás:
}
Begin{TanszTordListaz}
BeNyit(f); Lapoz;
While not Eof(f) do
Begin
Beolvas(f{,egyTanszek});
Kiir{képernyö,egyTanszek};
End;
KiZar;
End{TanszTordListaz};
(*
----------------------------------------------------------------- *)
Procedure OsszFokosListaz(Var f:TFile);
(*
Virtuális típusok:
Input:
bemeneti egység vagy egy tanszék összes dolgozója a nyitóval
vagy valami más
elem
a bementi eleme határát csak
előreolvasási technikával
tudjuk megtalálni
TBeEgyseg=Rekord(db:Egész,
e:TElem [az
elöreolvasott],
elemek:Tömb(1..MaxTszDolg+6:TElem))
Elöfeltétel => MaxTszDolg+6=LapHossz
(a +6-hoz:
legrosszabb esetben 3 nyitó rekord
+
legrosszabb esetben 3 összfok rekord)
BeNyit,BeVége?,Beolvas,Bezár
* BeNyit=Megnyitas+belap-puffer
inicializálás+elöreolvasás
* BeVége?=Eof,
* Beolvas=egységolvasás
elöreolvasással,
* Bezár=Lezar
Output:
TKiLap="Rekord"(sor:Egész,képernyö:TKépernyö)
=sor:Egész
KiNyit,Kiir(belap-puffer!),Kizár
* KiNyit=Lapoz,
* Kiir=belap-puffer
kiírása+sor-állítás, ha még kifér
ha nem fér ki, akkor
+ várakozás
+ Lapoz
+ puffer inicializálása
* Kizár= várakozás + ClrScr
*)
{
Típus-reprezentációk:
}
Const UresTElem:TElem=(szintKod:Ures;
Type TBeEgyseg=Record
db:Byte;
e:TElem;{az elöreolvasott}
elemek:Array [1..LapHossz] of TElem;
End;
Var
egyTanszek:TBeEgyseg;
{sor:Byte; <-- osszfok.inc}
osszFok:Array [TSzint] of TElem;
{
Típus-implementációk:
}
Procedure BeNyit(Var f:TFile);
Begin
Megnyit(f,Olvasas);
Read(f,egyTanszek.e); {Elöreolvasás:egyetem}
End;
Procedure Beolvas(Var f:TFile {;Var egyTanszek:TBeLap});
{Ef: NOT Eof(f) AND e=elöreolvasott
vmilyen szintü nyitó elem}
Var i:TSzint;
Begin
egyTanszek.db:=0;
{tanszéki dolgozókat megelözö,
"felsöbb" szintü nyitő elemek
beolvasása, inicializálás:}
For i:=egyTanszek.e.szintKod
downto Tanszek do
Begin
Inc(egyTanszek.db);
egyTanszek.e.fiz:=0;
{nyitó
elem fizu-ja 0-zandó}
egyTanszek.elemek[egyTanszek.db]:=egyTanszek.e;
osszFok[i]:=egyTanszek.e;
{osszFok[i].fiz:=0;}
Read(f,egyTanszek.e);
{elöreolvasás}
End;
{Uf: egyTanszek.e=elöreolvasott dolgozó}
{egy tanszék beolvasása, elkönyvelése:}
While Not Eof(f) and (egyTanszek.e.szintKod=Dolgozo) do
Begin
Inc(egyTanszek.db);
egyTanszek.elemek[egyTanszek.db]:=egyTanszek.e;
Inc(osszFok[Tanszek].fiz,egyTanszek.e.fiz);
Read(f,egyTanszek.e);
End;
{Uf: Eof(f) => egyTanszek[1..egyTanszek.db]+e=egy
egység AND
NOT Eof(f) => e=következö nem
dolgozó elem}
If Eof(f)
then
Begin
Inc(egyTanszek.db);
egyTanszek.elemek[egyTanszek.db]:=egyTanszek.e;
Inc(osszFok[Tanszek].fiz,egyTanszek.e.fiz);
End;
{Uf: egyTanszek[1..egyTanszek.db]=egy
egység AND
Eof(f) => e=üres AND
NOT Eof(f) => e=következö nem
dolgozó elem}
End;
Procedure Kinyit{Var
képernyö:TKépernyö};
Begin
egyTanszek.db:=0;
Lapoz;
End;
Procedure Kiir{Var
képernyö:TKépernyö, Var egyTanszek:TBelap};
Var i:Integer;
Begin
If sor+egyTanszek.db>LapHossz
then
Begin
BillreVar;
Lapoz;
End;
For i:=1
to egyTanszek.db do
Begin
ElemKi({képernyö,}egyTanszek.elemek[i]); {nem használom ki, hogy
figyeli a sorok számát,
csak, hogy kiírja és a
sor-t növeli}
End;
egyTanszek.db:=0;
End;
Procedure Kizar{képernyö:TKilap};
Var i:TSzint;
Begin
If sor>0
then BillreVar;
ClrScr
End;
{
A megoldás:
}
Var
i,ig:TSzint;
Begin{OsszFokosListaz}
Benyit(f); Kinyit{képernyö};
{összfokozatok generálása a beolvasott
tanszékhez:}
While not Eof(f) do
Begin
Beolvas(f{,egyTanszek});
If Eof(f)
then
Begin
ig:=Egyetem
End
else
Begin
ig:=egyTanszek.e.szintKod
End{If Eof};
For i:=Tanszek
to ig do
Begin
Inc(osszFok[Succ(i)].fiz,osszFok[i].fiz); {összfokozat göngyölítés}
{összfokozat hozzávétele:}
Inc(egyTanszek.db);
egyTanszek.elemek[egyTanszek.db]:=osszFok[i];
osszFok[i]:=UresTElem;
End;
{Az egység kiírása:}
Kiir{képernyö,egyTanszek};
End;
Lezar(f); Kizar{képernyö};
End{OsszFokosListaz};
Var
egy:TFile;
Begin
Inic;
ClrScr;
HighVideo;
Writeln(Kozepre('File-létrehozás',80)); NormVideo;
Megnyit(egy,Letrehozas);
General(egy);
Lezar(egy);
ClrScr;
HighVideo;
Writeln(Kozepre('Síma listázás',80)); NormVideo;
{Sima listázás:}
Listaz(egy);
(*
ClrScr;
HighVideo; Writeln(Kozepre('Síma listázás --
másként',80)); NormVideo;
{Sima listázás, másként:}
ListazMaskent(egy);
ClrScr;
HighVideo; Writeln(Kozepre('Tanszékre tördelt
listázás',80)); NormVideo;
{TanszékreTördeltListázás:}
TanszTordListaz(egy);
*)
ClrScr;
HighVideo;
Writeln(Kozepre('Összegfokozatos listázás',80)); NormVideo;
{Összfokos listázás:}
OsszFokosListaz(egy);
End.