NZH 2015
2015.10.30
A 2015-ös nagy ZH feladatok és megoldásaik. Ez az oldal rendszeresen frissülni fog!
11. NZH
1. feladat: Ötöslottó
BEUGRÓ: Írj főprogramot, amelyik létrehoz egy tömböt öt lottószám számára, és
a lotto()
nevű függvényt meghívja rá! A függvény dolga lesz feltölteni a tömböt.
Írd ki ezután a számokat a képernyőre!
Írd meg a lotto()
függvényt, amelyik az ötöslottó sorsolását szimulál, vagyis
a paraméterként kapott tömbbe tesz öt, egymástól különböző, 1 és 90 közötti,
véletlenszerűen választott egész számot!
Megoldás
#include <stdio.h> #include <stdlib.h> #include <time.h> void lotto(int *szamok) { int i, j; for (i = 0; i < 5; ++i) { int sorsol = 1; while (sorsol) { szamok[i] = rand()%90 + 1; sorsol = 0; for (j = 0; j < i; j++) if (szamok[j] == szamok[i]) sorsol = 1; } } } int main(void) { srand(time(NULL)); int szamok[5]; int j; lotto(szamok); for (j = 0; j < 5; j++) printf("%d ", szamok[j]); return 0; }
2. feladat: Virágnyelv
BEUGRÓ: Írj függvényt, amelyik igazat ad, ha kisbetűs magánhangzót kapott (a, e, i, o, u)! Használd ezt a következő programodban!
Írj kétparaméterű függvényt, amely a második paraméterként kapott, angol ábécé kisbetűiből álló szöveg „virágnyelvű” változatát állítja elő az első paramétereként kapott helyen! Ez azt jelenti, hogy a magánhangzókat megkétszerezi, és közéjük egy 'v' betűt rak, pl. „viragnyelv” → „viviravagnyevelv”.
Felteheted, hogy az első sztring elég nagy ahhoz, hogy elférjen benne az új szöveg. Írj főprogramot, melyből meghívod a virágnyelv függvényt, és kiírsz egy feldolgozott szöveget!
Megoldás
#include <stdio.h> int maganhangzo(char c) { return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'; /* return strchr("aeiou", c) != NULL :) */ } void virag(char *cel, char *forras) { int icel, iforr; icel = iforr = 0; while (forras[iforr] != '\0') { cel[icel++] = forras[iforr]; if (maganhangzo(forras[iforr])) { cel[icel++] = 'v'; cel[icel++] = forras[iforr]; } iforr++; } cel[icel] = '\0'; } int main(void) { char eredmeny[50]; virag(eredmeny, "viragnyelven"); printf("%s\n", eredmeny); return 0; }
3. feladat: Szálloda
Egy hétemeletes szállodában a szobafoglalásokat tömbben tárolják. A szobák a szokásos módon vannak számozva, a százasok adják meg az emeletet, a többi pedig a szoba sorszámát (pl. 712 = 7. emelet, 12. szoba). A földszint a 0. szint, utána 1-től 7-ig az emeletek. Ennél a feladatnál nem kell teljes programot írni, csak a megadott részeket.
BEUGRÓ: Definiálj Vendeg
nevű típust, amelyik egy szállóvendég adatait (név: max. 50 karakter, szobaszám: egész)
tartalmazza! Írj függvényt, amely átvesz egy vendéget, és visszaadja, hogy melyik emeleten lakik!
Írj függvényt, amely átvesz egy Vendeg
elemekből álló tömböt és egy nevet! Keresse ez
meg a névhez tartozó foglalást és adja vissza a megtalált tömbelem címét vagy
NULL-t, ha nincs találat!
Írj függvényt, amely paraméterként kapja a vendégek tömbjét és egy másik, inicializálatlan tömböt, amelyet a szint sorszámával indexelünk! Írja be az utóbbi tömbbe, hogy az egyes emeleteken hány vendég lakik!
Írj függvényt, amely megkapja a vendégek tömbjét, az előző függvénnyel előállítja a betöltöttségek tömbjét, és végül visszatér a legzsúfoltabb emelet sorszámával – tehát azzal, ahol a legtöbb vendég van éppen!
Megoldás
typedef struct Vendeg { char nev[50+1]; int szobaszam; } Vendeg; int emelet(Vendeg v) { return v.szobaszam / 100; } Vendeg *keres(Vendeg *vendegek, int meret, char *nev) { int i; for (i = 0; i < meret; ++i) if (strcmp(vendegek[i].nev, nev) == 0) return &vendegek[i]; return NULL; } void betoltottseg(Vendeg *vendegek, int meret, int *szintek) { int i; for (i = 0; i <= 7; ++i) szintek[i] = 0; for (i = 0; i < meret; ++i) szintek[emelet(vendegek[i])] += 1; } int legtobb_vendeg(Vendeg *vendegek, int meret) { int szintek[8]; betoltottseg(vendegek, meret, szintek); int i, maxi = 0; for (i = 1; i < 8; ++i) if (szintek[i] > szintek[maxi]) maxi = i; return maxi; }
4. feladat: Rendezés
BEUGRÓ: Írj függvényt, amely képes megcserélni két paraméterként kapott, valós típusú változó tartalmát!
Írj függvényt, amely paraméterként egy valósakat tartalmazó tömböt vesz át, továbbá két indexet, amelyek egy tartomány elejét és végét határozzák meg! Térjen vissza a függvény a megadott tartományból a legkisebb elem indexével!
Írj függvényt, amely paraméterként egy valós tömböt vesz át, és az előbbi két függvényt is felhasználva növekvő sorba rendezi a tömb számait!
Egészítsd ki ezeket egy főprogrammal, amely létrehoz egy 5 elemű tömböt, rendezi azt, majd kiírja a tömbelemeket sorszámozva!
Megoldás
#include <stdio.h> void csere(double *x, double *y) { double temp = *x; *x = *y; *y = temp; } int minindex(double *tomb, int mettol, int meddig) { int min = mettol, i; for (i = mettol+1; i <= meddig; ++i) if (tomb[i] < tomb[min]) min = i; return min; } void rendez(double *tomb, int meret) { int i; for (i = 0; i < meret-1; ++i) { int min = minindex(tomb, i, meret-1); if (min != i) csere(&tomb[i], &tomb[min]); } /* for (i = 0; i < meret-1; ++i) csere(&tomb[i], &tomb[minindex(tomb, i, meret-1)]); */ } int main(void) { double tomb[5] = {1.2, 3.5, 9.5, 3.4, 4.5}; rendez(tomb, 5); int i; for (i = 0; i < 5; ++i) printf("%d. %g\n", i, tomb[i]); return 0; }
22. NZH
1. feladat: Mátrix
Egy mátrix típust kell definiálnod. A
mátrix szélessége m.szeles
, magassága m.magas
,
a benne lévő valós számokat pedig m.adat[0][0]
formában kell tudni
elérni, előbb sort, aztán oszlopot indexelve 0-tól. Írd meg az alábbi programrészeket!
- BEUGRÓ: Definiáld a mátrix típust, amely dinamikus tömböt használ!
- Írj függvényt, amely egy paraméterként kapott, már létrehozott mátrix összes elemét kinullázza!
- Írj függvényt, amely paraméterként egy fájlnevet kap, amelyből beolvas egy mátrixot! Az inicializálást, azaz a memóriafoglalást is ennek a függvénynek kell elvégeznie. A fájlban szereplő első két érték a szélesség és a magasság, utána pedig valós a számok sorfolytonosan.
Megoldás
typedef struct Matrix { int szeles, magas; double **adat; } Matrix; void nullaz(Matrix *m) { int x, y; for (y = 0; y < m->magas; ++y) for (x = 0; x < m->szeles; ++x) m->adat[y][x] = 0; } void beolvas(Matrix *m, char const *fajlnev) { int szeles, magas, x, y; FILE *fp; fp = fopen(fajlnev, "rt"); fscanf(fp, "%d %d", &szeles, &magas); m->szeles = szeles; m->magas = magas; m->adat = (double**) malloc(sizeof(double*) * magas); for (y = 0; y < magas; ++y) m->adat[y] = (double*) malloc(sizeof(double) * szeles); for (y = 0; y < magas; ++y) for (x = 0; x < szeles; ++x) fscanf(fp, "%lf", &m->adat[y][x]); fclose(fp); }
2. feladat: C++ kommentek
A feladat a szabványos bemenetről érkező szövegben (fájl vége jelig) megszámolni, hogy hány C++ komment van benne, és a darabszámot kiírni. A C++ komment két / (per) jellel kezdődik, és a sor végéig tart, pl.:
printf("Hello"); // Üdvözlet
Ha kommenten belül van // karakterpár, az már nem növeli a kommentek számát. Feltételezheted, hogy sztringen belül nem lesz //. Készíts állapotgépes modellt, majd valósítsd meg teljes C program formájában! BEUGRÓ: Legyen állapottábla vagy -átmeneti gráf és a program legyen állapotgépes!
Megoldás
#include <stdio.h> int main(void) { int c, szaml = 0; enum Allapot { kod, pervolt, komment } all = kod; all = kod; while ((c = getchar()) != EOF) { switch (all) { case kod: if (c == '/') all = pervolt; break; case pervolt: if (c == '/') { szaml++; all = komment; } else { all = kod; } break; case komment: if (c == '\n') all = kod; break; } } printf("%d darab komment", szaml); return 0; }
3. feladat: Doge

