Zárthelyi feladatok és megoldások

Programtervezés c. tárgyból


Programozás zárthelyi I.VI.                         1999.11.23/D 

Minden lap tetejére írja fel balra a feladat számát, jobbra a nevét és tankörét! Egy lapra csak egy feladat megoldását írja! 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 állományokat csak egyszer olvashatja be, és nem használhat munkaállományt. 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õ meg. Törekedjen a tiszta, strukturált megoldásokra! Szükség esetén alkalmazzon alprogramokat! Nem kell törekedni a trükkös megoldásokra, de a durva, ügyetlen módszereket kerülje!

Megszerezetõ pontszám: 60p. Minimális pontszám az elégségeshez: 29p

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;
        hossz_t = 1..11;
        poi = ^lanc;
        lanc = record
          txt: packed array [hossz_t] of char;
          kov: poi
        end;
var     kezdo, p: poi;
        banya: banya_t; torpe: torpe_t;
        i: integer;
begin
        new(kezdo); kezdo^.txt:= 'A banyaban ';
        new(p); p^.txt:= ' torpe van '; p^.kov:= nil;
        kezdo^.kov:= p; p:= kezdo;
        i:= 0; banya:= [hapci, tudor, hapci, kuka, hapci, szundi] - [hapci, tudor];
        for torpe:= kuka downto hapci do
          if torpe in banya then
            i:= i + 1;
        while p <> nil do begin
          write(p^.txt);
          if p^.kov <> nil then write(i);
          p:= p^.kov;
        end;
end.



2. feladat                                                  10p
Írjon PASCAL programot, amely kiírja, hogy a standard inputon file végéig érkezõ szövegben hány olyan szó van, amelynek az utolsó elõtti betûje magánhangzó. Szónak tekintünk minden betûvel kezdõdõ alfanumerikus karaktarsoroszatot. Feltételezheti, hogy a szövegben csak az angol ábécé magánhangzói fordulnak elõ.

3. feladat                                                  10p
Írjon PASCAL függvényt, amely a paraméterként kapott maximum 20 jegyû 8-as számrendszerû számot átalakítja valós értékké! A függvény paraméterként kapja a számjegyeket tartalmazó karakter tömböt (S), és a számjegyek tényleges számát (N). Amennyiben a szám rövidebb, mint 20 karakter, úgy a tömb az 1. indextõl az N. indexig tartalmazza a számjegyeket. (A legmagasabb helyi érték mindig az 1. helyen van.)
TYPE SZAM_T = ARRAY [1..20] OF CHAR;
FUNCTION POLINOM(A: SZAM_T; N: INTEGER): REAL;


4. feladat                                                  10p
Egy levelezõ rendszer az e-mail címeket egy szöveges állományban tárolja. Ebben minden sor pontosan 2 információs mezõt tartalmaz, és egyik sor sem hosszabb, mint 80. karakter.  Az egyes mezõk sorrendben a következõk:

CÍM:   szóközzel határolt mezõ
Név:   idézõjelek közé tett mezõ

Pl:
bazsi@barat.bme.hu "Sándor Balázs István"
endre@zsozso.elte.hu "Palotás Endre"
fur@gepard.elte.hu "Für Kovács Csaba"
z.babik@girls.penthouse.com "Babik Zoltán"
andri@leopard.bme.hu "Andricsek Nenád"

Készítsen PASCAL programot, amely a fenti formátumú állományt a standard inputról beolvasva, kiírja a standard outputra azoknak a nevét, és e-mail cimét akiknek az elte.hu domain-ban van az e-mail címe!
A fenti példa szerint a következõ eredményt kapjuk:

"Palotás Endre" endre@zsozso.elte.hu
"Für Kovács Csaba" fur@gepart.elte.hu



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:               26 karakter
eladóhely azonosítója:    20 karakter
fizetett összeg:          valós szám
dátum:                    11 karakter, (pl: 1999.09.25.)
idõ:                      8 karakter, (pl: 11:53:23)

Az egyes tranzakciók (eladások) adatai a file-ban rendezetlenül követik egymást. Az OTP szeretné megjutalmazni azokat az ügyfeleket, akik 1999. szeptemberében legalább 6-szor vásároltak kártyával. Írjon Pascal programot, amely a POS.DAT file alapján, a számlaszámok csökkenõ sorrendje szerint kiírja ezen ügyfelek számlaszámát, és a szeptember hónapi vásárlásaik számát. Feltételezheti, hogy a feladat megoldásához elegendõ memória áll rendelkezésére.
 
 


