Vissza az előzőleg látogatott oldalra (nem elérhető funkció)Vissza a modul kezdőlapjáraUgrás a tananyag előző oldaláraUgrás a tananyag következő oldalára(34)Fogalom megjelenítés (nem elérhető funckió)Fogalmak listája (nem elérhető funkció)Oldal nyomtatása (nem elérhető funkció)Oldaltérkép megtekintéseSúgó megtekintése

Tanulási útmutató

Összefoglalás

Követelmény

Önállóan megoldható feladatok

Számonkérés

Ebben a leckében két feladat kitűzése, értékelési szempontjai és megoldása található. Közös jellemzőjük, hogy a megszerzett tudás mérése a céljuk. Mintázzák a kétféle számonkérést.

Általános tudnivalók

Az első feladatot az alapvető programozási ismeretek meglétének ellenőrzésére szánjuk. Nagyjából a 9. lecke tájékára időzítjük, és a megoldására 90 percet tervezünk. A feladat informális szövege mellett a megoldó megkapja a specifikációt. Algoritmust is kérhet, de ekkor a megoldása már kevesebbet ér, hiszen már „csak” a kódolással kell foglalkozni.

A második már egy nagyobb lélegzetű, több részproblémát tartalmazó feladat, a tananyag zárásául tervezzük. E feladat megoldására elegendőnek kell lennie 150 percnek. A csatolt anyagban tartozik egy-egy tesztelő rendszer, amely az elkészült megoldás helyességének mérésére szolgál. A helyességet kizárólag a futás alapján állapítja meg úgy, hogy néhány előre meghatározott bemeneti adat-együttesre lefuttatja a mérendő programot, és megvizsgálja a kapott eredményt. Az értékelendő programoknak a feladat szövegében leírt szerkezetű fájlból kell az adatokat beolvasni, és ugyancsak jól meghatározott szerkezetű fájlba kell írnia az eredményeket.

Vissza a tartalomjegyzékhez

Az első feladat

Feladat

Ismerjük a nem szökőévbeli ünnepnapjainkat, sorszámaikkal megadva (az 1 január elsejét jelenti), növekedő sorrendben. Tudjuk, hogy a mai nap hányadik napja az évnek. Határozzuk meg, hogy melyik ünnepnap esik a mai nap 8 napos sugarú környezetébe!

Specifikáció

Bemenet

N:Egész, Ünnepek:Tömb[1..N:Egész], MaiNap:Egész

Kimenet

VanE:Logikai, Hányadik,Melyik:Egész

Előfeltétel

N≥0 és MaiNap[1..365] és ∀i (1≤i≤N): Ünnepek[i][1..365] és

∀i (2≤i≤N): Ünnepek[i–1]<Ünnepek[i]

Utófeltétel

VanE=∃i (1≤i≤N): |Ünnepek[i]–MaiNap|≤8 és

VanE→1≤Hányadik≤N és |Ünnepek[Hányadik]–MaiNap|≤8 és

Melyik=Ünnepek[Hányadik]

Megjegyzés

Értékelés

Algoritmus

  • segítségként kérhető, de ekkor a jegy maximum 3-as (tört jegy esetén -1½ jegy levonás);
  • ha a megoldó algoritmust nem kér és nem is készít, akkor szintén a jegy maximum 3-as lehet (tört jegy esetén -1½ jegy levonás).

Kód

  • a beolvasás tartalmaz kérdést és helyesen be is olvas, de ellenőrzést nem végez, akkor a jegy maximum 4-es (tört jegy esetén -½ jegy levonás)
  • Az alábbi teszt-inputokkal próbálandó ki:
    • 0/()/1; 2/(2,22)/1; 3/(2,22,222)/23; 3/(2,22,222)/230; 3/(2,22,222)/123; 3/(2,22,222)/234;
    • -1/(?)/?; 1/(0)/?; 1/(1234)/?; 2/(3,2)/?; egy/(?)/?; 1/(egy)/?; 1/(1)/egy.
  • A fentiekhez az alábbi helyes (megjelenített) eredmény tartozik:
    • (Hamis); (Igaz,1,2); (Igaz,2,22); (Igaz,3,222); (Hamis); (Hamis);
    • Hibaüzenet; Hibaüzenet; Hibaüzenet; Hibaüzenet; Hibaüzenet; Hibaüzenet; Hibaüzenet.
  • Ha az algoritmus és a kód eltérnek egymástól, akkor a jegy maximum 3-as (tört jegy esetén -1½ jegy levonás).