Egy kutyatenyésztő számára kell programot írnod, amely a kutyákat tartja nyilván. Egy kutyáról a következő adatokat kell megjegyezni egy egyszeresen láncolt, strázsa nélküli listában: 1) id = azonosító, egész szám; 2) név, max. 20 betű; 3) papa és 4) mama, pointerek másik listaelemekre, a kutya szüleire, vagy null pointerek, ha ismeretlenek. Írd meg az alábbi programrészeket!
- BEUGRÓ: Definiáld a
Doge
nevű típust, amely a lista egy eleme! - BEUGRÓ: Írj függvényt, amelyik végigmegy a paraméterként kapott láncolt listán, és kiírja az összes kutya azonosítóját és nevét!
- Írj függvényt, amelyik felszabadítja a listát!
- Írj függvényt, amely egy a paraméterként kapott listában megkeresi a szintén paraméterként kapott azonosítójú kutyát! A visszatérési érték a megtalált elem, vagy null pointer.
- Írj függvényt, amely a paraméterként kapott nevű szöveges fájlba kiírja a kutyák adatait, soronként id, név, papa id, mama id formában, szóközökkel elválasztva. Ha ismeretlenek a szülők, az azonosítók helyére -1 kell kerüljön.
- Írj függvényt, amely egy megadott azonosítójú kutyát töröl a listából! Figyelj arra, hogy ilyenkor át kell vizsgálni a listát: ha a törölt listaelemet valamelyik másik elem szülőként (papa, mama) hivatkozza, akkor azoknál null pointert kell betenni.
Írj kódrészletet, amelyben definiálsz egy listát, és feltételezve, hogy tartalmaz adatokat, bemutatod a függvények használatát!
Megoldás
typedef struct Doge { int id; char nev[20+1]; struct Doge *papa, *mama; struct Doge *kov; } Doge; void kiir(Doge *eleje) { Doge *iter; for (iter = eleje; iter != NULL; iter = iter->kov) printf("%d %s\n", iter->id, iter->nev); } Doge *keres(Doge *eleje, int id) { Doge *iter; for (iter = eleje; iter != NULL; iter = iter->kov) if (iter->id == id) return iter; return NULL; } void felszabad(Doge *eleje) { while (eleje != NULL) { Doge *torlendo = eleje; eleje = eleje->kov; free(torlendo); } } void fajlba(Doge *eleje, char const *fajlnev) { FILE *fp = fopen(fajlnev, "wt"); Doge *iter; for (iter = eleje; iter != NULL; iter = iter->kov) { fprintf(fp, "%d %s %d %d\n", iter->id, iter->nev, iter->papa ? iter->papa->id : -1, iter->mama ? iter->mama->id : -1); } fclose(fp); } void torol(Doge **peleje, int id) { Doge *iter, *lemarado, *torlendo; lemarado = NULL; iter = *peleje; while (iter != NULL && iter->id != id) { lemarado = iter; iter = iter->kov; } torlendo = iter; /* nincs mit törölni? */ if (torlendo == NULL) return; /* ha van mit törölni, akkor a többinél nullra kell állítani, ha szülő */ for (iter = *peleje; iter != NULL; iter = iter->kov) { if (iter->papa == torlendo) iter->papa = NULL; if (iter->mama == torlendo) iter->mama = NULL; } /* és aztán törölni */ if (torlendo == *peleje) { *peleje = torlendo->kov; } else { lemarado->kov = torlendo->kov; } free(torlendo); } Doge *lista = NULL; kiir(lista); Doge *talalat = keres(lista, 3); fajlba(lista, "kutyak.txt"); torol(&lista, 3); felszabad(lista);