Kis ZH 2012

Itt találhatók a gyak- és a labor kis ZH-k megoldásai.

1 Gyak KZH 1.

Hétfő 12, A

Írj programot, amely kér egy n egész számot a felhasználótól, és utána „o” betűkből egy akkora háromszöget rajzol, amennyi a szám. Pl. n=5 esetén az alábbi rajz jelenik meg a kimenetén.

ooooo
 oooo
  ooo
   oo
    o
#include <stdio.h>

int main() {
    int n, x, y;

    printf("Haromszog magassaga?\n");
    scanf("%d", &n);

    for (y=0; y<n; y+=1) {
        for (x=0; x<y; x+=1)
            printf(" ");
        for (x=y; x<n; x+=1)
            printf("o");

        printf("\n");
    }

    return 0;
}

Hétfő 12, B

Írj programot, amely kér egy n egész számot a billentyűzetről, és utána akkora „háztetőt” rajzol kettőskereszt karakterekből, amekkora a szám. Pl. n=5 esetén az alábbi rajz jelenik meg a kimeneten.

    ##
   #  #
  #    #
 #      #
#        #
#include <stdio.h>

int main() {
    int n, x, y;

    printf("Hazteto magassaga?\n");
    scanf("%d", &n);

    for (y=0; y<n; y+=1) {
        for (x=0; x<n-y-1; x+=1)
            printf(" ");
        printf("#");
        for (x=0; x<y*2; x+=1)
            printf(" ");
        printf("#");
        printf("\n");
    }

    return 0;
}

Kedd 10, A

Írj programot, amely két számot (m és n) kér a billentyűzetről, és egy szakaszt rajzol karakterekből összerakva. A szakasz darabjainak a hosszát az első szám adja meg, a sorok számát a második. Pl. m=3, n=5 esetén:

xxx
   xxx
      xxx
         xxx
            xxx
#include <stdio.h>

int main() {
    int m, n, x, y;

    printf("Vonal darabok szelessege, osszmagassag?\n");
    scanf("%d %d", &m, &n);

    for (y=0; y<n; y+=1) {
        for (x=0; x<m*y; x+=1)
            printf(" ");
        for (x=0; x<m; x+=1)
            printf("x");
        printf("\n");
    }

    return 0;
}

Kedd 10, B

Írj programot, amely beolvas egy egész számot, és egymás mellé rajzol két ferde vonalat, karakterekből összerakva. A második vonal teteje egy karakterrel arrébb kezdődik, mint az első vége. Pl. ha a megadott n szám 5, a kimeneten az alábbi rajz jelenik meg.

#    #
 #    #
  #    #
   #    #
    #    #
#include <stdio.h>

int main() {
    int n, x, y;

    printf("Atlos vonal hossza?\n");
    scanf("%d", &n);

    for (y=0; y<n; y+=1) {
        for (x=0; x<y; x+=1)
            printf(" ");
        printf("#");
        for (x=0; x<n-1; x+=1)
            printf(" ");
        printf("#");
        printf("\n");
    }

    return 0;
}

2 Labor KZH 1.

Kedd

Egy program bekér a felhasználótól három valós számot, kiírja, hogy az első szám negatív vagy nemnegatív, majd az első számtól indulva, a második szám által meghatározott lépésközzel halad a harmadik számig, a számsorozat elemeit kiírja.
Pl. be: 3.2 0.6 5.1 ki: nemnegativ 3.2 3.8 4.4 5.0
Pl. be: -1.7 1.0 2.5 ki: negativ -1.7 -0.7 0.3 1.3 2.3
Add meg az algoritmus pszeudokódját, és készítsd el a programot C nyelven! A program kötelezően a pszeudokódot valósítsa meg! Feltételezheted, hogy az első szám kisebb, mint a harmadik, és a második szám pozitív, ennek ellenőrzésével nem kell foglalkoznod. A kiírás formázásával sem kell foglalkoznod (pl. hány tizedesjegy jelenik meg), egyszerűen csak írd ki a számokat!

#include <stdio.h>

int main() {
    double a, step, b, i;
    scanf("%lg%lg%lg", &a, &step, &b);
    if (a < 0)
        printf("negativ ");
    else
        printf("nemnegativ ");
    i=a;
    while (i <= b) {
        printf("%g, ",i);
        i = i + step;
    }
    return 0;
}

Szerda

Egy program bekér a felhasználótól két pozitív egész számot, és a kisebbiktől a nagyobbikig növekvő lépésközzel kiírja a számokat. A lépésköz kezdetben 1, és minden lépésben eggyel nő. A program akkor is helyesen működik, ha a felhasználó előbb a felső, aztán az alsó határt adja meg (és fordítva is).
Pl. be: 4 23 ki: 4 5 7 10 14 19
Pl. be: 23 4 ki: 4 5 7 10 14 19
Add meg az algoritmus pszeudokódját, és készítsd el a programot C nyelven! A program kötelezően a pszeudokódot valósítsa meg!

#include <stdio.h>

int main() {
    int elso, masodik, also, felso, i, step;

    printf("Elso = ");       scanf("%d",&elso);
    printf("Masodik = ");    scanf("%d",&masodik);

    if (elso > masodik) { also = masodik; felso = elso; }
    else {also = elso; felso = masodik; }

    i = also;
    step = 1;
    while (i <= felso) {
        printf("%d ", i);
        i = i + step;
        step = step + 1;
    }

    return 0;
}

Csütörtök

Egy program bekér a felhasználótól két valós számot, melyek két szöget jelentenek °-ban. A program a kisebb szögtől a nagyobbig haladva kiírja a szögeket egy fokonként, és mindegyik szög mellett zárójelbe téve radiánban is kiírja a szöget (1°=π/180 rad). A program akkor is helyesen működik, ha a felhasználó előbb a nagyobb, aztán a kisebb szöget adja meg (és fordítva is).
Pl. be: 11.3 14.9 ki: 11.3 (0.197), 12.3 (0.215), 13.3 (0.232), 14.3 (0.249),
Pl. be: 180 176 ki: 176 (3.07), 177 (3.09), 178 (3.11), 179 (3.12), 180 (3.14),
Add meg az algoritmus pszeudokódját, és készítsd el a programot C nyelven! A kiírás formázásával sem kell foglalkoznod (pl. hány tizedesjegy jelenik meg), egyszerűen csak írd ki a számokat!