Megoldások I.VI.                          1999.11.23/D 

1. feladat
A program létrehoz egy láncot, amley két elembõl áll. Ezek txt mezõibe a 'A banyaban ' és a ' torpe van ' szöveget írja. Ezt követõen a banya halmaz típusú változó két konstans halmaz különbségét kapja értékül, vagyis a [kuka, szundi] értéket. A for ciklusban a törpe változó a kuka és a kapci közötti értékeket feszi fel. A ciklusmag mindannyiszor növeli az i változót, ahányszor ezen értékek közül valamelyik eleme a banya halmaznak. Igy a ciklus végén i értéke 2 lesz.
Végül a while ciklus a fenti láncon végighaladva kírja a lánc elemeinek txt mezõjét. Az elsõ elem kírása után azonban kiírja az i változó értékét is. A program a következô eredményt adja:

A banyaban 2 torpe van



2. feladat
Megoldási elv: egy alprogram segítségével felismerjük a szöveg szavait. Ezeknek csupán utolsó elõtti betûit kell tátolni és vizsgálni. A vizsgálat eredményétõl függõen számlálni kell.
Algoritmus vázlat:
sz:= 0;
while not eof do
  if szoolvas(llch) >= 2 then
    if llch in maganhangzo then sz:= sz + 1;
writeln(sz);
(Az alporgramok specifikációit a megjegyzések tartalmazák.)

program feladat_2;
const BETUK  = ['A'..'Z', 'a'..'z'];   { betûk halmaza }
const SZAMOK = ['0'..'9'];             { számjegyek halmaza }
const MGH    = ['A','E','I','O','U','a','e','i','o','u']; { magánhangzók halmaza }
var ll_ch: char;                       { utolsó elõtti karakter }
    sz: integer;                       { számláló }

{ szoolvas specifikáció:
  Beolvas egy szót a standard bemenetrõl. Visszaadja az urtolsó elõtti karaktert és a szó
  hosszát.
  Bemenet: standard input
  Kimenet: lch változóban az utolso elõtti karakter.
           vissztérési érték: a szó hossza
}
function szoolvas(var lch: char): integer;
var l: integer;          { hossz }
    ch, ch1: char;
begin
    l:= 0; ch:= ' ';
    while not eof and not (ch in BETUK) do
      read(ch);          { kovetkezõ karakter }
    while not eof and ch (in BETUK+SZAMOK) do begin
      lch:= ch1; ch1:= ch;{ tároljuk az utolsó elõttit }
      l:= l + 1;         { nõ a hossza }
      read(ch);          { következõ karakter }
    end;
    szoolvas:= l;
end;

begin
    sz:= 0;                             { inicializál }
    while not eof do
      if szoolvas(ll_ch) >= 2 then       { ha legalább 2 karakter }
        if ll_ch in MGH then sz:= sz+1;  { számolunk, ha kell }
    writeln(sz, ' darab ilyen szo volt.');
end.



3. feladat{ 3. feladat }
Felhasználjuk a polinom szozattá alakítási szabályát (Horner). Az átalakítás:

function polinom(a: szam_t, n: integer): real;
var i: integer;
    r: real;
begin
    r:= 0;                              { eddigi összeg }
    for i:= 1 to n do
      r:= r * 8 + ord(a[i]) - ord('0');  { új összeg }
    polinom:= r;
end;



4. feladat { feladat 4 }
A megoldáshoz célszerû egy olyan beolvasó eljárást készíteni, ami szóközig, vagy sorvégéig olvas. Ezzel a sor két információs mezõje egyszerûen beolvasható. Ezután a feldolgozás a cím elemzésébõl áll.

program feladat_4;
type str_t = record     { saját string tipus }
       txt: array [1..80] of char;
       len: integer      { tényleges hossz }
     end;
     domain_t = array [1..7] of char;
var cim, nev: str_t;    { cím és név }

{ beolvas:
  Boelovas szóközig, vagy sorvégéig
  Bemenet: standard input
           string tipus
  Kimenet: beolvasott string, es a hossza
}
procedure beolvas(var s: str_t);
var l: integer;         { hossz }
    ch: char;
begin
    l:= 0; ch:= 'A';
    while not eof and not eoln and (ch <> ' ') do begin
      read(ch);         { kovetkezõ karakter }
      l:= l + 1;        { nõ a hossza }
      s.txt[l]:= ch;
    end;
    if (ch = ' ') l:= l -1; { ha space miatt állt le }
    s.len:= l;          { hossz beirása }
