Zárthelyi feladatok és megoldások

Programozás c. tárgyból


Programozás zárthelyi I.VI.                         1996.11.28/B 

Minden lap tetejére írja fel balra a feladat számát, jobbra a nevét és tankörét! A megoldásokban csak STANDARD PASCAL utasításokat, strukturált konstansokat és az assign elôre definiált eljárást használhatja. A megoldások során feltételezheti, hogy minden szükséges input adat az elôírt formátumban rendelkezésre áll. A bemeneti file-okat csak egyszer olvashatja be és nem használhat munka file-t. A feladatok helyes, mûködôképes megoldásával a feladatnál elérhetô pontszám 70%-a szerezhetô meg. A további 30% a nyelvi lehetôségek helyes alkalmazása és az algoritmusok eleganciája, ötletessége alapján szerezhetô. Nem kell törekedni a trükkös megoldásokra, de a durva, ügyetlen módszereket kerülni kell.

1. feladat                                                  10p
Mit nyomtat a következô PASCAL program? Jelölje a szóközöket és soremelést is ! Ne csak a végeredményt adja meg, hanem a jellemzô változó értékeket is!

program namit(input, output);
type torpe_t = (hapci,tudor,vidor,szende,szundi,morgo,kuka,hofeherke);
  banya_t = set of torpe_t;
  duma_t = array [1..17] of char;
var duma: ^duma_t;
  banya, szenbanya: banya_t;
  torpe: torpe_t;
  i: integer;
begin
  new(duma);
  duma^ := 'A gonosz mostoha ';
  banya:= []; szenbanya:= [tudor, vidor, hofeherke];
  for torpe:= kuka downto hapci do begin
    if not odd(ord(torpe)) then
      banya:= banya + [torpe]
    else
      writeln(' ':ord(torpe)+1, duma^);
  end;
  banya:= banya - szenbanya;
  i:= 0;
  torpe:= hapci;
  repeat
    if torpe in banya then
      i:= succ(i);
    torpe:= succ(torpe);
  until torpe > kuka;
  writeln('A banyaban csak ', i, ' torpe van');
  end.


2. feladat                                                  10p
Írjon PASCAL programot, amely statisztikát készít arról, hogy standard inputon file végéig érkezô szövegben melyik irodalmi hivatkozás hányszor szerepelt! A szövegben az irodalmi hivatkozások szögletes zárójelek között elhelyezkedô maximum 2 jegyû egész számmal vannak jelezve. Pl: [8], [77]. Az eredményt az elôfordulási szám szerint növekvô sorrendben írja ki a standard outputra. Feltételezheti, hogy a szövegben csak az irodalmi hivatkozások jelölésére használnak szögletes zárójeleket. 


3. feladat                                                  10p
Írjon PASCAL függvényt, amely kiszámítja egy maximum 50. fokú polinom helyettesítési értékét! A függvény paraméterként kapja a polinom fokszámát (N), egy maximum 51 elemû valós tömböt (A), amely az együtthatókat tartalmazza, valamint a független változó értékét (X), ahol a helyettesítési értéket kell kiszámolni. Az együtthatókat tartalmazó tömb 0. eleme tartalmazza az N. együtthatót, és az N. elem pedig az 0. együtthatót.
TYPE EHATO_T = ARRAY [0..50] OF REAL;
FUNCTION POLINOM(N: INTEGER; A: EHATO_T, X:REAL): REAL;

4. feladat                                                  10p
Készítsen PASCAL programot, amely beolvas egy ilyen szerkezetû szöveges állományt:

s6021san Sándor Balázs István, 1. VI, 1.
s6022and Andricsek Nenád, 1. VI, 2.
s6055fur Für Kovács Csaba, 1. VI, 3.
s6048pal Palotás Endre, 2. VI, 2.
s6050bab Babik Zoltán, 1. VI, 3.
...

Majd a szabványos kimenetre soronként kiírja az elsôéves hallgatók tankörszámait és a neveket ilyen alakban:

1  Sándor Balázs István  1
2  Andricsek Nenád  2
3  Für Kovács Csaba  3
3  Babik Zoltán  3
...

A bemenô adatok minden sora pontosan 5 információs mezôt tartalmaz, melyeket egy szóköz választ el egymástól. A név mezô maga is tartalmaz szóközöket. Egyik sor sem hosszabb mint 80 karakter. Az egyes mezôk sorrendben a következôk:
 