#include <stdio.h>

int main() {
    double also, felso, i;
    scanf("%lg %lg",&also, &felso);
    if (also>felso) {
        double temp=also;
        also=felso;
        felso=temp;
    }
    i = also;
    while (i<=felso) {
        printf("%g (%g), ", i, i*3.14/180);
        i = i + 1;
    }
    return 0;
}

Péntek

Egy program bekér a felhasználótól két pozitív valós számot, és a nagyobbiktól induló csökkenő számsorozatot ír ki. A csökkenés lépésköze a kisebbik szám. A csökkenés addig tart, amíg a kiírandó érték nagyobb, mint a kisebbik szám. A program akkor is helyesen működik, ha a felhasználó előbb a nagyobb, aztán a kisebb számot adja meg (és fordítva is).
Pl. be: 1.1 5.2 ki: 5.2 4.1 3.0 1.9
Pl. be: 6.3 2.1 ki: 6.3 4.2
Add meg az algoritmus pszeudokódját, és készítsd el a programot C nyelven! A kiírás formázásával sem kell foglalkoznod (pl. hány tizedesjegy jelenik meg), egyszerűen csak írd ki a számokat!

#include <stdio.h>

int main() {
    double also, felso, i;
    scanf("%lg %lg",&also, &felso);
    if (also>felso) {
        double temp=also;
        also=felso;
        felso=temp;
    }
    i = felso;
    while (also<i) {
        printf("%g ", i);
        i = i - also;
    }
    return 0;
}

3 Gyak KZH 2.

Hétfő 12, A

Egy áruházban 32 kassza van, 1-től számozva. A tulajdonos nyomon szeretné követni a napi forgalom adatait az egyes kasszáknál. Így minden vásárláskor egy központi gépen megjelenik a kassza sorszáma és a fizetett összeg, szóközzel elválasztva: 11 33800 – Ez a 11-es kassza, 33800 Ft. Írj olyan programot, ami beolvassa ezeket az adatokat a szabványos bemenetéről, és összegzi kasszánként a bevételeket! (Záráskor 0 0 számokkal zárul az aznapi forgalom figyelése.) Írja ki az összegzés után, melyik kasszánál mekkora volt a bevétel, és hogy az az összbevétel hány százaléka! Ha egy kassza az adott napon nem üzemelt, akkor az ne jelenjen meg.

#include <stdio.h>

int main() {
    int kassza, osszeg, i;
    int forint[32] = {0}, osszbevetel = 0;

    scanf("%d %d", &kassza, &osszeg);
    while (kassza!=0) {
        forint[kassza-1] += osszeg;
        osszbevetel += osszeg;
        scanf("%d %d", &kassza, &osszeg);
    }

    for (i=0; i<32; i+=1)
        if (kassza[i]!=0)
            printf("%2d. kassza, %6d Ft, %f%%.\n",
                i+1, kassza[i], 100.0*kassza[i]/osszbevetel);

    return 0;
}

Hétfő 12, B

Egy áruházban 32 kassza van, 1-től számozva. A tulajdonos észrevette, hogy bizonyos kasszákat valamiért a vevők jobban preferálnak, és ezt szeretné megfigyelni. Minden vásárláskor egy központi gépen megjelenik a kassza sorszáma, amely egy 1...32 közötti egész szám. Záráskor a 0 számmal zárul az aznapi forgalom figyelése. Írj olyan programot, ami beolvassa a kasszák sorszámait, és a nap végén kiírja a szabványos kimenetre annak a kasszának a sorszámát, ahol a legtöbb vevő járt, és azt is, hogy ez az összes vevő hány százaléka!

#include <stdio.h>

int main() {
    int kassza, max, i;
    int vasarlok[32] = {0}, osszvasarlok = 0;

    scanf("%d", &kassza);
    while (kassza!=0) {
        vasarlok[kassza-1] += 1;
        osszvasarlok += 1;
        scanf("%d", &kassza);
    }

    max = 0;
    for (i=1; i<32; i+=1)
        if (vasarlok[i]>vasarlok[max])
            max = i;

    printf("A kedvenc kassza a(z) %d-edik, "
           "a vasarlok %f%%-a ment oda.\n",
        max+1, 100.0*vasarlok[max]/osszvasarlok);

    return 0;
}

Kedd 10, A

Bölcsész haverod, aki az angol nyelvvel foglalkozik, szeretné megvizsgálni a szavakban előforduló betűk gyakoriságát. Ezért megkér téged, hogy írj egy programot, amely a szabványos bemenetén egy angol nyelvű szöveget fogad (fájl vége jelig). A szöveg eleve nagybetűsítve van: „TO BE OR NOT TO BE: THAT IS THE QUESTION.” A programod feladata egy statisztikát készíteni, amelyben az szerepel, hogy melyik betű hányszor fordult elő a szövegben, és az összes betű hány százalékát adja. A kimenete ilyen:
A: 19 db, 5.0%
B: 7 db, 1.8%
stb.
Ha valamelyik betű nem szerepelt a szövegben, az ne jelenjen meg a statisztikában se! A nem betű karaktereket figyelmen kívül kell hagyni.

#include <stdio.h>

int main() {
    char c;
    int gyakorisag['Z'-'A'+1] = {0}, osszes = 0;

    while (scanf("%c", &c)==1)
        if (c>='A' && c<='Z') {
            gyakorisag[c-'A'] += 1;
            osszes += 1;
        }

    for (c='A'; c<='Z'; c+=1)
        if (gyakorisag[c-'A']!=0)
            printf("%c: %d db, %f %%.\n",
                c-'A', gyakorisag[c-'A'], 100.0*gyakorisag[c-'A']/osszes);

    return 0;
}