Vissza a tartalomjegyzékhez

Az első feladat egy lehetséges megoldása

Az algoritmus efféle kell legyen:

Az "ünnepek" feladat lényegi részének a struktogramja.

Egy lehetséges C++ kód:

//név: Szabó Emerencia
//ETR-azonosító: SZEMAAT.ELTE
//drótposta-cím: 
#include <iostream>
#include <windows.h> //Code::Blocks 10.05-höz már kell a system kedvéért
#include <string>    //getline-hoz
using namespace std;
//programparaméterek -- globálisak:
//bemenetiek:
int N;
const int maxN=100;
int Unnepek[maxN];
int MaiNap;
//kimenetiek:
bool VanE;
int Hanyadik;
int Melyik;
//beolvassa a min..max közötti egész számot (max<min => max=végtelen)
void be_int(string kerdes, int &n, int min, int max, string uzenet);
//beolvassa a min..max közötti egész számokat tartalmazó tömböt
//(max<min => max=végtelen)
void be_int_tomb(string kerdes, int x[], int &n, int maxN,
                 int min, int max);
//ünnepkeresés:
void unnepKereses();
//eredménykiírás:
void eredmenyKiiras();
void billentyureVar();
//konvertálás: int -> string -- az igényes tömb-beolvasásért
string intToStr(int x);
int main()
{
    //a tömb beolvasása:
    be_int_tomb("Az unnepek",Unnepek,N,maxN,1,365);
    //a mai nap beolvasása:
    be_int("Mai nap",MaiNap,1,365,"Nem jo napsorszam!" );
    //a lényeg:
    unnepKereses();
    //az eredmény kiírása:
    eredmenyKiiras();
    billentyureVar();
    return 0;
}
//ünnepkeresés:
void unnepKereses()
{
    //keresés tétel:
    int i=0;
    while (i<N && abs(Unnepek[i]-MaiNap)>8)
    {
      i++;
    }
    VanE=i<N;
    if (VanE)
    {
      Hanyadik=i; Melyik=Unnepek[Hanyadik];
    }
}
//eredménykiírás:
void eredmenyKiiras()
{
    if (VanE)
    {
      cout << "A(z) " << Hanyadik+1 << ". unnep 8 napon beluli. "
           << "Ez az ev " << Melyik << ". napja." << endl;
    }
      else
    {
      cout << "Nincs 8 napon belul unnep." << endl;
    }
}
//beolvassa a min..max közötti egész számot (max<min => max=végtelen)
void be_int(string kerdes, int &n, int min, int max, string uzenet)
{
    bool hiba;
    string tmp;
    do
    {
      if (max>=min)
      {
        cout << kerdes << " (" << min << ".." << max << "):"; cin >> n;
        hiba=cin.fail() || n<min || n>max;
      }
        else
      {
        cout << kerdes << " (" << min << "..):"; cin >> n;
        hiba=cin.fail() || n<min;
      }
      if (hiba)
      {
        cout << uzenet << endl;
        cin.clear(); getline(cin,tmp,'\n');
      }
    }
    while(hiba);
}
//beolvassa a min..max közötti egész számokat tartalmazó tömböt
//(max<min => max=végtelen)
void be_int_tomb(string kerdes, int x[], int &n, int maxN,
                 int min, int max)
{
    //a "nyitó" kérdés:
    cout << kerdes << endl;
    //elemszám beolvasása:
    be_int("Elemszam",n,0,maxN,"Nem jo elemszam." );
    //a számok beolvasása:
    for (int i=0;i<n;++i)
    {
      string iS=intToStr(i+1)+". ";
      //az "extra" ellenőrzés miatti többlet ciklus:
      if (i>0)
      {
        bool novoE;
        do
        {
          be_int(iS,x[i],min,max,"Nem jo ertek." );
          novoE=x[i-1]<x[i];
          if (!novoE)
          {
            cout << "Nem novekvo!" << endl;
          }
        }
        while (!novoE);
      }
        else
      {
          be_int(iS,x[i],min,max,"Nem jo ertek." );
      }
    }
}
void billentyureVar()
{
    system("pause");
}
//konvertálás: int -> string
string intToStr(int x)
{
    string s="";
    bool neg=x<0;
    //előjel letagadása:
    if (neg)
    {
      x=-x;
    }
    while (x>0)
    {
      char c=char(x%10+48);//utolsó számjegy
      x=x/10;//utolsó számjegy nélkül
      s=c+s;
    }
    //x=0 esete:
    if (s.length()==0)
    {
      s="0";
    }
    //a negatív előjel hozzáragasztása:
    if (neg)
    {
      s="-"+s;
    }
    return s;
}