VSZK azonosító:  pontosan 8 karakter
Név:   vesszôvel határolt mezô
Évfolyam:  ponttal határolt mezô
Szak:  vesszôvel határolt mezô
Tankör:  ponttal határolt mezô


5. feladat                                                  20p
Az OTP POS (Point Of Sale) termináljainak forgalmát a következô szerkezetû POS.DAT nevû adatfile-ban rögzítik:
 
számlaszám:  18 karakter
eladóhely azonosítója:  20 karakter
forgalom:  valós szám
dátum:  11 karakter, (1993.11.25.)
idô:  8 karakter, (11:53:23)

A file-ban az adatok rendezetlenül szerepelnek.

Írjon Pascal programot, amely a POS.DAT file alapján számlaszám szerint rendezve kiírja az 1996. november 28-i vásárlások adatait! Feltételezheti, hogy a feladat megoldásához elegendô memória áll rendelkezésére.


Értékelés:
 
Pontszám Osztályzat
0-28 1
29-36 2
37-43 3
44-51 4
52-60 5


Megoldások I.VI.                          1996.11.28/B 

1. feladat
A banya halmaz tipusú változó for ciklus során a hapci, vidor, szundi, kuka értékekból álló halmazt veszi fel értékül. Ebbôl kivonjuk a szenbanya változóban levô tudor, vidor, hofeherke halmazt. Így a banya halmazban csupán három érték marad: [hapci, szundi, kuka]. A for ciklus során a duma pointer által hivatkozott szöveg íródik ki egyre balra tolódva, majd a legutolsó write kiírja, hogy hány elem van a banya változóban. A program a következô eredményt adja:

      A gonosz mostoha
    A gonosz mostoha
  A gonosz mostoha
A banyaban csak 3 torpe van


2. feladat
program feladat_2;
const MAX = 99;  { maximalis irodalom sorszám amire még hivatkozni lehet }
var  irodalom: array [0..MAX] of integer; { ebben tároljuk a hiv. számát }
     hiv: integer;           { ez egy hivatkozás }
     ch: char;               { munkaváltozó a kar. olvasáshoz }
     m, i, j: integer;       { munkaváltozók a kiíratáshoz }
     volt: boolean;         { kiíratáshoz használjuk }
begin
     for i:= 0 to MAX do irodalom[i]:= 0; { feltöltjük 0-val }
     while not eof do begin
       read(ch);             { következô karakter }
       if ch = '[' then begin { ha nyitó zárójel }
         hiv:= 0;
         repeat             { beolvassuk a számot }
           read(ch);          { és átalakítjuk, ha nem zárójel }
           if ch <> ']' then  { feltételezzük, hogy a bemenô adatok jók }
             hiv:= hiv * 10 + ord(ch) - ord('0');
         until ch = ']';      { ezért nincs hiba, vagy file vég vizsgálat }
         irodalom[hiv]:= irodalom[hiv] + 1; { növeljuk a megfelelô számlálót }
       end;
     end;
     repeat
       m:= 0;               { kiválasztjuk az elsôt }
       volt:= false;
       for i:= 1 to MAX do    { keresünk, hogy van-e kisebb }
         if irodalom[i] > 0 then begin
           if (irodalom[i] < irodalom[m]) or (irodalom[m] = 0) then
             then m:= i;      { ha van megjegyezzük }
        end;
       if irodalom[m] > 0 then begin  { ha nem 0, akkor kiírjuk }
         writeln('Hivatkozasok szama [', m, ']-re:', irodalom[m]);
         irodalom[m]:= 0;    { hogy ne talájuk meg mégegyszer }
         volt:= true;         { addig, amig találunk kiírandót }
       end;
     until not volt;
end.



 

3. feladat
A megoldásnál felhasználtuk a polinom szorzattá való átalakításának szabályát (Horner szabály):
  a(n) * X ^ N + a(n-1) X ^ n-1 + ... + a(1) * x + a(0) =
  [[[a(n) * X + a(n-1)] * X + a(n-2)] * X + ... a(1)] * X + a(0)
 

type ehato_t = array [0..50] of real;

function polinom(n: integer; a:ehato_t; x:real): real;
var  y: real;               { részösszeg tárolására }
     i: integer;           { ciklusváltozó }
begin
     y:= 0;                 { eddig 0 a részösszeg }
     for i:= 0 to n do
       y:= y * x + a[i];    { következô részösszeg }
     polinom:= y;           { végeredmény }