Kedd 10, B

Kódtörő haverod nagyon ért a titkosítások visszafejtéséhez, a programozással viszont hadilábon áll. Szerzett egy számjegyekből álló titkos kódot:
1238971125432563125555535555665554325671231321555253555
Megfigyelte, hogy ebben nem egyforma a jegyek gyakorisága. Megkért téged, hogy írj egy programot, amely a szabványos bemenetén fogadja ezt a karaktersorozatot (fájl vége jelig), és megmondja, hogy melyik az a számjegy, amely a legtöbbször szerepelt, és azt is, hogy hány % a gyakorisága! A fenti bemenetre ez az 5-ös számjegy, 40%-kal. Ha bemeneten számjegyen kívül más karakter is szerepel, azt figyelmen kívül kell hagyni.

#include <stdio.h>

int main() {
    int gyakorisag[10] = {0}, osszes;
    char c;
    int max, i;

    while (scanf("%c", &c)==1)
        if (c>='0' && c<='9') {
            gyakorisag[c-'0']+=1;
            osszes += 1;
        }

    max = 0;
    for (i=1; i<10; i+=1)
        if (gyakorisag[i]>gyakorisag[max])
            max = i;

    printf("Leggyakoribb: %c, %f %%-kal.\n", '0'+max,
        100.0*gyakorisag[max]/osszes);

    return 0;
}

4 Labor KZH 2.

Kedd

Írj C programot, amely bekér a felhasználótól egy egész számot, és kiírja a számnál kisebb számok közül a legnagyobb prímet, ha van ilyen! Tömböt használni tilos!

#include <stdio.h>

int main(){
    int szam, prim = 0;
    scanf("%d",&szam);
    if(szam>2){
        for( szam--; szam>1 && !prim; szam-- ){
            int i;
            prim=1;
            for(i=2; i<szam && prim; i++)
                if( szam % i == 0) prim = 0;
        }
        printf("%d\n", szam+1);
    }
    return 0;
}

Szerda

Írj C programot, amely egész számokat kér be a felhasználótól mindaddig, amíg a felhasználó pozitív számokat ad meg! Ezt követően írja ki a beolvasott számok közül a legnagyobb prímet (a beolvasott számok között lehet a legnagyobb prímnél nagyobb összetett szám is, tehát nem elég a maximumot vizsgálni, a prímséget is kell)! Tömböt használni tilos!

#include <stdio.h>

int main(){
    int szam, max = 0;
    while( scanf("%d", &szam)==1 && szam>0){
        if( szam > max ){
            int i, prim;
            for( i = 2, prim = 1; i < szam; i++ )
                if( szam % i == 0 ) prim = 0;
            if(prim) max = szam;
        }
    }
    if(max>0) printf("Max= %d\n",max);
    return 0;
}

Csütörtök

Írj C programot, amely karaktereket olvas a szabványos bemenetről! A karaktersorozat végét pont (’.’) jelzi. A program írja ki azokat a karaktereket, amelyek sorszáma a szövegben egy prímszám (tehát a szöveg 2, 3, 5, 7, 11 stb. sorszámú karaktereit)! Tömböt használni tilos!

Pl. be: „:Ebfeldiszeileg nyilul szorom egy mancsot ez? ma nem.”, ki: „Ebedelni mentem”.

#include <stdio.h>

int main() {
    char ch;
    int sorszam = 1;
    while (scanf("%c", &ch)==1 && ch!='.') {
        int i;
        for (i = 2; sorszam%i!=0 && i<sorszam; i++) /*üres*/;
        if (sorszam==i)
            printf("%c", ch);
        sorszam++;
    }
    return 0;
}

Péntek

Írj C programot, amely bekér a felhasználótól egy pozitív egész számot (nem kell ellenőrizni, feltételezzük, hogy a felhasználó valóban pozitív egészt adott meg)! A program számítsa ki a szám osztóinak összegét, és írja ki, hogy ez prím-e! Tömböt használni tilos! Pl. be: 9 ki: Osszeg: 13, prím (1+3+9).

#include <stdio.h>

int main(){
    int szam, osszeg, i;
    scanf("%d",&szam);

    /* Osztók sszege */
    for( osszeg = 0, i = 1; i <= szam; i++ )
        if( szam % i == 0 ) osszeg += i;

    /* Prím-e */
    for( i = 2; i < osszeg && osszeg % i != 0; i++ ) /* üres */ ;

    if( i == osszeg) printf("Osszeg: %d, prim\n", osszeg);
    else printf("Osszeg: %d, nem prim\n", osszeg);

    return 0;
}

5 Gyak KZH 3.

Hétfő 12, A

Egy geometriai programban körök adatait kell tárolni: középpont (x, y koordináta) és sugár. Ezek valós számok.

#include <stdio.h>
#include <math.h>

typedef struct Kor {
    double x, y, r;
} Kor;

Kor beolvas(void) {
    Kor k;
    scanf("%lf %lf %lf", &k.x, &k.y, &k.r);
    return k;
}

int atfed(Kor k1, Kor k2) {
    return sqrt(pow(k1.x-k2.x, 2)-pow(k1.y-k2.y, 2))<k1.r+k2.r;
}

int main() {
    Kor a, b;
    a=beolvas();
    b=beolvas();
    printf("%s\n", atfed(a, b) ? "Atfedik egymast" : "Nem fedik at egymast.");
    return 0;
}

Hétfő 12, B

Egy gyárban fémrudakat gyártanak. A megmunkálás pontatlansága miatt azonban ezek hossza kicsit eltérő: pl. egy 1 méteresnek szánt rúd 999 mm és 1001 mm között bármekkorára sikerülhet. Ha két ilyen rudat egymás mögé teszünk, akkor az összegzett hosszuk valahol 1998 és 2002 mm között lesz.

#include <stdio.h>

typedef struct Rud {
    double min, max;
} Rud;

Rud osszeg(Rud r1, Rud r2) {
    Rud uj;
    uj.min=r1.min+r2.min;
    uj.max=r1.max+r2.max;
    return uj;
}

