Minta második ZH

Czirkos Zoltán · 2019.02.27.

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, "rt");
    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.