Vissza a tartalomjegyzékhez

A második feladat

Fontos

A feladat megoldásánál fontos, hogy projekt-, az exe-név, és a bemeneti, valamint a kimeneti adatfájlok „vezetékneve” miki legyen! A tesztkörnyezet ezt feltételezi, ha ezek valamelyik nem teljesül, nem értékel!

Feladat

A családok a Mikulásnak megrendeléseket küldtek, megadva a család nevét és a kért csomagok számát. Ezt tartalmazza a miki.be text fájl, amelynek első sorában a megrendelések száma, alatta soronként egy-egy megrendelés, ’darabszám + szóköz + név’ alakban. A miki.ki text fájlba kell kiírni az alábbi kérdésekre, feladatokra adott válaszokat, az alábbi sorrendben.

Biztonság kedvéért a részfeladatok eredményeit a képernyőre is írja ki! Kezdje egy, csak a részfeladat betűjelét (pl. „B”-t) tartalmazó sorral, alatta következzenek a részfeladat válaszai! Ugyanilyen szerkezetű lesz a fájlbeli output is. A képernyőre írás „többlet-tevékenységért” nem jár külön pont (csak az Ön munkáját segíti)!

a) Írja ki a fájlból beolvasott megrendeléseket: ’név + szóköz + darabszám’ alakban; egy sorban egy megrendelést (azaz helyesen 1+N sor tartozik ehhez a részfeladathoz, ha N megrendelés volt; N<100). (2+2)

b) Adja meg, hogy hány fordulóban tudja a Mikulás kiszállítani a csomagokat, ha egyszerre csak 20 darabot képes.

Kezdje a tétel nevével, ha nem tudja, akkor írja: „nem tudom”. Ez lesz a válasz első sora, a másodikba kerül a fordulók száma. (1+3)

c) Mekkora volt a legnagyobb megrendelés? Itt is a tétel neve a válasz első sora, majd követi a darabszám. (1+3)

d) Hány család rendelt legalább 5 csomagot? Sorolja is föl őket! A tétel neve után következzen a megfelelő családok száma és alatta a megrendelések ’név + szóköz + darabszám’ alakban! (1+3+4)

Minta

#

Input (miki.be)
Sortartalom
[magyarázat]

#

Output (miki.ki/képernyő)
Sortartalom
[magyarázat]

1.

5 [1≤megrendelések száma≤100]

1.

A

2.

3 Szlávi [az első család megrendelése]

2.

Szlávi 3 [az első család megrendelése]

3.

3 Nagy [a 2. család megrendelése]

3.

Nagy 3 [a 2. család megrendelése]

4.

10 Betyár [a 3. család megrendelése]

4.

Betyár 10 [a 3. család megrendelése]

5.

5 Papp [a 4. család megrendelése]

5.

Papp 5 [a 4. család megrendelése]

6.

3 Balogh [az 5. család megrendelése]

6.

Balogh 3 [az 5. család megrendelése]

.

.

7.

B

.

.

8.

[az alkalmazandó tétel neve]

.

.

9.

2

.

.

10.

C

.

.

11.

[az alkalmazandó tétel neve]

.