double atlagos(Rud r) {
    return (r.min+r.max)/2;
}

int main() {
    Rud a = { 999, 1001 }, b = { 498, 502 }, o;

    o = osszeg(a, b);
    printf("min: %f, max: %f, atlag: %f\n",
        o.min, o.max, atlagos(o));

    return 0;
}

Kedd 10, A

Geometriai programodban téglalapok adatait kell tárolni: x, y bal felső koordináták, szélesség és magasság (valós számok).

#include <stdio.h>

typedef struct Teglalap {
    double x, y, a, b;
} Teglalap;

Teglalap beolvas(void) {
    Teglalap uj;
    scanf("%lf %lf %lf %lf", &uj.x, &uj.y, &uj.a, &uj.b);
    return uj;
}

int atfed(Teglalap t1, Teglalap t2) {
    /* ez a t2 bal felso sarkat nezi. a tobbit is kellene, de ez
     * boven elegendo volt a pont megszerzesehez. */
    return t2.x>t1.x && t2.y>t1.y && t2.x<t1.x+t1.a && t2.y<t1.y+t1.a;
}

int main() {
    Teglalap t1, t2;

    t1 = beolvas();
    t2 = beolvas();
    printf("%s\n", atfed(t1, t2) ?
            "Eltakar valamennyit belole." : "Nincsenek atfedesben.");

    return 0;
}

Kedd 10, B

Egy programban kétdimenziós vektorok adatait kell tárolni. Ilyenek lehetnek a sebességek: vx vízszintes irányú, vy függőleges irányú sebességek adják a v sebességvektort.

#include <stdio.h>
#include <math.h>

typedef struct Vektor {
    double x, y;
} Vektor;

Vektor osszeg(Vektor v1, Vektor v2) {
    Vektor uj;
    uj.x=v1.x+v2.x;
    uj.y=v1.y+v2.y;
    return uj;
}

double hossz(Vektor v) {
    return sqrt(pow(v.x, 2)+pow(v.y, 2));
}

int main() {
    Vektor v1 = { 1, 2 }, v2 = { -0.5, 3 }, vo;

    vo = osszeg(v1, v2);
    printf("vx: %f, vy: %f\n", vo.x, vo.y);
    printf("hossz: %f\n", hossz(vo));
    return 0;
}

6 Lab KZH 3.

Kedd

Mennyi 20|13? Írd le mindkét számot, valamint az eredményt is kettes számrendszerben! Az eredményt tízes számrendszerben is add meg!

 20 = 10100
|13 = 01101
-----------
 29 = 11101
 

Írj C függvényt, amely paraméterként kap egy pozitív egész számot, és logikai igazzal tér vissza, ha a szám pontosan 6 db 1-es bitet tartalmaz! Tömböt használni tilos!

int hat(unsigned szam) {
    int db=0;
    for (db=0; szam!=0; szam>>=1)
        db += szam & 1;
    return db == 6;
}

Szerda

Mennyi 42&54 ? Írd le mindkét számot, valamint az eredményt is kettes számrendszerben! Az eredményt tízes számrendszerben is add meg!

 42 = 101010
&54 = 110110
------------
 34 = 100010

Írj C függvényt, amely paraméterként kap két előjel nélküli egész számot (mit, db), és mit-et db számú bittel forgatja el jobbra, és ezt az értéket adja vissza (az előjel nélküli egészeket 32 bitesnek feltételezzük)! A jobbra forgatás azt jelenti, hogy mit bitjei db számú bittel jobbra tolódnak, és a „kieső” bitek a szám elejére kerülnek vissza. Pl. be: mit = 16775850 = 00000000111111111111101010101010 és db = 4, ki: 2685403050 = 10100000000011111111111110101010. Tömböt használni tilos!

unsigned rotr2(unsigned mit, int db) {
    unsigned eredmeny = 0, i;
    for (i = 0; i < 32; i++)
        if (mit & (1 << ((i + db) % 32)))
            eredmeny |= 1 << i;
    return eredmeny;
}

Csütörtök

Mennyi 0x2A ^ 0x36 ? Írd le mindkét számot, valamint az eredményt is kettes számrendszerben! Az eredményt tizenhatos számrendszerben is add meg!

 0x2A = 101010
^0x36 = 110110
--------------
 0x1C = 011100

Írj függvényt, amely paraméterként kap egy egész számot, melyről feltételezzük, hogy 16 bites. A függvény logikai igazzal térjen vissza, ha a számban bárhol található egymás mellett két 1-es értékű bit, és hamissal, ha nem! Pl. 138=10001010 esetén hamis a válasz, 154=10011010 esetén pedig igaz. Tömböt használni tilos!

int dupla(unsigned szam) {
    int i;
    for (i = 0; i < 15; i++)
        if (((szam >> i) & 3) == 3)
            return 1;
    return 0;
}

Egy trükkös megoldás. (Ha egymás mellett két egyes van, eggyel léptetve azok át fogják fedni egymást. Az így kapott számok bitenkénti ÉS-elve ezért nem nullát adnak.)

int dupla(unsigned szam) {
    return (szam & (szam << 1)) != 0;
}

Péntek

Mennyi (~22) & 10 ? Írd le 22-t, ~22-t és 10-et, valamint az eredményt is kettes számrendszerben!

 22 = 010110
~22 = 101001
 10 = 001010
------------
  8 = 001000

Írj függvényt, amely paraméterként kap három egész számot (szam, honnan, db)! A függvény vegye ki a szam jobbról honnan sorszámú, db számú bitet tartalmazó tartományát, és ezt adja vissza egész számként! Pl. Be: 471, 3, 5 => 471=111010111 => 10101=21, tehát ki: 21. Tömböt használni tilos!

unsigned kivesz2(unsigned szam, int honnan, int db) {
    unsigned temp = 0, tolt = szam >> (honnan - 1);
    int i;
    for (i = 0; i < db; i++)
        temp |= tolt & (1 << i);
    return temp;
}