end;


4. feladat
program feladat_4;
var  nev: array [1..80] of char; { ennyi biztosan elég lesz a névere }
     tk: integer;               { tankörszámhoz }
     f: text;                   { file olvasához }
     ch: char;
     l, i: integer;

function read_int: integer;      { egész szám beolvasása nem számjegyig }
var  n: integer;                 { ebben lesz a szám }
     ch: char;                   { beolvasott karakter }
     ok: boolean;               { segédváltozó }
begin
     n:= 0;                     { kezdetben 0 }
     repeat
       ok:= false;
       read(ch);                 { következô karakter }
       if (ch >= '0') and (ch <= '9') then begin  { ha szám, akkor ok }
           n:= n * 10 + ord(ch) - ord('0'); { hozzáadjuk }
           ok:= true;
       end
       until not ok;             { egyébként vége a ciklusnak }
     read_int:= n;               { visszatérési érték }
end;

begin
     while not eof do begin
       for i:= 1 to 9 do read(ch); { VSZK azonositó nem kell }
       i:= 1;
       repeat
         read(ch);
         if ch <> ',' then begin
           nev[i]:= ch;           { nevet elteszük }
           i:= i + 1;
         end;
       until ch = ',';           { vesszôig }
       l:= i;                     { ez a név hossza }
       ev:= read_int;             { év }
       repeat
         read(ch);
       until ch = ',';           { szak nem kell }
       read(ch);                 { eldobjuk a szóközt }
       tk:= read_int;             { tankor beolvasása }
       readln;                   { eldobjuk a maradékot }
       if ev = 1 then begin
         write(tk, '  ');         { kiíratjuk a tankorszámot }
         for i:= 1 to l do         { kiíratjuk a nevet }
           write(nev[i]);
         write('  ', tk);         { és a tankörszámot }
       end;
     end;
end. 



5. feladat
A feladatot egy egyszerû számlaszám szerint rendezett lánccal oldjuk meg. A lánc végén stárzsa van, az új elem beszúrását a "beszúrunk elé úgy, hogy mögé szúrunk be" trükkel valósítjuk meg. A láncon már csak a bemeneti feltetelnek megfelelô adatokat tároljuk.

      -> számlaszám -> számlaszám  -> számlaszám  ->  ...

program feladat_5;
type szamla_t = array [1..18] of char; { számla típus }
     eladoh_t = array [1..20] of char;  { eladóhely típus }
     datum_t = array [1..11] of char;   { dátum típus }
     ido_t = array [1..8] of char;      { idô típus }
     posrec_t = record                 { bemenô adatok szerkezete }
        szla: szamla_t;               { számlaszám }
        hely: eladoh_t;               { eladóhely }
        forg: real;                   { forgalom }
        date: datum_t;                 { dátum }
        time: ido_t                   { idô }
     end;
     poi = ^lanc_t;                   { pointer a lánchoz }
     lanc_t = record                   { lánc elem szerkezete }
        adat: posrec_t;               { tárolt adatok }
        kov:  poi                     { következô pointer }
     end;
var  be_rec: posrec_t;                 { ebbe olvasunk be }
     kezdo, futo, uj: poi;             { pointerek }
     f: file of posrec_t;             { bemenô file }
begin
     assign(f, 'pos.dat');             { file nyitás }
     reset(f);
     new(kezdo);                       { strázsa elem (a végén tartjuk) }
     kezdo^.kov:= nil;
     while not eof(f) do begin          { a file végéig }
       read(f, be_rec);               { következô rekord }
       if be_rec.forg > 15000 then begin  { kell tárolni ? }
         futo:= kezdo;                 { befûzzük a láncba }
         while (futo^.kov <> nil) and (futo^.adat.date < be_rec.date) do
           futo:= futo^.kov;
         new(uj);                     { új elem }
         uj^:= futo^;                 { az újba kerül a régi }
         futo^.adat:= be_rec;         { régi helyébe az új }
         futo^.kov:= uj;               { láncolás }
       end;
     end;
     futo:= kezdo;                     { már csak ki kell írni }
     while futo^.kov <> nil do begin    { a lánc végéig }
       with futo^.adat do
         writeln(szla, ' ', hely, forg:8:0, ' ', date, ' ', time);
       futo:= futo^.kov;
     end;
end.


Szeberényi Imre
© BME Folyamatszabályozási Tanszék
Utolsó módosítás: 1999.11.24