.

12.

10

.

.

13.

D

.

.

14.

[az alkalmazandó tétel neve]

.

.

15

2

.

.

16

Betyár 10

.

.

17

Papp 5

Megjegyzés

A [magyarázat] nem része a fájlnak!

A megoldás (ez esetben) 17 sorból áll. (A maximális szám: 2*megrendelésszám+10)

Fontos

A program végleges változatában ne maradjon billentyűre várakozás (a tesztrendszer nem képes billentyűket nyomogatni )!

12 többletpont jár, ha használ függvényeket.

Megjegyzés

Az alábbi programozási tételnevek fordulhatnak elő (ékezetes betűk kicserélhetők az ékezetmentes párjukkal, kis- és nagybetűk nem különbözőek):

  • Sorozatszámítás
  • Eldöntés
  • Kiválasztás
  • Keresés
  • Maximumkiválasztás
  • Megszámolás
  • Kiválogatás

Csak a feladat érdemi megoldását célzó programokat értékelünk, a tesztelő rendszer próbára tételét célzó megoldások 0 pontosak, a belefektetett munka ellenére!

Tesztelés

A letöltött fájlból ki kell csomagolni a tesztkörnyezetet. Helye: a S:\TESZT könyvtár. Fontos, hogy a tesztelendő fájlt tartalmazó könyvtár is ugyanezen a drive-on foglaljon helyet. (A S drive helyett a pendrive drive-ja is megfelelő választás.)

A saját könyvtárba állva el kell indítani az S:\TESZT\T parancsfájlt, ami leteszteli az ea.exe nevű programját 6 tesztfájllal, s az eredményeket az EREDMENY.TXT fájlba írja.

Fontos

Ismételt teszteléskor csak arra a tesztesetre futtatja újra, amit addig még nem próbált. Ha az x. tesztre újra szeretné próbálni, akkor a MIKI.STx fájlt le kell törölnie!

Ha a programnak bármi futási üzenete van – ilyen pl. a feladat konzol outputjai, vagy egy futási hibakód is – akkor azt a miki.sox fájlba írja. A saját program tesztkimenetei a miki.kix fájlokba kerülnek, a bemenetek a miki.bex fájlokban láthatók.

Megjegyzés

Értékelés

Az értékelés futás közben 6 teszt-adatfájl alapján történik. A függvények alkalmazásáért járó féljegy pontértéke: 12 pont.

Összpontszám: 6*(4+4+4+8) +12= 6*20+12= 120+12= 132 pont

Alsópont:

6*8=48

6*11=66

6*14=84

6*17=102

Jegy:

2

3

4

5

Vissza a tartalomjegyzékhez

A második feladat egy lehetséges megoldása

Az alábbiakban egy lehetséges megoldás C++ kódját mellékeljük:

//név: Szabó Emerencia
//ETR-azonosító: SZEMAAT.ELTE
//drótposta-cím: 
#include <iostream>
#include <fstream>
#include <windows.h> //Code::Blocks 10.05-höz már kell a system kedvéért
#include <string>    //getline-hoz
using namespace std;
//Bemenet:
struct TMegrendeles{string nev; int db;};//a megrendelés
const string befN="miki.be";//bemeneti fájl neve
const int maxN=100;
const int maxCs=20;//egyszerre szállítható csomagok száma
const int sokCs=5; //sok csomag elsóhatára
int N;
TMegrendeles megrend[maxN];
ifstream iF;
//Kimenet:
const string kifN="miki.ki";//kimeneti fájl neve
ofstream oF;
//a nyitott _iF fájlból beolvassa a _mr[_n] tömböt
void beolvasas(ifstream &_iF, int _n, TMegrendeles _mr[]);
//lényegi eljárások:
//az eljárások kiírják a kívánt eredményt a képernyőre is és a fájlba is
void A_elj(ofstream &_oF, int _n, const TMegrendeles _mr[]);
void B_elj(ofstream &_oF, int _n, const TMegrendeles _mr[]);
void C_elj(ofstream &_oF, int _n, const TMegrendeles _mr[]);
void D_elj(ofstream &_oF, int _n, const TMegrendeles _mr[]);
using namespace std;
int main()
{
    setlocale(LC_ALL, "hun");//"magyaros" betűk kedvéért
    iF.open(befN.c_str());
    if (!iF.is_open())
    {
      return 1;//nem létező fájl
    }
    iF >> N;
    string tmp; getline(iF,tmp,'\n');//az 1. sor maradékát eldobjuk
    if (N>maxN || N<1)
    {
      return 2;//túl sok vagy túl kevés adat
    }
    beolvasas(iF,N,megrend);//beolvasás
    iF.close();
    //feldolgozás:
    oF.open(kifN.c_str());
    //a lényeg:
    A_elj(oF,N,megrend);
    B_elj(oF,N,megrend);
    C_elj(oF,N,megrend);
    D_elj(oF,N,megrend);
    oF.close();
    return 0;
}
//A) feladat (beolvasas):
void A_elj(ofstream &_oF, int _n, const TMegrendeles _mr[])
{
  _oF << 'A' << endl;
  cout<< 'A' << endl;
  for (int i=0;i<_n; ++i)
  {
    _oF << _mr[1].nev << ' ' << _mr[i].db << endl;
    cout << _mr[i].nev << ' ' << _mr[i].db << endl;
  }
}
//B) feladat:
void B_elj(ofstream &_oF, int _n, const TMegrendeles _mr[])
{
  _oF << "B\nSorozatszámítás\n";
  cout<< "B\nSorozatszamitas\n";
  int db=0;
  for (int i=0;i<_n; ++i)
  {
    db+=_mr[i].db;
  }
  int ford;
  if (db%maxCs==0)
  {
    ford=db/maxCs;
  }
    else
  {
    ford=db/maxCs+1;
  }
  _oF << ford << '\n';
  cout<< ford << '\n';
}
void C_elj(ofstream &_oF, int _n, const TMegrendeles _mr[])
{
  _oF << "C\nMaximumkivalasztas\n";
  cout<< "C\nMaximumkivalasztas\n";
  int max=_mr[0].db;
  for (int i=1;i<_n; i++)
  {
    if (_mr[i].db>max)
    {
      max=_mr[i].db;
    }
  }
  _oF << max << endl;
  cout<< max << endl;
}
void D_elj(ofstream &_oF, int _n, const TMegrendeles _mr[])
{
  _oF << "D\nKivalogatas\n";
  cout<< "D\nKivalogatas\n";
  TMegrendeles nagyCs[maxN];
  int db=0;
  for (int i=0; i<_n; i++)
  {
    if (_mr[i].db>=sokCs)
    {
      nagyCs[db++]=_mr[i];
    }
  }
  _oF << db << endl;
  cout<< db << endl;
  for (int i=0; i<db; i++)
  {
    _oF << nagyCs[i].nev << ' ' << nagyCs[i].db << endl;
    cout<< nagyCs[i].nev << ' ' << nagyCs[i].db << endl;
  }
}
//a nyitott _iF fájlból beolvassa a _mr[_n] tömböt
void beolvasas(ifstream &_iF, int _n, TMegrendeles _mr[])
/*
  elvárások: NYITOTT(_iF), _n sorban, soronként egy egész szám és egy szöveg van
*/
{
  for (int i=0; i<_n; ++i)
  {
    _iF >> _mr[i].db >> _mr[i].nev;
    string tmp; getline(_iF,tmp,'\n');//a sor maradékát eldobjuk
  }
  return;
}

Töltse le az alábbi prezentációt, amely ugyan az 1. zárthelyihez készült, ennek ellenére mindkét feladat megoldásához kiegészítő ismereteket, jól használható szempontokat ad.

Az animáció bemutatja, hogy mire is kell figyelni a ZH írásnál.

Az animáció bemutatja, hogy mire kell figyelni a ZH írásánál.

Flash lejátszó letöltése

ZH írás módszertana

Vissza a tartalomjegyzékhez

Fel a lap tetejére
Új Széchenyi terv
A projekt az Európai Unió támogatásával, az Európai Szociális Alap társfinanszirozásával valósul meg.