Pohl László trükkös megoldása az alábbi. (A temp az alsó helyiértékein már a kivágandó biteket tartalmazza. Ebből eldobva az alsó db darabot, invertálva saját magával, az összes többi 1-es eltűnik.)

int temp = szam >> (honnan-1);
return temp ^ (temp >> db << db);

Benedek Zsófia ötlete. (Balra csúsztatva a felső bitek dobhatóak el (aztán vissza), jobbra csúsztatva az alsók. Ez 32 bitesen működik. A két jobbra shift egyébként összevonható.)

return (szam<<(32-(honnan-1)-db)>>(32-(honnan-1)-db))) >> (honnan-1);

Estók Dániel megoldása. (0 = csupa 0, ~0 = csupa 1, ~0<<db = csupa 1, de alul db darab 0, ~(~0<<db) = csupa 0, de alul db darab 1-es, és ez pont a maszk, ami kell.)

return (szam>>(honnan-1)) & ~(~0 << db);

Abonyi József megoldása. (1<<db a fenti maszknál pont eggyel nagyobb szám, ami ráadásul pont kettő hatványa. Ezzel modulózva kivághatók az alsó bitek.)

return (szam>>(honnan-1)) % (1<<db);

7 Gyak KZH 4.

Hétfő 12, A

Definiálj egy olyan DinSztring struktúrát, amely egy tetszőlegesen hosszú sztring karaktereit tárolja dinamikus tömbben, és annak hosszát is megjegyzi (a tömb nincsen nullával lezárva)!

Írj függvényt, amely átvesz paraméterként egy ilyen sztringet, és úgy módosítja a tartalmát, hogy abból eltűnnek a szóközök! Pl. „egy ilyen sztring”-ből „egyilyensztring” lesz. A foglalt tömbnek mindig pont akkorának kell lennie, amennyi a karakterek tárolásához szükséges. A szükséges fejlécfájlokat jelezd!

Írj rövid programrészt, amelyben definiálsz egy ilyen változót, és azzal a feltételezéssel, hogy már tartalmaz valamit, szóközteleníted.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct DinSztring {
    int meret;
    char *betuk;
} DinSztring;

void spacetelenit(DinSztring *ds) {
    int i, j, kell;
    char *uj;
    
    kell=0;
    for (i=0; i<ds->meret; ++i)
        if (ds->betuk[i]!=' ')
            ++kell;
    uj = (char*) malloc(kell*sizeof(char));
    j=0;
    for (i=0; i<ds->meret; ++i)
        if (ds->betuk[i]!=' ')
            uj[j++] = ds->betuk[i];
    
    free(ds->betuk);
    ds->betuk = uj;
    ds->meret = kell;
}

int main() {
    DinSztring szoveg;  /* a mainbol csak ez a sor kellett */
    
    szoveg.meret = strlen("ez egy szoveg");
    szoveg.betuk = (char*) malloc(sizeof(char)*szoveg.meret);
    strncpy(szoveg.betuk, "ez egy szoveg", szoveg.meret);
    
    spacetelenit(&szoveg);  /* es ez a sor */
    
    int i;
    for (i=0; i<szoveg.meret; ++i)
        putchar(szoveg.betuk[i]);
    free(szoveg.betuk);
    
    return 0;
}

Hétfő 12, B

Definiálj egy olyan Halmaz struktúrát, amely egy elemszámot, és a halmaz elemeit (egész típusúak) képes tárolni egy dinamikus tömbben!

Írj függvényt, amely paraméterként kap egy ilyen halmazt, és egy számot. Távolítsa el a függvény a halmazból azokat a számokat, amelyek kisebbek a paraméterben kapottnál! A lefoglalt tömbnek mindig pont akkorának kell lennie, mint amennyi elem van. A szükséges fejlécfájlokat jelezd!

Írj rövid programrészt, amelyben definiálsz egy halmaz változót, és azzal a feltételezéssel, hogy már vannak benne adatok, kiveszed belőle a 20-nál kisebbeket!

#include <stdio.h>
#include <stdlib.h>

typedef struct Halmaz {
    int meret;
    double *szamok;
} Halmaz;

void kisebbeket_kivesz(Halmaz *h, double minel) {
    int i, j, kell;
    double *uj;
    
    kell = 0;
    for (i=0; i<h->meret; ++i)
        if (!(h->szamok[i]<minel))
            ++kell;
    
    uj = (double*) malloc(sizeof(double)*kell);
    j = 0;
    for (i=0; i<h->meret; ++i)
        if (!(h->szamok[i]<minel))
            uj[j++] = h->szamok[i];
    
    free(h->szamok);
    h->szamok = uj;
    h->meret = kell;
}

int main() {
    Halmaz h;  /* a mainbol csak ez a sor kellett */
    int i;
    
    h.meret = 5;
    h.szamok = (double*) malloc(sizeof(double)*5);
    for (i=0; i<5; ++i)
        h.szamok[i]=i*15;
    
    kisebbeket_kivesz(&h, 20);  /* es ez a sor */

    for (i=0; i<h.meret; ++i)
        printf("%g ", h.szamok[i]);
    free(h.szamok);
    
    return 0;
}

Kedd 10, A

Definiálj egy olyan DinSztring struktúrát, amely egy tetszőlegesen hosszú sztring karaktereit tárolja dinamikus tömbben, és annak hosszát is megjegyzi (a tömb nincsen nullával lezárva)!

Írj függvényt, amely átvesz paraméterként egy ilyen sztringet, és madárnyelvesíti a sztringet: minden magánhangzó után betesz egy v betűt, és újra a magánhangzót (mavadávárnyelv). Ehhez tételezd fel, hogy van egy maganhangzo() függvény, amely igazat ad vissza magánhangzó karakterekre. A foglalt tömbnek pont akkorának kell lennie, amennyi a karakterek tárolásához szükséges. A szükséges fejlécfájlokat jelezd!

Írj rövid programrészt, amelyben definiálsz egy ilyen DinSztring változót, és azzal a feltételezéssel, hogy már tartalmaz valamit, madárnyelvesíted.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct DinSztring {
    int meret;
    char *betuk;
} DinSztring;