end;

{ vizsgal:
  Megállapítja a cim a domain-ban van-e
  Bemenet: cim,
           domain
  Kimenet: true, ha jó cím (függvény érték)
}
function vizsgal(cim: str_t; domain: domain_t): boolean;
var i, j: integer;
    ok: boolean;
begin
    if cim.len > 7 then begin
      i:= cim.len-7;
      ok:= (cim.txt[i] = '.') or (cim.txt[i] = '@'); { . vagy @ határolja }
      for j:= 1 to 7 do begin
        i:= i + 1;
        ok:= ok and (domain[j] = cim.txt[i]);      { összehasonlítjuk }
      end;
      vizsgal:= ok;
    end else
      vizsgal:= false;
end;

{ kiir:
  Kiirja a paraméterként kapott stringet
  Bemenet: string
  Kimenet: standard output
}
procedure kiir(s: str_t);
var i: integer;
begin
      for i:= 1 to s.len do
        write(s.txt[i]);
end;

begin
    while not eof do begin
      beolvas(cim); beolvas(nev); readln;
      if vizsgal(cim, 'elte.hu') then begin
        kiir(nev); write(' ');
        kiir(cim); writeln;
      end;
    end;
end.



5. feladat
A feladatot egy egyszerû, számlaszám szerint rendezett lánccal oldjuk meg. Minden elemben tároljuk a szeptemberi vásárlások számát 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 ->  ... számlaszám

program feladat_5;
type szsz_t = packed array [1..26] of char; { számlaszám típus }
     hely_t = packed array [1..20] of char; { eladóhely típus }
     date_t = packed array [1..11] of char; { dátum típus }
     ido_t  = packed array [1..8]  of char; { idõ típus }
     lanc_poi = ^lanc;
     lanc = record              { lánc elem a hívó összsített adataihoz }
       szsz: szsz_t;            { számlaszám }
       sz:  integer;            { vásárlások száma }
       kov:  lanc_poi           { következõ elem mutatója }
     end;

     inp = record               { beolvasás rekordja }
       szsz: szsz_t;            { számlaszám }
       hely: hely_t;            { eladóhely díja }
       ossz: real;              { összeg }
       date: date_t;            { dátum }
       ido:  ido_t              { idõ }
     end;

var kezdo:  lanc_poi;           { kezdõ pointer }
    be:     file of inp;         { file változó }
    adat:   inp;                { rekord a beolvasához }

{ lancol:
  Számlaszám szerint csökkenõ sorrendben épít egy láncot. A lánc végén van a strázsa.
  A vásárlási számot növeli.
  Bemenet: pointer a láncra,
           beolvasott adatok
  Kimenet: epül a lánc
}
procedure lancol(p: lanc_poi; r: inp);
var i: integer;
    uj: lanc_poi;
begin
    while (p^.kov <> nil) and (p^.szsz > r.szsz) do p:= p^.kov; { keres }
    if (p^.kov = nil) or (p^.szsz <> r.szsz) then begin
      new(uj);                       { új elemet veszünk fel }
      uj^:= p^;
      p^.kov:= uj;
      p^.sz:= 0;                     { nullázzzuk számlálót }
      p^.szsz:= r.szsz;              { beírjuk a számlaszámot }
    end;
    p^.sz:= p^.sz + 1;               { növeljük a vásárlások számát }
end;

{ kiir:
  Kiírja a felépített láncot.
}
procedure kiir(p: lanc_poi);
var sum: real;
begin
    while (p^.kov <> nil) do begin      { amíg a strázsát el nem érjuk }
      if p^.sz >= 6 then               { legalább 6 szor vásárolt }
      write(p^.szsz:30, p^.sz:3);       { számlaszám, vásárlások száma  }
      p:= p^.kov;                      { kövekezõ elemre }
    end;
end;

begin
  new(kezdo); kezdo^.kov:= nil;        { strázsa }
  assign(be, 'POS.DAT');               { file }
  reset(be);
  while not eof(be) do begin           { a file végéig }
    read(be, adat);                    { beolvasunk }
    adat.date[9]:= '0';                { átírjuk a napot, hogy egyszerûbb }
    adat.date[10]:= '0';               { legyen az összehasonlítás }
    if adat.date = '1999.09.00.' then
      lancol(kezdo, adat);
  end;
  kiir(kezdo);                         { kiír }
end.


Szeberényi Imre
© BME Irányítástechnika és Informatika Tanszék
Utolsó módosítás: 1999.12.11.