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.
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.
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!
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]
Az algoritmus efféle kell legyen:
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; }
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!
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)
# | Input (miki.be) | # | Output (miki.ki/képernyő) |
---|---|---|---|
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 |
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)
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.
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):
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!
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.
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.
É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 |
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.