/* ez a fuggveny nem kellett */
int maganhangzo(char c) {
    return c=='a' || c=='e' || c=='i' || c=='o' || c=='u';
}

void madar(DinSztring *ds) {
    int i, j, kell;
    char *uj;
    
    kell=0;
    for (i=0; i<ds->meret; ++i)
        kell += maganhangzo(ds->betuk[i]) ? 3 : 1;
    
    uj = (char*) malloc(kell*sizeof(char));
    
    j=0;
    for (i=0; i<ds->meret; ++i) {
        uj[j++] = ds->betuk[i];
        if (maganhangzo(ds->betuk[i])) {
            uj[j++] = 'v';
            uj[j++] = ds->betuk[i];
        }
    }
    
    free(ds->betuk);
    ds->betuk = uj;
    ds->meret = kell;
}

int main() {
    DinSztring szoveg;  /* a mainbol csak ez a sor kellett */
    
    szoveg.meret = strlen("ez egy szoveg");
    szoveg.betuk = (char*) malloc(sizeof(char)*szoveg.meret);
    strncpy(szoveg.betuk, "ez egy szoveg", szoveg.meret);
    
    madar(&szoveg);  /* es ez a sor */
    
    int i;
    for (i=0; i<szoveg.meret; ++i)
        putchar(szoveg.betuk[i]);
    free(szoveg.betuk);
    
    return 0;
}

Kedd 10, B

Definiálj olyan DinTomb struktúrát, amely egész típusú számokat (tetszőlegesen sokat) képes tárolni egy dinamikus tömbben, és melléjük eltárolja a darabszámukat is!

Írj függvényt, amely paraméterként kap egy ilyen DinTomb-ot, és kiszűri (eldobja) belőle a negatív számokat! Pl. ha az eredeti tartalom 3, 5, -1, 0, -3, 7, akkor a szűrés után a 3, 5, 0, 7 számok kell, hogy benne legyenek. A foglalt tömbnek pontosan akkorának kell lennie, amekkorában a számok éppen elférnek. A szükséges fejlécfájlokat jelezd!

Írj rövid programrészt, amelyben definiálsz egy DinTomb változót, és azzal a feltételezéssel, hogy már vannak benne számok, kiszűröd belőle a negatívakat!

#include <stdio.h>
#include <stdlib.h>

typedef struct DinTomb {
    int meret;
    int *szamok;
} DinTomb;

void negativakat_kivesz(DinTomb *h) {
    int i, j, kell;
    int *uj;
    
    kell = 0;
    for (i=0; i<h->meret; ++i)
        if (!(h->szamok[i]<0))
            ++kell;
    
    uj = (int*) malloc(sizeof(int)*kell);
    j = 0;
    for (i=0; i<h->meret; ++i)
        if (!(h->szamok[i]<0))
            uj[j++] = h->szamok[i];
    
    free(h->szamok);
    h->szamok = uj;
    h->meret = kell;
}

int main() {
    DinTomb h;  /* a mainbol csak ez a sor kellett */
    int i;
    
    h.meret = 5;
    h.szamok = (int*) malloc(sizeof(int)*5);
    for (i=0; i<5; ++i)
        h.szamok[i]=i*15-30;
    
    negativakat_kivesz(&h);  /* es ez a sor */

    for (i=0; i<h.meret; ++i)
        printf("%d ", h.szamok[i]);
    free(h.szamok);
    
    return 0;
}

8 Lab KZH 4.

Kedd

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 C++ kommenten belül van „//” karakterpár, az nem növeli a kommentek számát. Készíts állapotgépes modellt állapottábla és tevékenységtábla megadásával, majd valósítsd meg C program formájában!

#include <stdio.h>

int main() {
    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;
            case komment:
                if (c == '\n')
                    all = kod;
                break;
        }
    }
    printf("%d darab komment", szaml);
    return 0;
}

Szerda

A feladat a szabványos bemenetről érkező Haskell nyelvű programkódban megszámolni, hogy hány komment van benne, és a darabszámot kiírni. A szöveg végét fájl vége jelzi. A Haskell komment két - (mínusz) jellel kezdődik, és a sor végéig tart, pl.:
lesser = filter (< p) xs -- kivalogatja a p-nel kisebbeket
Ha a kommenten belül van „--” karakterpár, az nem növeli a kommentek számát. Készíts állapotgépes modellt állapottábla és tevékenységtábla megadásával, majd valósítsd meg C program formájában!

#include <stdio.h>

int main() {
    int c, szaml = 0;
    enum Allapot { kod, minuszvolt, komment } all = kod;
    all = kod;
    while ((c = getchar()) != EOF) {
        switch (all) {
            case kod:
                if (c == '-')
                    all = minuszvolt;
                break;
            case minuszvolt:
                if (c == '-') {
                    szaml++;
                    all = komment;
                } else
                    all = kod;
            case komment:
                if (c == '\n')
                    all = kod;
                break;
        }
    }
    printf("%d darab komment", szaml);
    return 0;
}

Csütörtök

A feladat a szabványos bemenetről érkező szövegben (fájl vége jelig) megszámolni, hogy hány üres sor van benne. A szöveget a szabványos kimenetre ki is kell írni változatlanul, majd a szöveg után az üres sorok darabszámát. Üres sornak számít az, amiben nincs karakter, de az is, amiben csak szóközök vannak. Készíts állapotgépes modellt állapottábla és tevékenységtábla megadásával, majd valósítsd meg C program formájában!

#include <stdio.h>

int main() {
    enum Allapot { soreleje, sorbelseje } all = soreleje;
    int c, szaml = 0;
    while ((c = getchar()) != EOF) {
        putchar(c);
        switch (all) {
            case soreleje:
                if (c == '\n')
                    szaml++;
                else if (c != ' ')
                    all = sorbelseje;
                break;
            case sorbelseje:
                if (c == '\n')
                    all = soreleje;
                break;
        }
    }
    printf("%d ures sor volt.", szaml);
    return 0;
}

