Minta második ZH
Czirkos Zoltán · 2022.05.25.
Minta második ZH, előző évek feladataiból összeollózva.
Minta második nagy ZH, néhány előző évekből származó feladatból összeállítva. Tudnivalók a feladatsor felhasználásával kapcsolatban: lásd itt.
Ha a nulladik ZH miatt vagy itt: lásd a követelmények oldalát. A feladatsor tematikája az egész félév anyagát felöleli – lényegében megegyezik a második, félév végén írt zárthelyivel.
Gondolatjelek
Írj állapotgépes programot, amely a szabványos bemeneten érkező szövegből kitörli a gondolatjelek közötti részeket – olyanokat, mint ez –, és úgy írja ki a szabványos kimenetére! A gondolatjelet az különbözteti meg a kötőjeltől, hogy előtte egy szóköz van.
Rajzold meg az ehhez tartozó állapot- és tevékenységtáblát, és abból kiindulva írd meg a programot! BEUGRÓ: a programnak állapotgépesnek kell lennie.
Megoldás (de előtte próbáld meg te magad!)
szóköz | mínusz | többi | |
---|---|---|---|
szöveg | →lehet | ki: c | ki: c |
lehet | ki: c | →gondolat | ki: szóköz, c, →szöveg |
gondolat | →vége? | – | – |
vége? | – | →szöveg | →gondolat |
#include <stdio.h>
int main() {
typedef enum GondolatAll { szoveg, lehet, gondolat, vege } GondolatAll;
int c;
GondolatAll allapot = szoveg;
while ((c = getchar()) != EOF) {
switch (allapot) {
case szoveg:
if (c == ' ') allapot = lehet;
else putchar(c);
break;
case lehet:
if (c == ' ') putchar(' ');
else if (c == '-') allapot = gondolat;
else { putchar(' '); putchar(c); allapot = szoveg; }
break;
case gondolat:
if (c == ' ') allapot = vege;
break;
case vege:
if (c == ' ') /* semmi */;
else if (c == '-') allapot = szoveg;
else allapot = gondolat;
break;
}
}
return 0;
}
Pontozás:
- Bemenet sztringbe beolvasva, vagy iterációnként több karakter beolvasása: nincs meg a beugró, nem állapotgépes a megoldás.
- Állapotgép: helyes állapotátmenetek 3p, helyes tevékenységek 1p.
- Program: felsorolt típus 1p, beolvasás 1p, állapotgép kódolása 4p.
Továbbá az általános pontozási irányelvek.
Leghosszabb szó
Írj programot, mely a szabványos bemenetről fájl végéig olvas egy szöveget, a benne található leghosszabb szót megtalálja, és a futás végén a kimenetre írja! Egy szó alatt a bemeneti karakterfolyam olyan szakaszát értjük, melyben csak angol betűk vannak. A szavak bármilyen hosszúak lehetnek. (Javasolt saját függvényt írni a sztringhez karakter hozzáfűzéshez és sztring értékadáshoz.)
Megoldás (de előtte próbáld meg te magad!)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
void ertekadas(char **hova, char *mit) {
free(*hova);
*hova = (char*) malloc((strlen(mit) + 1) * sizeof(char));
strcpy(*hova, mit);
}
void hozzafuz(char **str, char mit) {
char *uj = (char*) malloc((strlen(*str) + 2) * sizeof(char));
sprintf(uj, "%s%c", *str, mit);
free(*str);
*str = uj;
}
int main() {
char *akt = NULL, *legh = NULL;
ertekadas(&akt, "");
ertekadas(&legh, "");
int c;
while ((c = getchar()) != EOF) {
if (isalpha(c)) {
hozzafuz(&akt, c);
} else {
if (strlen(akt) > strlen(legh))
ertekadas(&legh, akt);
ertekadas(&akt, "");
}
}
printf("leghosszabb: %s\n", legh);
free(akt);
free(legh);
return 0;
}
Pontozás:
- főprogram: inicializálás 1p, beolvasás 1p, beolvasás ciklusfeltétele 1p, maximumkeresés 1p
- értékadás: régi terület felszabadítása 1p, új foglalása 1p, másolás és lezáró nulla 1p
- hozzáfűzés: régi terület felszabadítása 1p, új foglalása 1p, másolás és lezáró nulla 1p
Továbbá az általános pontozási irányelvek.
Átszállások
Szöveges fájlokban buszjáratok megállóinak neveit tároljuk, soronként egyet. A neveik maximum 60 karakterből állnak. A programod feladata, hogy láncolt listákba beolvassa a buszjáratok adatait, és megmondja két adott járatról, hogy át lehet-e szállni egyikről a másikra, vagy nem; és ha igen, hol.
- Írj függvényt, amely paraméterként egy fájlnevet kap, visszatérési értéke pedig egy járat megállóinak listája (a fájlban szereplő sorrendben).
- Írj függvényt, amely megvizsgál két, paraméterként kapott megállólistát, hogy van-e átszállási lehetőség (azonos megállónév). A függvény visszatérési értéke egy sztring legyen, amely a megálló neve.
- Egészítsd ki mindezt teljes programmá, amelyben beolvasod a 7E.txt és az M3.txt nevű fájlokat! Ha át lehet szállni, írd ki a megálló nevét, ha nem, akkor pedig írd ki azt! Ne felejtsd el felszabadítani a memóriát, amit foglaltál!
Megoldás (de előtte próbáld meg te magad!)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Megallo {
char nev[60+1];
struct Megallo *kov;
} Megallo;
Megallo *jarat_beolvas(char const *fajlnev) {
FILE *fp = fopen(fajlnev, "r");
if (fp == NULL)
return NULL;
char megallo[60+1];
Megallo *elso = NULL, *utolso = NULL;
while (fscanf(fp, " %[^\n]", megallo) != EOF) {
Megallo *uj = (Megallo*) malloc(sizeof(Megallo));
strcpy(uj->nev, megallo);
uj->kov = NULL;
if (elso == NULL) {
elso = uj;
} else {
utolso->kov = uj;
}
utolso = uj;
}
fclose(fp);
return elso;
}
void felszabadit(Megallo *lista) {
while (lista != NULL) {
Megallo *kov = lista->kov;
free(lista);
lista = kov;
}
}
char const *hol_van_kozos(Megallo *j1, Megallo *j2) {
for (Megallo *it1 = j1; it1 != NULL; it1 = it1->kov)
for (Megallo *it2 = j2; it2 != NULL; it2 = it2->kov)
if (strcmp(it1->nev, it2->nev) == 0)
return it1->nev;
return NULL;
}
int main(void) {
Megallo *j1, *j2;
j1 = jarat_beolvas("7E.txt");
j2 = jarat_beolvas("M3.txt");
if (j1 == NULL || j2 == NULL) {
printf("Nem sikerült beolvasni valamelyik járatot\n");
} else {
char const *atszallas = hol_van_kozos(j1, j2);
if (atszallas == NULL)
printf("Nincs közös megálló\n");
else
printf("Közös megálló: %s\n", atszallas);
}
felszabadit(j1);
felszabadit(j2);
return 0;
}
Pontozás:
- típus 1p.
- járat beolvasása hibaellenőrzéssel 4p. lista végéhez fűzés 4p (beleértve, hogy O(n)).
- n2 keresés 4p.
- felszabadítás 2p, ha nincs duplikálva a kód.
- főprogram 3p.
Továbbá az általános pontozási irányelvek.