Péntek

A feladat a szabványos bemenetről érkező C sztring feldolgozása: a szövegben szereplő \n, \t és \" karakterpárokat a megfelelő karakterrel (újsor, tabulátor, idézőjel) helyettesíteni, és úgy írni a szabványos kimenetre. (Egyéb \+karakter párok nem szerepelnek a sztringben, kezelésük tetszőleges.) Készíts állapotgépes modellt állapottábla és tevékenységtábla megadásával, majd valósítsd meg C program formájában! Pl. be:

hello \n    \"világ\"

ki:

hello
    "világ"!
#include <stdio.h>

int main() {
    enum Allapot { alap, visszaper } all = alap;
    int c;
    while ((c = getchar()) != EOF) {
        switch (all) {
            case alap:
                if (c == '\\')
                    all = visszaper;
                else
                    putchar(c);
                break;
            case visszaper:
                switch (c) {
                    case 'n':
                        putchar('\n');
                        break;
                    case 't':
                        putchar('\t');
                        break;
                    case '"':
                        putchar('"');
                        break;
                }
                all = alap;
                break;
        }
    }
    return 0;
}

9 Gyak KZH 5.

Hétfő 12, A

Írj függvényt, amely egy lista legelső elemét a lista végére helyezi át! (Például az 1,2,3,4,5 listából így 2,3,4,5,1 lesz.) Ha kettőnél kevesebb elem van, akkor ne csináljon semmit.

Definiáld az egyszeresen láncolt lista adatszerkezetét úgy, hogy egész számokat tartalmazzon! Készíts rajzot, amely a listakezelést mutatja számozott lépésekkel (2p)! Írj programrészt, amely létrehoz két listaelemet, és a függvénnyel áthelyezi az első elemet a lista végére!

typedef struct Lista {
   int szam;
   struct Lista *kov;
} Lista;

Lista *elso_vegere(Lista *elso) {
   Lista *iter, *masodik;
   
   if (elso==NULL) return;
   if (elso->kov==NULL) return;
   
   for (iter=elso; iter->kov!=NULL; iter=iter->kov)
      ;
   
   masodik=elso->kov;
   iter->kov=elso;      
   elso->kov=NULL;      
   return masodik;      
}
 
Lista *eleje;

eleje=(Lista*) malloc(sizeof(Lista));
eleje->szam=3;
eleje->kov=(Lista*) malloc(sizeof(Lista));
eleje->kov->szam=4;
eleje->kov->kov=NULL;

eleje = elso_vegere(eleje);

Hétfő 12, B

Írj függvényt, amely egy lista utolsó elemét a lista elejére helyezi át! (Például az 1,2,3,4,5 listából így 5,1,2,3,4 lesz.) Ha kettőnél kevesebb elem van, akkor ne csináljon semmit.

Definiáld az egyszeresen láncolt lista adatszerkezetét úgy, hogy az valós számokat tartalmazzon! Készíts rajzot, amely a listakezelést mutatja számozott lépésekkel (2p)! Írj programrészt, amely létrehoz két listaelemet, és meghívja a keletkező listára a függvényt.

typedef struct Lista {
   double szam;
   struct Lista *kov;
} Lista;
 
Lista *utolso_elore(Lista *eleje) {
   Lista *iter, *utolso;
   
   if (eleje==NULL) return;
   if (eleje->kov==NULL) return;
   
   for (iter=eleje; iter->kov->kov!=NULL; iter=iter->kov)
      ;
   utolso=iter->kov;
   
   utolso->kov=eleje;   
   iter->kov=NULL;      
   return utolso;       
}
 
Lista *eleje;

eleje=(Lista*) malloc(sizeof(Lista));
eleje->szam=3;
eleje->kov=(Lista*) malloc(sizeof(Lista));
eleje->kov->szam=4;
eleje->kov->kov=NULL;

eleje = utolso_elore(eleje);

Kedd 10, A

Írj függvényt, amely paraméterként vesz át egy számokból álló listát, és törli abból a páros számokat! Ha a lista eredeti tartalma 2,3,4,5,6, akkor a módosított lista 3,5 kell legyen.

Definiáld az egyszeresen láncolt lista adatszerkezetét úgy, hogy az egész számokat tartalmazzon! Készíts rajzot, amely a listakezelést mutatja számozott lépésekkel (2p)! Írj programrészt, amely meghívja egy listára a függvényt!

typedef struct Lista {
   int szam;
   struct Lista *kov;
} Lista;
 
Lista *parosakat_torol(Lista *eleje) {
    Lista *iter, *lemarado;
    
    iter = eleje;
    lemarado = NULL;
    
    while (iter!=NULL) {
        if (iter->szam%2 == 0) {
            Lista *kov = iter->kov;
            if (lemarado!=NULL)
                lemarado->kov = kov;    
            else
                eleje = kov;            
            
            free(iter);                 
            iter = kov;
        } else {
            lemarado = iter;
            iter = iter->kov;
        }
    }
    
    return eleje;
}

Lista *eleje = ..........;

eleje = parosakat_torol(eleje);

Kedd 10, D

Írj függvényt, amely paraméterként vesz át egy számokból álló listát, és minden páros szám elé beszúr egy listaelemet, amely annak ellentettjét tartalmazza! Például ha az eredeti lista 2,3,4,5, akkor a módosított -2,2,3,-4,4,5 legyen.

Definiáld az egyszeresen láncolt lista adatszerkezetét úgy, hogy az egész számokat tartalmazzon! Készíts rajzot, amely a listakezelést mutatja számozott lépésekkel (2p)! Írj programrészt, amely létrehoz két listaelemet, és meghívja a keletkező listára a függvényt.

typedef struct Lista {
   int szam;
   struct Lista *kov;
} Lista;

Lista *parosakat_duplaz(Lista *eleje) {
    Lista *iter, *lemarado;

    for (iter = eleje, lemarado = NULL;
         iter != NULL;
         lemarado = iter, iter = iter->kov) {
        if (iter->szam%2 == 0) {
            Lista *uj = (Lista *) malloc(sizeof(Lista));
            uj->szam = -iter->szam;
            uj->kov = iter;
            if (lemarado!=NULL)
                lemarado->kov = uj;
            else
                eleje = uj;
        }
    }

    return eleje;
}

Lista *eleje = .............;

eleje = parosakat_duplaz(eleje);

10 Lab KZH 5.

Kedd

Hozz létre típust, mely alkalmas egészek láncolt listában való tárolására! Írj függvényt, amely átvesz egy NULL-terminált, növekvően rendezett listát a fenti típusból, és egy új számot. A számot úgy szúrja a listába, hogy annak rendezettsége megmaradjon. A működés áttekintéséhez készíts ábrát! Egy másik függvénnyel gondoskodj a lista felszabadításáról is. Az elkészült függvények alkalmazását rövid programrészlettel szemléltesd; a listát feltöltöttnek tekintheted.

typedef struct listaelem {
    int adat;
    struct listaelem *kov;
} listaelem;

listaelem *beszur(listaelem *elso, int ertek) {
    listaelem *futo, *lemarado, *uj;
    uj=(listaelem *)malloc(sizeof(listaelem));  
    uj->adat=ertek;

    if(elso == NULL || elso->adat > ertek) {
        uj->kov=elso;
        elso=uj;        
    }
    else {
        for(futo=elso; futo != NULL && futo->adat <= ertek; futo=futo->kov)
            lemarado=futo;
        uj->kov=futo;   
        lemarado->kov=uj;
    }
    return elso;
}

void felszab(listaelem *elso) {
    listaelem *futo=elso, *lemarado;
    while(futo != NULL) {
        lemarado=futo;
        futo=futo->kov;
        free(lemarado);
    }
}


listaelem *elso=NULL;
elso = beszur(elso, 5);
felszab(elso);

Szerda

Hozz létre típust, mely alkalmas tetszőleges méretű szavak láncolt listában való tárolására, azaz a szavak helyét dinamikusan kell kezelni! Írj függvényt, amely átvesz két NULL-terminált listát a fenti típusból, és az első lista végéhez fűzi a másodikat. A függvény az új lista kezdőcímével térjen vissza; feltételezhetjük, hogy az átvett eredeti listákat és kezdőcímeiket a hívás helyén már nem használjuk tovább. A függvény akkor is helyesen működjön, ha bármelyik lista üres! A működés áttekintéséhez készíts ábrát! Egy másik függvénnyel gondoskodj a lista felszabadításáról is. Az elkészült függvények alkalmazását rövid programrészlettel szemléltesd; a listákat feltöltöttnek tekintheted.

typedef struct listaelem {
    char *szo;      
    struct listaelem *kov;
} listaelem;

listaelem *osszefuz(listaelem *elso, listaelem *masodik) {
    listaelem *futo;
    
    if(elso == NULL) 
        return masodik;
    else {
        for(futo=elso; futo->kov != NULL; futo=futo->kov); 
        futo->kov=masodik; 
    }
    
    return elso;
}

void felszab(listaelem *elso) {
    listaelem *futo=elso, *lemarado;
    while(futo != NULL) {
        lemarado=futo;
        futo=futo->kov;
        free(lemarado->szo);
        free(lemarado);
    }
}


listaelem *egy, *ket, *uj;
uj=osszefuz(egy, ket);
felszab(uj);

Csütörtök

Hozz létre típust, mely alkalmas egészek kétszeresen láncolt listában való tárolására! Írj függvényt, amely átvesz egy mindkét végén strázsával lezárt listát a fenti típusból, és kitörli a negatív értékű elemeket. A működés áttekintéséhez készíts ábrát! Egy másik függvénnyel gondoskodj a lista felszabadításáról is. Az elkészült függvények alkalmazását rövid programrészlettel szemléltesd; a listát feltöltöttnek tekintheted.

typedef struct listaelem {
    int adat;
    struct listaelem *elozo, *kov;
} listaelem;

void kiszed(listaelem *elso) {
    listaelem *futo, *torlendo;
    
    futo=elso->kov; 
    while(futo->kov != NULL) {
        
        if(futo->adat < 0) {
            torlendo=futo;
            futo=futo->kov;
            torlendo->elozo->kov=torlendo->kov;     
            torlendo->kov->elozo=torlendo->elozo;
            free(torlendo);         
        }
        else
            futo=futo->kov; 
    }
}

void felszab(listaelem *elso)
{
    listaelem *futo=elso, *lemarado;
    while(futo != NULL)
    {
        lemarado=futo;
        futo=futo->kov;
        free(lemarado);
    }
}

listaelem *elso, *utolso;
kiszed(elso);
felszab(elso);

Péntek

Hozz létre típust, mely alkalmas valós számok láncolt listában való tárolására! Írj függvényt, amely átvesz egy NULL-terminált listát a fenti típusból, és egy új számot. A számot véletlenszerűen kiválasztott helyre szúrja a listába, tehát az a végére és az elejére is kerülhet! A működés áttekintéséhez készíts ábrát! Az elkészült függvény alkalmazását rövid programrészlettel szemléltesd; a listát feltöltöttnek tekintheted.

typedef struct listaelem {
    double adat;
    struct listaelem *kov;
} listaelem;


int szamol(listaelem *elso) {
    int i;
    for(i=0; elso != NULL; i++, elso=elso->kov);
    return i;
}

void veletlenbe(listaelem **elso, double ertek) {
    int i, n;
    listaelem *futo, *uj=(listaelem *)malloc(sizeof(listaelem));
    uj->adat=ertek; 
    
    n=rand()%(szamol(*elso)+1); 
    if(n == 0)  {
        uj->kov=*elso;
        *elso=uj;
    }
    else {
        for(futo=*elso, i=1; i<n; futo=futo->kov, i++);
        uj->kov=futo->kov; 
        futo->kov=uj;
    }   
}


listaelem *elso=NULL;
veletlenbe(&elso, 2.71);