programozas-peldatar

Upload: zsolt-magyar

Post on 05-Apr-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/2/2019 programozas-peldatar

    1/109

    Ksa Mrk Pnovics Jnos

    Pldatr a Programozs 1 trgyhoz

    Juhsz Istvn feladatsoraibl

    mobiDIK knyvtr

  • 8/2/2019 programozas-peldatar

    2/109

  • 8/2/2019 programozas-peldatar

    3/109

    Ksa Mrk Pnovics Jnos

    Pldatr a Programozs 1 trgyhoz

    Juhsz Istvn feladatsoraibl

  • 8/2/2019 programozas-peldatar

    4/109

    mobiDIK knyvtr

    SOROZATSZERKESZT

    Fazekas Istvn

  • 8/2/2019 programozas-peldatar

    5/109

    Ksa Mrk Pnovics Jnos

    Pldatr a Programozs 1 trgyhoz

    Juhsz Istvn feladatsoraibl

    Egyetemi jegyzet

    els kiads

    mobiDIK knyvtr

    Debreceni EgyetemInformatikai Intzet

  • 8/2/2019 programozas-peldatar

    6/109

    Lektor

    Juhsz IstvnDebreceni Egyetem

    Copyright c Ksa Mrk, Pnovics Jnos, 2004

    Copyright c elektronikus kzls mobiDIK knyvtr, 2004

    mobiDIK knyvtrDebreceni EgyetemInformatikai Intzet4010 Debrecen, Pf. 12http://mobidiak.unideb.hu

    A m egyni tanulmnyozs cljra szabadon letlthet. Minden egyb felhasznls csaka szerzk elzetes rsbeli engedlyvel trtnhet.

    A m a A mobiDIK nszervez mobil portl (IKTA, OMFB-00373/2003) s a GNUItertor, a legjabb genercis portl szoftver (ITEM, 50/2003) projektek keretben k-szlt.

  • 8/2/2019 programozas-peldatar

    7/109

    Tartalomjegyzk

    Elsz 7

    1. Pldk tematikus csoportostsban 81.1. A legegyszerbb feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.2. Egydimenzis tmbk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.3. Sztringek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211.4. Ktdimenzis tmbk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

    1.5. Fk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341.6. Kifejezsek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381.7. llomnyok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

    2. Feladatsorok 822.1. 1994. mjus 16., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 822.2. 1995. mjus 15., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 822.3. Idpontja ismeretlen, nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 842.4. Idpontja ismeretlen, nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 862.5. 1996. mjus 18., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 872.6. 1996. jnius 13., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 882.7. 1996. december 14., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

    2.8. 1997. mjus 26., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 892.9. 1997. jnius 10., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 902.10. 1997. jnius 16., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 902.11. 1998. mjus 18., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 912.12. 1998. mjus 29., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 912.13. 1998. jnius 2., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 922.14. 1998. december 12., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 922.15. 1999. mjus 17., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 932.16. 1999. mjus 21., esti tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 932.17. 1999. december 10., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942.18. 2000. janur 12., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942.19. 2000. mjus 10., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942.20. 2000. mjus 20., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 952.21. 2000. augusztus 21., esti tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 952.22. 2000. december 1., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962.23. 2001. janur 3., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962.24. 2001. prilis 28., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962.25. 2001. mjus 14., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 972.26. 2001. augusztus 21., esti tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 972.27. 2001. oktber 26., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 972.28. 2001. november 30., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 982.29. 2001. december 17., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 982.30. 2001. december 18., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 982.31. 2002. janur 2., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992.32. 2002. janur 2., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

    2.33. 2002. prilis 20., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1002.34. 2002. mjus 13., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1002.35. 2002. mjus 23., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

  • 8/2/2019 programozas-peldatar

    8/109

    6 Tartalomjegyzk

    2.36. 2002. augusztus 21., esti tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1012.37. 2002. november 29., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1012.38. 2003. janur 6., esti tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1012.39. 2003. janur 6., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1022.40. 2003. mjus 17., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1022.41. 2003. mjus 23., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1032.42. 2003. mjus 28., nappali tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1032.43. 2003. augusztus 25., esti tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1032.44. 2003. december 5., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1042.45. 2004. janur 9., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1042.46. 2004. mjus 15., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1052.47. 2004. jnius 2., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1052.48. 2004. december 3., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1052.49. 2004. december 20., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1062.50. 2005. mjus 14., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1062.51. 2005. jnius 14., levelez tagozat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

  • 8/2/2019 programozas-peldatar

    9/109

    Elsz

    A Programozs 1 trgy gyakorlatainak keretben a 2001/2002-es tanvtl kezdve mindhrom kpzsiformban (nappali, levelez s esti tagozaton) a C programozsi nyelvet tanuljk hallgatink. A flvvgi beugrkon is e nyelven kell kdolniuk a feladataikat. Termszetes az igny, hogy mindenki sz-mra hozzfrhet mdon rendelkezsre lljon egy feladatgyjtemny, amely a feladatok szvege melletttartalmazza azok lehetsges megoldsait is.

    Ez a gyjtemny egy vlogats a trgy eladjnak, Juhsz Istvnnak a beugrkon ratott feladatso-raibl, az 1994-es nyri vizsgaidszaktl kezdden egszen napjainkig. A korai feladatsorok egy konkrtprogramozsi nyelvhez (Turbo Pascalhoz vagy C-hez) kapcsoldtak, mg az jabbak tetszleges nyelvenmegoldhatk. Igazodva azonban a tantrgy gyakorlati kvetelmnyeihez, ebben a pldatrban csak Cnyelv programkdokat adunk kzre. A feladatokat tmakrnknt csoportostottuk, minden tmak-rn bell igyekeztnk egy nehzsgi sorrendet is fellltani. A legtbb feladatnak csak egy lehetsgesmegoldst kzltk, m ahol tbb, egymstl valamilyen lnyeges szempontbl klnbz megolds isltezett, ott azok kzl tbbet is megadtunk. Ugyanakkor az is elkpzelhet s ettl szp a programozs, hogy az olvas fog kitallni az itt lertaktl eltr, esetleg egyszerbb megoldst egyik-msik feladatra.

    A pldatrban kzreadott programkdokat Linux opercis rendszer alatt GNU C fordtval tesztel-tk, de brmely ANSI C fordtval lefordthatk.

    A feladatgyjtemny vgn megtallhat az sszes beugr feladatsor idrendi sorrendben 1994.mjus 16-tl kezdve. Ezekbl az olvas kpet kaphat arrl, hogy milyen nehzsg feladatsorokat kellettmegoldaniuk a hallgatknak az elmlt vekben, s egyttal tesztelheti sajt tudst is.

    Sikeres felkszlst kvnnak a szerzk, akik a feladatgyjtemnyben esetleg benne maradt aprbb hib-krt elnzst krnek, s minden javt szndk kritikt szvesen vesznek a kvetkez cmek valamelyikn:

    [email protected] vagy [email protected].

    Debrecen, 2004. janur 18.

    Ksa MrkPnovics Jnos

  • 8/2/2019 programozas-peldatar

    10/109

    1. fejezet

    Pldk tematikus csoportostsban

    1.1. A legegyszerbb feladatok

    1.1. feladat. rjon programot, amely billentyzetrl lthat karaktereket olvas mindaddig, amga @ karaktert meg nem kapja. A program hatrozza meg s rja kpernyre a beolvasott klnbzkaraktereket s azok gyakorisgt!

    Egy tetszleges karakterrl a ctype.h-ban definilt isprint() fggvny segtsgvel tudjuk eldnteni,hogy lthat-e (nyomtathat-e). Azonban mivel most kizrlag lthat karaktereket olvasunk, ezrt ezaz ellenrzs elhagyhat. gy egy lehetsges megolds a kvetkez:

    #include

    main(){

    int c;int gyak[ 256 ] = { 0 };while ( ( c = getchar() ) != @ )

    ++gyak[ c ];for ( c = 0; c < 256; ++c )

    if ( gyak[ c ] != 0 )

    printf( "%c: %d\n", c, gyak[ c ] );}

    1.2. feladat. rjon programot, amely billentyzetrl egsz rtkeket olvas be a 0 vgjelig. A prog-ram rja kpernyre azokat az rtkeket, amelyek megegyeznek az elz kt rtk sszegvel.

    #include

    #define FALSE 0#define TRUE !FALSE

    main(){

    int t[ 3 ], idx = -1, megvolt = FALSE;f o r ( ; ; ){

    scanf( "%d", &t[ idx = ( idx + 1 ) % 3 ] );if ( !t[ idx ] )

    break;if ( idx == 2 )

    megvolt = TRUE;if ( megvolt && t[ idx ] == t[ ( idx + 1 ) % 3 ] + t[ ( idx + 2 ) % 3 ] )

    printf( "%d\n", t[ idx ] );}

    }

    1.3. feladat. rjon programot, amely nulltl klnbz egsz rtkeket olvas be a billentyzetrla 0 vgjelig. A program hatrozza meg s rja kpernyre azt a hrom rtket, amelynek tlagamaximlis.

  • 8/2/2019 programozas-peldatar

    11/109

    1.1. A LEGEGYSZERBB FELADATOK 9

    A feladat megfogalmazsa csalafinta, gyakorlatilag a hrom legnagyobb rtket kell kivlasztani a be-gpelt szmok kzl, hiszen ezek tlaga lesz maximlis. Hromnl kevesebb beolvasott rtk esetn aprogramok csak egy figyelmeztet zenetet rnak a kpernyre.

    (a) Az els megolds trolja az sszes beolvasott rtket, majd a 0 rtk beolvassa utn cskkensorrendbe rendezi ket, s kirja kzlk az els hrmat (ha van legalbb hrom rtk).

    #include

    void rendez_csok( int t[], int meret ){

    int i, j;for ( i = meret - 2; i >= 0; --i )

    for ( j = 0; j

  • 8/2/2019 programozas-peldatar

    12/109

    10 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    {int index = tomb[ 0 ] < tomb[ 1 ] ? tomb[ 0 ] < tomb[ 2 ] ? 0 : 2 :

    tomb[ 1 ] < tomb[ 2 ] ? 1 : 2;if ( szam > tomb[ index ] )

    tomb[ index ] = szam;}

    }if ( meret < 3 )

    puts( "Nincs hrom rtk." );else

    printf( "%d, %d, %d\n", tomb[ 0 ], tomb[ 1 ], tomb[ 2 ] );}

    (c) A harmadik megolds a msodik megoldshoz hasonlan a hrom legnagyobb rtket trolja, ame-lyek sorrendje azonban a beolvass szerinti sorrend marad.

    #include

    #define N 3

    main(){

    int tomb[ N ], meret = 0, szam;scanf( "%d", &szam );while ( szam ){

    if ( meret < N )tomb[ meret++ ] = szam;

    else{

    int index = 0, i;for ( i = 1; i < N; ++i )if ( tomb[ i ] < tomb[ index ] )

    index = i;if ( tomb[ index ] < szam ){

    while ( index < N - 1 ){

    tomb[ index ] = tomb[ index + 1 ];++index;

    }tomb[ N - 1 ] = szam;

    }}scanf( "%d", &szam );

    }if ( meret < N )

    printf( "Nem volt %d rtk\n", N );else{

    int i;printf( "%d", tomb[ 0 ] );for ( i = 1; i < N; ++i )

    printf( ", %d", tomb[ i ] );putchar( \n );

    }}

  • 8/2/2019 programozas-peldatar

    13/109

    1.1. A LEGEGYSZERBB FELADATOK 11

    1.4. feladat. rjon programot, amely a billentyzetrl pozitv egsz szmokat olvas mindaddig, mg0-t nem adunk. A program vlassza ki a szmok kzl a legkisebbeket s a legnagyobbakat (lehetnekazonos rtkek is, de legfeljebb 3-3), rja azok rtkt a kpernyre, s adja meg, hogy hnyadikkntolvastuk be ket!

    #include

    main(){

    int szam, i, legk, legn, min[ 3 ], max[ 3 ], mindb = 0, maxdb;for ( i = 1; ; ++i ){

    scanf( "%d", &szam );if ( szam == 0 )

    break;i f ( i = = 1 ){

    legk = legn = szam; min[ 0 ] = max[ 0 ] = 1; mindb = maxdb = 1;

    }else{

    if ( szam < legk ){

    legk = szam; mindb = 1; min[ 0 ] = i;

    }

    else if ( szam > legn ){

    legn = szam; maxdb = 1; max[ 0 ] = i;

    }else{

    if ( szam == legk ) min[ mindb++ ] = i;

    if ( szam == legn ) max[ maxdb++ ] = i;

    }}

    }if ( mindb == 0 )

    puts( "Nem volt egy rtk sem." );else{

    printf( "A legkisebb rtk: %d.\nElfordulsai: ", legk );for ( i = 0; i < mindb; ++i )

    printf( "%d ", min[ i ] );printf( "\nA legnagyobb rtk: %d.\nElfordulsai: ", legn );for ( i = 0; i < maxdb; ++i )

    printf( "%d ", max[ i ] );

    putchar( \n );}

    }

  • 8/2/2019 programozas-peldatar

    14/109

    12 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    1.2. Egydimenzis tmbk

    1.5. feladat. rjon eljrst, amely paramterknt megkap egy karaktereket tartalmaz, tetszlegesmret egydimenzis tmbt, s a tmb nem bet karaktereit kicserli szkzre.

    #include

    void nembetu( char t[], int meret ){

    int i;for ( i = 0; i < meret; ++i )

    if ( !isalpha( t[ i ] ) )t [ i ] = ;

    }

    1.6. feladat. rjon eljrst, amely paramterknt megkap egy tetszleges mret, egszeket tar-talmaz egydimenzis tmbt. Az eljrs hatrozza meg a tmbben lv pozitv, negatv s nullaelemek darabszmt! Az eljrs nem rhat a kpernyre!

    A feladat tbbflekppen is megoldhat.(a) Nzzk elszr azt a megoldst, amikor az eljrs globlis vltozkban hatrozza meg a pozitv,

    negatv s nulla elemek darabszmt:

    int pozitiv, negativ, nulla;

    void poznegnull( int *t, int meret ){

    int i;pozitiv = negativ = nulla = 0;for ( i = 0; i < meret; ++i )

    i f ( t [ i ] > 0 )

    ++pozitiv;else if ( t[ i ] < 0 )

    ++negativ;else

    ++nulla;}

    (b) Egy msik megoldsi lehetsg, ha az eljrsnak tadunk mg hrom paramtert, azoknak a me-mriaterleteknek a cmt, ahol a keresett rtkeket trolni szeretnnk:

    void poznegnull( int *t, int meret, int *pozitiv, int *negativ, int *nulla ){

    int i;*pozitiv = *negativ = *nulla = 0;for ( i = 0; i < meret; ++i )

    i f ( t [ i ] > 0 )++*pozitiv;

    else if ( t[ i ] < 0 )++*negativ;

    else++*nulla;

    }

    1.7. feladat. rjon eljrst, amely paramterknt megkap egy tetszleges mret, sztringeket tar-talmaz vektort, s elllt egy olyan vektort, amelymek elemei rendre a paramterknt kapott vektor

    elemeinek annyiadik karaktert tartalmazzk, amennyi az adott elem indexe, illetve a @ karaktert,ha nem ltezik ilyen elem. Egy sztring karaktereit 0-tl sorszmozzuk. Az eljrsban nem lehetsemmilyen I/O mvelet!

  • 8/2/2019 programozas-peldatar

    15/109

    1.2. EGYDIMENZIS TMBK 13

    #include #include

    char *vektor;

    void kukacvektor( char *tomb[], int meret ){

    int i;vektor = ( char * )malloc( meret * sizeof( char ) );for ( i = 0; i < meret; ++i )

    vektor[ i ] = strlen( tomb[ i ] )

  • 8/2/2019 programozas-peldatar

    16/109

    14 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    if ( fabs( tomb[ i ] - atlag ) > atlag / 2 )printf( "%lf\n", tomb[ i ] );

    }

    1.10. feladat. rjon programot, amely billentyzetrl pozitv vals szmokat olvas be mindaddig,amg nullt nem adunk (tudjuk, hogy maximum 100 szm lehet). A program rja egy most ltrehozott

    szveges llomnyba azokat a beolvasott szmokat, amelyeknek a szmok tlagtl val eltrsenagyobb, mint az tlag fele!

    #include #include

    #define MERET 100

    main(){

    FILE *fout;double tomb[ MERET ], atlag = 0, szam;int darab = 0, i;fout = fopen( "atlagfel.txt", "w" );scanf( "%lf", &szam );while ( szam != 0 ){

    atlag += tomb[ darab++ ] = szam;scanf( "%lf", &szam );

    }if ( darab > 0 ){

    atlag /= darab;for ( i = 0; i < darab; ++i )

    if ( fabs( tomb[ i ] - atlag ) > atlag / 2 )

    fprintf( fout, "%lf\n", tomb[ i ] );}fclose( fout );

    }

    1.11. feladat. rjon eljrst, amely egy paramterknt megkapott, karaktereket tartalmaz egy-dimenzis tmbben meghatrozza azon rsz kezd- s vgindext, amelyben azonos karakterekvannak! Tbb ilyen esetn vlassza ki azt, amelyben a karakterek szma maximlis!

    void azonosresz( char t[], int meret, int *kezdo, int *veg ){

    int k = 0, v;*kezdo = *veg = 0;

    for ( v = 1; v < meret; ++v )i f ( t [ v ] ! = t [ v - 1 ] )

    k = v;else if ( v - k > *veg - *kezdo ){

    *kezdo = k;*veg = v;

    }}

    1.12. feladat. rjon programot, amely billentyzetrl egyenknt beolvas egsz rtkeket addig,amg a 1 rtket nem kapja. A program rja kpernyre a beolvasott szmok azon szekvencijt,amely a leghosszabb szigoran monoton cskken sorozatot alkotja!

    #include #include

  • 8/2/2019 programozas-peldatar

    17/109

    1.2. EGYDIMENZIS TMBK 15

    main(){

    int i, *sorozat = NULL, kezdo = 0, veg = -1, maxkezdo = 0, maxveg = 0;do{

    sorozat = ( int * )realloc( sorozat, ( ++veg + 1 ) * sizeof( int ) );scanf( "%d", &sorozat[ veg ] );if ( veg != 0 &&

    ( sorozat[ veg ] >= sorozat[ veg - 1 ] || sorozat[ veg ] == -1 ) ){

    if ( veg - 1 - kezdo > maxveg - maxkezdo ){

    maxkezdo = kezdo; maxveg = veg - 1;

    }kezdo = veg;

    }

    } while ( sorozat[ veg ] != -1 );for ( i = maxkezdo; i

  • 8/2/2019 programozas-peldatar

    18/109

    16 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    *kezdo = *veg = 0;reszosszeg[ 0 ] = 0;for ( i = 1; i maxosszeg ){

    maxosszeg = reszosszeg[ v + 1 ] - reszosszeg[ k ];*kezdo = k;*veg = v;

    }free( reszosszeg );

    }

    (c) Vgl lssuk azt a megoldst, amely egyetlen for-ciklussal hatrozza meg a legnagyobb sszegrsztmb kezd- s vgindext.

    void maxosszresz( int t[], int meret, int *kezdo, int *veg ){

    int reszosszeg, maxosszeg, i, k; maxosszeg = reszosszeg = *t;*kezdo = *veg = k = 0;for ( i = 1; i < meret; ++i ){

    if ( reszosszeg >= 0 )reszosszeg += t[ i ];

    else{

    reszosszeg = t[ i ];

    k = i;}if ( reszosszeg > maxosszeg ){

    maxosszeg = reszosszeg;*kezdo = k;*veg = i;

    }}

    }

    1.14. feladat. rjon eljrst, amely egy paramterknt megadott, sztringeket tartalmaz egydimen-zis tmbt elemeinek hossza szerint cskken sorrendbe rendez!

    A feladat megoldshoz a qsort() knyvtri fggvnyt hasznljuk. A rendezst kveten az azonoshosszsg sztringek egymshoz viszonytott elhelyezkedse implementcifgg.

    #include /* qsort() */#include

    int rendezo( const void *egyik, const void *masik ){

    return strlen( *( char ** )masik ) - strlen( *( char ** )egyik );}

    void quickcsoksztring( char *t[], int meret )

    {qsort( t, meret, sizeof( char * ), rendezo );

    }

  • 8/2/2019 programozas-peldatar

    19/109

    1.2. EGYDIMENZIS TMBK 17

    Lsd mg a 1.15. feladat megoldst!

    1.15. feladat. rjon egy eljrst, amely a paramterknt megkapott, tetszleges mret, sztrin-geket tartalmaz, egydimenzis tmbt a sztringek hossznak cskken sorrendjbe teszi! Azonoshosszak esetn a sztringek sorrendje az eredeti sorrend legyen!

    A feladatban lert egydimenzis tmb rendezsre brmely olyan rendez algoritmus alkalmas, amelynem vltoztatja meg a tmb azonos hosszsg elemeinek relatv sorrendjt. Egy ilyen algoritmus akzvetlen beszr rendezs:

    #include

    void csoksztringhossz( char *t[], int meret ){

    int j;for ( j = 1; j < meret; ++j ){

    char *kulcs = t[ j ];int i = j - 1;

    while ( i >= 0 && strlen( t[ i ] ) < strlen( kulcs ) ){

    t [ i + 1 ] = t [ i ] ;--i;

    }t[ i + 1 ] = kulcs;

    }}

    Lsd mg a 1.14. feladat megoldst!

    1.16. feladat. rjon eljrst, amely paramterknt megkap egy azonos hosszsg sztringekettartalmaz, tetszleges mret egydimenzis tmbt, tovbb egy karaktert s egy pozitv egsz

    szmot, s a kpernyre rja azokat a tmbelemeket, amelyekben a karakter pontosan az adott szmszorfordul el. A szlssges eseteket vizsglni kell!

    #include #include

    void azonos( char *t[], int meret, char kar, int szam ){

    int i;if ( szam > strlen( t[ 0 ] ) || strlen( t[ 0 ] ) == 0 )

    return;for ( i = 0; i < meret; ++i ){

    int db = 0;char *p;for ( p = t[ i ]; *p; ++p )

    if ( *p == kar )++db;

    if ( db == szam )puts( t[ i ] );

    }}

    1.17. feladat. rjon eljrst, amely egy paramterknt megkapott, angol szavakat tartalmaz egydi-menzis tmbben meghatrozza s kpernyre rja a szavak gyakorisgt!

    #include #include

  • 8/2/2019 programozas-peldatar

    20/109

    18 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    void sztringtombgyak( char *t[], int meret ){

    int i;for ( i = 0; i < meret; ++i ){

    int j;for ( j = 0; j < i; ++j )

    if ( strcmp( t[ i ], t[ j ] ) == 0 )break;

    if ( j == i ) /* ha nem szerepelt korbban */{

    int darab = 1;for ( j = i + 1; j < meret; ++j )

    if ( strcmp( t[ i ], t[ j ] ) == 0 )++darab;

    printf( "%s: %d\n", t[ i ], darab );}

    }

    }

    1.18. feladat. rjon fggvnyt, amely paramterknt megkap egy olyan tetszleges mret egydi-menzis tmbt, amely angol szavakat tartalmaz. A fggvny visszatrsi rtke adja meg a szavakgyakorisgt.

    A feladat tbbflekppen is megoldhat, attl fggen, hogy milyen adatszerkezetben, illetve hogyantroljuk s adjuk vissza a szavak gyakorisgt.

    (a) Nzzk elszr azt a megoldst, amikor egy tblzatot adunk vissza, amelyet egy dinamikusan le-foglalt trterlet kezdcmvel, valamint az ott elhelyezked elemek darabszmval reprezentlunk:

    #include #include

    typedef struct{

    char *szo;int gyakorisag;

    } ELEM;

    typedef struct{

    ELEM *tomb;int meret;

    } GYAK;

    GYAK gyakszo( char *t[], int meret ){

    GYAK gy = { NULL, 0 };int i;for ( i = 0; i < meret; ++i ){

    int j;for ( j = 0; j < gy.meret && strcmp( gy.tomb[ j ].szo, t[ i ] ); ++j )

    ;if ( j < gy.meret )

    ++gy.tomb[ j ].gyakorisag;else

    {gy.tomb = ( ELEM * )realloc( gy.tomb, ( gy.meret + 1 ) * sizeof( ELEM ) );gy.tomb[ gy.meret ].szo = t[ i ];

  • 8/2/2019 programozas-peldatar

    21/109

    1.2. EGYDIMENZIS TMBK 19

    gy.tomb[ gy.meret++ ].gyakorisag = 1;}

    }return gy;

    }

    (b) A kvetkez megolds egy egyirnyban lncolt listban adja meg a keresett adatokat:

    #include #include

    typedef struct listaelem{

    char *szo;int gyakorisag;struct listaelem *kov;

    } LISTAELEM;

    LISTAELEM *gyakszo( char *t[], int meret ){LISTAELEM *lista = NULL;int i;for ( i = 0; i < meret; ++i ){

    LISTAELEM *seged = lista, *elozo = NULL;while ( seged && strcmp( seged->szo, t[ i ] ) ){

    elozo = seged;seged = seged->kov;

    }if ( seged )

    ++seged->gyakorisag;else{

    seged = ( LISTAELEM * )malloc( sizeof( LISTAELEM ) );seged->szo = t[ i ];seged->gyakorisag = 1;seged->kov = NULL;if ( elozo )

    elozo->kov = seged;else

    lista = seged;}

    }return lista;}

    (c) Lssuk vgl a keresfs megoldst:

    #include #include

    typedef struct faelem{

    char *szo;int gyakorisag;

    struct faelem *bal, *jobb;} FAELEM;

  • 8/2/2019 programozas-peldatar

    22/109

    20 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    FAELEM *beszur( FAELEM *fa, char *szo ){

    if ( !fa ){

    fa = ( FAELEM * )calloc( 1, sizeof( FAELEM ) );fa->szo = szo;fa->gyakorisag = 1;

    }else if ( strcmp( fa->szo, szo ) > 0 )

    fa->bal = beszur( fa->bal, szo );else if ( strcmp( fa->szo, szo ) < 0 )

    fa->jobb = beszur( fa->jobb, szo );else

    ++fa->gyakorisag;return fa;

    }

    FAELEM *gyakszo( char *t[], int meret )

    {FAELEM *fa = NULL;int i;for ( i = 0; i < meret; ++i )

    fa = beszur( fa, t[ i ] );return fa;

    }

    1.19. feladat. rjon eljrst, amely egy paramterknt megkapott, sztringeket tartalmaz egydi-menzis tmb minden elemt azonos hosszsgra (a maximlis hosszsg elem hosszsgra)hozza gy, hogy a sztringek elejre megfelel szm szkzt szr be!

    #include #include

    void eloretolt( char *t[], int meret ){

    int i, maxhossz = 0;for ( i = 0; i < meret; ++i )

    if ( strlen( t[ i ] ) > maxhossz ) maxhossz = strlen( t[ i ] );

    for ( i = 0; i < meret; ++i ){

    int j, akthossz = strlen( t[ i ] );t[ i ] = realloc( t[ i ], ( maxhossz + 1 ) * sizeof( char ) );

    for ( j = maxhossz; akthossz >= 0; --j, --akthossz )t[ i ][ j ] = t[ i ][ akthossz ];

    for ( ; j >= 0; --j )t [ i ] [ j ] = ;

    }}

    1.20. feladat. rjon fggvnyt, amely egy egydimenzis, sztringeket tartalmaz tmbt kap para-mterknt, s annak minden elemt csonktja a legrvidebb elem hosszra, s visszaadja az j tmbt!

    #include #include

    char **sztringcsonkolo( char *t[], int meret ){

    char **uj = ( char ** )malloc( meret * sizeof( char * ) );

  • 8/2/2019 programozas-peldatar

    23/109

    1.3. SZTRINGEK 21

    int i, min = strlen( t[ 0 ] );for ( i = 1; i < meret; ++i )

    if ( strlen( t[ i ] ) < min ) min = strlen( t[ i ] );

    for ( i = 0; i < meret; ++i ){

    uj[ i ] = ( char * )malloc( ( min + 1 ) * sizeof( char ) );strncpy( uj[ i ], t[ i ], min );uj[ i ][ min ] = \0;

    }return uj;

    }

    1.21. feladat. rjon eljrst, amely egy paramterknt kapott, sztringeket tartalmaz egydimen-zis tmb minden elemt az elejn s a vgn egyenletesen elosztott szkzkkel kiegszti olyanhosszsgra, mint a leghosszabb elem hossza! Az eredeti tmb nem mdosulhat!

    #include #include

    void eloszt( char *t[], int meret, char ***uj ){

    int maxhossz = 0, i;for ( i = 0; i < meret; ++i )

    if ( strlen( t[ i ] ) > maxhossz ) maxhossz = strlen( t[ i ] );

    *uj = ( char ** )malloc( meret * sizeof( char * ) );for ( i = 0; i < meret; ++i ){

    int j;( *uj )[ i ] = ( char * )malloc( ( maxhossz + 1 ) * sizeof( char ) );

    strcpy( ( *uj )[ i ], "" );for ( j = 0; j < ( maxhossz - strlen( t[ i ] ) ) / 2; ++j )

    strcat( ( *uj )[ i ], " " );strcat( ( *uj )[ i ], t[ i ] );for ( j = strlen( ( *uj )[ i ] ); j < maxhossz; ++j )

    strcat( ( *uj )[ i ], " " );}

    }

    1.3. Sztringek

    1.22. feladat. rjon logikai fggvnyt, amely egy paramterknt megkapott sztringnl igaz rtket

    ad vissza, ha a sztring tkrszimmetrikus (pl. grg, kosarasok)!A feladat a kvetkez megfogalmazsban is szerepelt a beugrkon:

    rjon logikai fggvnyt, amely egy paramterknt megkapott sztringrl eldnti, hogy az palindr-ma-e!

    #include

    int tukorszo( char *s ){

    int i, j;for ( i = 0, j = strlen( s ) - 1; i < j; ++i, --j )

    i f ( s [ i ] ! = s [ j ] )

    return 0;return 1;

    }

  • 8/2/2019 programozas-peldatar

    24/109

    22 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    1.23. feladat. rjon egy logikai fggvnyt, amely egy paramterknt megkapott sztring esetn igazrtkkel tr vissza, ha a sztringben a betk (angol bc!) szma nagyobb, mint a nem-bet karakterekszma, s hamissal tr vissza egybknt!

    #include

    int tobb_betu( char *s ){

    int betu = 0;while ( *s ){

    if ( isalpha( *s ) )++betu;

    else--betu;

    s++;}return betu > 0;

    }

    1.24. feladat. rjon egy fggvnyt, amely egy paramterknt megkapott sztringben szkzzel fe-llrja a nem bet karaktereket s visszaadja az j sztringet!

    #include /* isalpha() */#include /* malloc() */#include /* strlen() */

    char *nembetu( char *s ){

    char *uj = ( char * )malloc( ( strlen( s ) + 1 ) * sizeof( char ) );int i;for ( i = 0; s[ i ]; ++i )

    uj[ i ] = isalpha( s[ i ] ) ? s[ i ] : ;uj[ i ] = \0;return uj;

    }

    1.25. feladat. rjon logikai fggvnyt, amely egy paramterknt megkapott angol sz esetn igazzaltr vissza, ha a szban nincs egyms mellett kt mssalhangz!

    #include #include

    int nincsketmsh( char *s ){char *msh = "bcdfghjklmnpqrstvwxyz";int i;for ( i = 0; i + 1 < strlen( s ); ++i )

    if ( strchr( msh, tolower( s[ i ] ) ) && strchr( msh, tolower( s[ i+1 ] ) ) )return 0;

    return 1;}

    1.26. feladat. rjon logikai fggvnyt, amely egy paramterknt megkapott sztringnl igaz rtketad vissza, ha a sztringben van olyan 4 elem rszsztring, amely legalbb hromszor ismtldik.

    A feladat tbbflekppen is rtelmezhet, s tbbflekppen is megoldhat.

    (a) Az els megoldsban karakterenknt vgezzk az sszehasonltst, s megengedjk a rszsztringekkztti tfedst:

  • 8/2/2019 programozas-peldatar

    25/109

    1.3. SZTRINGEK 23

    #include

    int negyismet( char *s ){

    int i;for ( i = 0; i + 5 < strlen( s ); ++i ){

    int j, darab = 1;for ( j = i + 1; j + 5 - darab < strlen( s ); ++j )

    if ( s[ i ] == s[ j ] && s[ i+1 ] ==s [ j+1 ] && s[ i+2 ] == s[ j+2 ] &&s[ i+3 ] == s[ j+3 ] && ++darab == 3 )

    return 1;}return 0;

    }

    (b) A msodik megoldsban a rszsztringek sszehasonltst az strncmp() knyvtri fggvnyre bz-zuk, s nem engedjk meg a rszsztringek kztt az tfedst:

    #include

    int negyismet( char *s ){

    int i;for ( i = 0; i + 11 < strlen( s ); ++i ){

    int j, darab = 1;for ( j = i + 4; j + 11 - 4 * darab < strlen( s ); ++j )

    if ( !strncmp( s + i, s + j, 4 ) ){

    if ( ++darab == 3 )return 1;j += 3;

    }}return 0;

    }

    1.27. feladat. rjon logikai fggvnyt, amely egy paramterknt kapott sztringrl eldnti, hogyvan-e benne olyan rszsztring, amely pontosan 4 azonos karakterbl ll!

    #include

    int pontnegy( char *s ){

    int i;for ( i = 0; i + 3 < strlen( s ); ++i )

    if ( s[ i ] == s[ i+1 ] && s[ i ] == s[ i+2 ] && s[ i ] == s[ i+3 ] )return 1;

    return 0;}

    1.28. feladat. rjon fggvnyt, amely egy paramterknt megkapott sztringben az egyms mellettll szkzk kzl csak egyet hagy meg, s visszatr az j sztringgel!

    #include

    #include

    char *szokoztelenito( char *s )

  • 8/2/2019 programozas-peldatar

    26/109

    24 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    {char *uj = ( char * )malloc( ( strlen( s ) + 1 ) * sizeof( char ) );int i, j;for ( i = 0, j = 0; i < strlen( s ); ++i )

    if ( i == 0 || s[ i ] != || s[ i-1 ] != )uj[ j++ ] = s[ i ];

    uj[ j ] = \0;return uj;

    }

    1.29. feladat. rjon egy fggvnyt, amelynek els paramtere egy sztring, msodik paramtere egypozitv egsz szm, s a fggvny adja vissza azt a sztringet, amely az eredetibl gy keletkezik, hogyazt az elejn s a vgn kiegsztjk szkzkkel (egyenletesen elosztva azokat) gy, hogy az j sztringhossza a msodik paramter rtke legyen!

    #include #include

    char *eloszt( char *s, int hossz ){

    char *uj;if ( strlen( s ) >= hossz ){

    uj = ( char * )malloc( ( strlen( s ) + 1 ) * sizeof( char ) );strcpy( uj, s );

    }else{

    int i;uj = ( char * )malloc( ( hossz + 1 ) * sizeof( char ) );for ( i = 0; i < ( hossz - strlen( s ) ) / 2; ++i )

    uj[ i ] = ;uj[ i ] = \0;strcat( uj, s );for ( i = strlen( uj ); i < hossz; ++i )

    uj[ i ] = ;uj[ i ] = \0;

    }return uj;

    }

    1.30. feladat. rjon logikai fggvnyt, amely akkor tr vissza igaz rtkkel, ha a paramterkntkapott sztring szabvnyos C egsz literl.

    A feladatot tbbflekppen is meg lehet oldani.(a) Els megoldsunkban llapottmenet-grfot hasznlunk.

    #include

    int egeszliteral( char *s ){

    enum { START, JO, ROSSZ, DECIMALIS, OKT_HEXA, OKTALIS, HEXA_ELSO, HEXA,L, U, LU } allapot = START;

    while ( allapot != JO && allapot != ROSSZ ){

    switch ( allapot )

    {case START: if ( *s == 0 )

    allapot = OKT_HEXA;

  • 8/2/2019 programozas-peldatar

    27/109

    1.3. SZTRINGEK 25

    else if ( isdigit( *s ) )allapot = DECIMALIS;

    elseallapot = ROSSZ;

    break;case DECIMALIS: if ( !*s )

    allapot = JO;else if ( tolower( *s ) == u )

    allapot = U;else if ( tolower( *s ) == l )

    allapot = L;else if ( !isdigit( *s ) )

    allapot = ROSSZ;break;

    case OKT_HEXA: if ( !*s )allapot = JO;

    else if ( tolower( *s ) == x )allapot = HEXA_ELSO;

    else if ( *s >= 0 && *s = 0 && *s

  • 8/2/2019 programozas-peldatar

    28/109

    26 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    break;case U: if ( !*s )

    allapot = JO;else if ( tolower( *s ) == l )

    allapot = LU;else

    allapot = ROSSZ;break;

    case LU: if ( !*s )allapot = JO;

    elseallapot = ROSSZ;

    break;}++s;

    }return allapot == JO;

    }

    (b) A msodik megoldsban egyszer sztringkezelst hasznlunk.

    #include

    #define FALSE 0#define TRUE !FALSE

    int egeszliteral( char *s ){

    int i;if ( !isdigit( s[ 0 ] ) )

    return FALSE;if ( s[ 0 ] == 0 )

    if ( tolower( s[ 1 ] ) == x ){

    if ( !isxdigit( s[ 2 ] ) )return FALSE;

    for ( i = 3; isxdigit( s[ i ] ); ++i );

    }else

    for ( i = 1; s[ i ] >= 0 && s[ i ]

  • 8/2/2019 programozas-peldatar

    29/109

    1.4. KTDIMENZIS TMBK 27

    #include

    int negyzetes( char *s[], int meret ){

    int i, j;for ( i = 0; i < meret - 1; ++i )

    for ( j = i + 1; j < meret; ++j )if ( strcmp( s[ i * meret + j ], s[ j * meret + i ] ) )

    return 0;return 1;

    }

    1.32. feladat. rjon eljrst, amely paramterknt megkapott, tetszleges mret, egszeket tar-talmaz kvadratikus mtrixot tkrz a mellktljra!

    void tukroz( int *t, int meret ){

    int i, j;for ( i = 0; i < meret - 1; ++i )

    for ( j = 0; j < meret - 1 - i; ++j ){

    int seged = t[ i * meret + j ];t[ i * meret + j ] = t[ ( meret - j - 1 ) * meret + ( meret - i - 1 ) ];t[ ( meret - j - 1 ) * meret + ( meret - i - 1 ) ] = seged;

    }}

    1.33. feladat. rjon eljrst, amely paramterknt megkap egy bitmtrixot s egy bitvektort, majda bitmtrix minden oszlopa s a bitvektor kztt kizr vagy mveletet vgez! Az eredeti bitmtrixraa tovbbiakban nincs szksg.

    void xor( int *m, int *v, int sor, int oszlop ){

    int i, j;for ( j = 0; j < oszlop; ++j )

    for ( i = 0; i < sor; ++i ) m[ i * oszlop + j ] ^= v[ i ];

    }

    1.34. feladat. rjon fggvnyt, amely tetszleges mret, vals rtkeket tartalmaz ktdimen-zis tmbt kap paramterknt. A fggvny hatrozza meg azon oszlop indext, amelyben van olyanelem, amelynek az rtke megegyezik az oszlop elemeinek tlagval! Ha tbb ilyen oszlop is van, akkora legnagyobb indexrtket adja vissza!

    int atlagindex( double *t, int sor, int oszlop ){int j;for ( j = oszlop - 1; j >= 0; --j ){

    double atlag = 0;int i;for ( i = 0; i < sor; ++i )

    atlag += t[ i * oszlop + j ];atlag /= sor;for ( i = 0; i < sor; ++i )

    if ( t[ i * oszlop + j ] == atlag )return j;

    }return -1;

    }

  • 8/2/2019 programozas-peldatar

    30/109

    28 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    Megjegyezzk, hogy a t[ i * oszlop + j ] == atlag kifejezs rtke az oszloptlag lebegpontosbrzolsnak pontatlansga miatt igen gyakran akkor is hamis, ha matematikailag megegyezik vele atmbelem rtke. Ezrt a kvetkez megoldst javasoljuk:

    #include /* fabs() */#include /* DBL_EPSILON */

    int atlagindex( double *t, int sor, int oszlop ){

    int j;for ( j = oszlop - 1; j >= 0; --j ){

    double atlag = 0;int i;for ( i = 0; i < sor; ++i )

    atlag += t[ i * oszlop + j ];atlag /= sor;for ( i = 0; i < sor; ++i )

    if ( fabs( t[ i * oszlop + j ] - atlag ) < DBL_EPSILON )return j;}return -1;

    }

    1.35. feladat. rjon fggvnyt, amely egy paramterknt kapott, egszeket tartalmaz ktdimen-zis tmb azon oszlopnak indext adja vissza, amelyben a legkevesebb pozitv elem van!

    Amennyiben tbb oszlopban is annyi pozitv elem van, mint abban, amelyikben a legkevesebb pozitvelem tallhat, akkor az albbi fggvny a legels ilyen oszlop indext hatrozza meg.

    int kevespozoszlop( int *t, int sor, int oszlop ){

    int j, min = sor, minoszlop = 0;for ( j = 0; j < oszlop; ++j ){

    int i, poz = 0;for ( i = 0; i < sor; ++i )

    if ( t[ i * oszlop + j ] > 0 )++poz;

    if ( poz < min ){

    min = poz; minoszlop = j;

    }

    }return minoszlop;

    }

    1.36. feladat. rjon egy fggvnyt, amely egy paramterknt megkapott, egszeket tartalmaz kt-dimenzis tmb esetn megadja azon oszlopok szmt, amelyekben egy szintn paramterknt meg-adott rtknl csak nagyobb rtkek szerepelnek!

    int csaknagyobb( int *t, int sor, int oszlop, int ertek ){

    int j, db = 0;for ( j = 0; j < oszlop; ++j ){

    int i;for ( i = 0; i < sor; ++i )

    if ( t[ i * oszlop + j ]

  • 8/2/2019 programozas-peldatar

    31/109

    1.4. KTDIMENZIS TMBK 29

    break;if ( i == sor )

    ++db;}return db;

    }

    1.37. feladat. rjon eljrst, amely paramterknt megkap egy tetszleges mret, valsakat tar-talmaz ktdimenzis tmbt, s elllt egy olyan egydimenzis tmbt, amely a sorok tlagttartalmazza. Az eljrs a kpernyre nem rhat!

    #include

    double *soratl;

    void soratlagok( double *t, int sor, int oszlop ){

    soratl = ( double * )calloc( sor, sizeof( double ) );int i;

    for ( i = 0; i < sor; ++i ){

    int j;for ( j = 0; j < oszlop; ++j )

    soratl[ i ] += t[ i * oszlop + j ];soratl[ i ] /= oszlop;

    }}

    1.38. feladat. rjon eljrst, amely egy paramterknt megkapott, egszeket tartalmaz ktdimen-zis tmb oszlopait gy rendezi t, hogy az els sor elemei nagysg szerint cskken sorrendbenlegyenek! Feltehetjk, hogy az els sor elemei klnbzek.

    A feladatot tbbfle mdon is meg lehet oldani, itt buborkrendezssel rendeztk a tmb els sornakelemeit:

    void csokelsosor( int *a, int sor, int oszlop ){

    int korlat = oszlop - 1, t;do{

    int j;t = -1;for ( j = 0; j < korlat; ++j )

    i f ( a [ j ] < a [ j + 1 ] ){

    int i;for ( i = 0; i < sor; ++i ) /* az oszlopok minden elemt cserljk */{

    int seged = a[ i * oszlop + j ];a[ i * oszlop + j ] = a[ i * oszlop + j + 1 ];a[ i * oszlop + j + 1 ] = seged;

    }t = j ;

    }korlat = t;

    } while ( t != -1 );}

    1.39. feladat. rjon eljrst, amely egy paramterknt megkapott, tetszleges mret, valsakat tar-talmaz ktdimenzis tmb sorait gy rendezi t, hogy az utols oszlop rtkei cskken sorrendbenlegyenek!

  • 8/2/2019 programozas-peldatar

    32/109

    30 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    A feladatot tbbfle mdon is meg lehet oldani, itt maximumkivlasztsos rendezssel rendeztk a tmbutols oszlopnak elemeit:

    void atrendez( double *t, int sor, int oszlop ){

    int i;

    for ( i = 0; i < sor - 1; ++i ){

    int j, k, index = i;for ( k = i + 1; k < sor; ++k )

    if ( t[ index * oszlop + oszlop - 1 ] < t[ k * oszlop + oszlop - 1 ] )index = k;

    for ( j = 0; j < oszlop; ++j ) /* a sorok minden elemt cserljk */{

    double seged = t[ index * oszlop + j ];t[ index * oszlop + j ] = t[ i * oszlop + j ];t[ i * oszlop + j ] = seged;

    }

    }}

    1.40. feladat. rjon eljrst, amely egy paramterknt megkapott, tetszleges mret, egszeket tar-talmaz ktdimenzis tmb oszloptlagai kzl meghatrozza a legnagyobbat (tbb ilyen is lehet)!Az eljrs nem rhat kpernyre s llomnyba!

    Vegyk szre, hogy a feladat megfogalmazsa csalafinta: hiba van esetleg tbb azonos legnagyobboszloptlag, az eljrsnak csak ezek egyikt, egyetlen rtket kell meghatroznia.

    A feladat tbbflekppen is megoldhat.

    (a) Lssuk elszr azt a megoldst, amikor az eljrs egy globlis vltozban hatrozza meg a keresett(legnagyobb) oszloptlagot:

    double atlag;

    void atlagol( int *t, int sor, int oszlop ){

    int i, j;atlag = 0.0;for ( i = 0; i < sor; ++i )

    atlag += t[ i * oszlop ];for ( j = 1; j < oszlop; ++j ){

    double seged = 0.0;for ( i = 0; i < sor; ++i )

    seged += t[ i * oszlop + j ];if ( seged > atlag )

    atlag = seged;}atlag /= sor;

    }

    (b) Egy msik megoldsi lehetsg, ha az eljrsnak tadunk mg egy paramtert, annak a memria-terletnek a cmt, ahol a keresett tlagrtket trolni szeretnnk:

    void atlagol( int *t, int sor, int oszlop, double *atlag ){

    int i, j;*atlag = 0.0;for ( i = 0; i < sor; ++i )

  • 8/2/2019 programozas-peldatar

    33/109

    1.4. KTDIMENZIS TMBK 31

    *atlag += t[ i * oszlop ];for ( j = 1; j < oszlop; ++j ){

    double seged = 0.0;for ( i = 0; i < sor; ++i )

    seged += t[ i * oszlop + j ];if ( seged > *atlag )

    *atlag = seged;}*atlag /= sor;

    }

    1.41. feladat. rjon fggvnyt, amely paramterknt megkap egy tetszleges mret, egszekettartalmaz kvadratikus mtrixot, s visszaadja a ftl maximlis s minimlis elemt. A kper-nyre nem runk!

    typedef struct{

    int max, min;} MAXMIN;

    MAXMIN foatlo( int *m, int meret ){

    MAXMIN mm = { *m, *m };int i;for ( i = 1; i < meret; ++i )

    if ( m[ i * ( meret + 1 ) ] > mm.max ) mm.max = m[ i * ( meret + 1 ) ];

    else if ( m[ i * ( meret + 1 ) ] < mm.min ) mm.min = m[ i * ( meret + 1 ) ];

    return mm;

    }

    1.42. feladat. rjon fggvnyt, amely paramterknt megkap egy tetszleges mret, valsakattartalmaz ktdimenzis tmbt, s visszatrsi rtkknt meghatrozza a sorok tlagnak mini-mumt s az oszlopok tlagnak maximumt.

    typedef struct { double min, max; } MINMAX;

    MINMAX sorminoszmax( double *m, int sor, int oszlop ){

    MINMAX mm;int i, j;

    for ( i = 0; i < sor; ++i ){double osszeg = 0;for ( j = 0; j < oszlop; ++j )

    osszeg += m[ i * oszlop + j ];if ( i == 0 || osszeg < mm.min )

    mm.min = osszeg;}

    mm.min /= oszlop;for ( j = 0; j < oszlop; ++j ){

    double osszeg = 0;for ( i = 0; i mm.max )

    mm.max = osszeg;

  • 8/2/2019 programozas-peldatar

    34/109

    32 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    } mm.max /= sor;return mm;

    }

    1.43. feladat. rjon eljrst, amely egy paramterknt megkapott, egszeket tartalmaz ktdimen-

    zis tmbben meghatrozza azon oszlopok indext (akrhny ilyen lehet), amelyekben a negatv elemekszma legalbb ktszerese a nulla rtk elemek szmnak! A tmb mrete tetszleges.

    A feladat tbbflekppen is megoldhat.

    (a) Elszr is lssuk azt a megoldst, amely kt globlis vltozt hasznl: egyik a felttelnek megfele-l oszlopok darabszmt fogja tartalmazni, a msik pedig arra a memriaterletre mutat, ahol akeresett oszlopindexeket troljuk.

    #include

    int *dupneg;int darab;

    void negketszer( int *t, int sor, int oszlop ){

    int j;dupneg = NULL;darab = 0;for ( j = 0; j < oszlop; ++j ){

    int i, negativ = 0, nulla = 0;for ( i = 0; i < sor; ++i )

    if ( t[ i * oszlop + j ] < 0 )++negativ;

    else if ( t[ i * oszlop + j ] == 0 )

    ++nulla;if ( negativ >= 2 * nulla ){

    dupneg = ( int * )realloc( dupneg, darab + 1 );dupneg[ darab++ ] = j;

    }}

    }

    (b) Az eljrs termszetesen paramterlistn keresztl is kommuniklhat a hv programegysggel.Ekkor a megolds a kvetkez lehet:

    #include

    void negketszer( int *t, int sor, int oszlop, int *darab, int **dupneg ){

    int j;*dupneg = NULL;*darab = 0;for ( j = 0; j < oszlop; ++j ){

    int i, negativ = 0, nulla = 0;for ( i = 0; i < sor; ++i )

    if ( t[ i * oszlop + j ] < 0 )++negativ;

    else if ( t[ i * oszlop + j ] == 0 )++nulla;

    if ( negativ >= 2 * nulla )

  • 8/2/2019 programozas-peldatar

    35/109

    1.4. KTDIMENZIS TMBK 33

    {*dupneg = ( int * )realloc( *dupneg, *darab + 1 );( *dupneg )[ ( *darab )++ ] = j;

    }}

    }

    (c) lljon itt vgl az a megoldst, amely egy globlis mutatval dolgozik: a mutat egy olyan memria-terletre mutat, amelynek els eleme az ezt kvet elemek (a keresett oszlopindexek) darabszmtadja meg.

    #include

    int *dupneg;

    void negketszer( int *t, int sor, int oszlop ){

    int j;dupneg = ( int * )malloc( sizeof( int ) );*dupneg = 0;for ( j = 0; j < oszlop; ++j ){

    int i, negativ = 0, nulla = 0;for ( i = 0; i < sor; ++i )

    if ( t[ i * oszlop + j ] < 0 )++negativ;

    else if ( t[ i * oszlop + j ] == 0 )++nulla;

    if ( negativ >= 2 * nulla ){

    dupneg = ( int * )realloc( dupneg, *dupneg + 2 );

    dupneg[ ++*dupneg ] = j;}

    }}

    1.44. feladat. rjon eljrst, amely egy paramterknt megadott ktdimenzis, egszeket tartalma-z tmb azon oszlopt hatrozza meg, amelyben benne van az egsz tmb legnagyobb eleme (csak egyilyen van)!

    #include #include

    void legoszlop( int *t, int sor, int oszlop, int **oszl )

    {int i, j, maxelem = *t, maxoszlop = 0;*oszl = ( int * )malloc( sor * sizeof( int ) );for ( i = 0; i < sor; ++i )

    for ( j = 0; j < oszlop; ++j )if ( t[ i * oszlop + j ] > maxelem ){

    maxelem = t[ i * oszlop + j ]; maxoszlop = j;

    }for ( i = 0; i < sor; ++i )

    ( *oszl )[ i ] = t[ i * oszlop + maxoszlop ];

    }1.45. feladat. rjon egy eljrst, amely egy paramterknt megkapott, tetszleges mret, egsze-ket tartalmaz kvadratikus mtrix ftljban elhelyezi soronknt a ftl fltti elemek sszegt!

  • 8/2/2019 programozas-peldatar

    36/109

    34 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    #include

    void atlossz( int *t, int meret ){

    int j;for ( j = 0; j < meret; ++j ){

    int i;t[ j * meret + j ] = 0;for ( i = 0; i < j; ++i )

    t[ j * meret + j ] += t[ i * meret + j ];}

    }

    1.46. feladat. rjon eljrst, amely egy paramterknt megkapott, egszeket tartalmaz, tetszle-ges mret ktdimenzis tmb minden olyan elemnek a 0 rtket adja, amelynek a tmb elemeinektlagtl val eltrse az tlag felnl nagyobb! Az eredeti tmbt vltozatlanul kell hagyni.

    #include

    #include

    void nullaz( int *t, int sor, int oszlop, int **ujtomb ){

    *ujtomb = ( int * )malloc( sor * oszlop * sizeof( int ) );int i, j;double atlag;for ( i = 0; i < sor; ++i )

    for ( j = 0; j < oszlop; ++j )atlag += t[ i * oszlop + j ];

    atlag /= sor * oszlop;for ( i = 0; i < sor; ++i )

    for ( j = 0; j < oszlop; ++j )if ( fabs( t[ i * oszlop + j ] - atlag ) > atlag / 2 )( *ujtomb )[ i * oszlop + j ] = 0;

    else( *ujtomb )[ i * oszlop + j ] = t[ i * oszlop + j ];

    }

    1.5. Fk

    1.47. feladat. rjon logikai fggvnyt, amely egy paramterknt megkapott, egszeket tartalmaz,szigor rtelemben vett binris frl eldnti, hogy tkletesen kiegyenslyozott-e!

    typedef struct faelem{

    int adat;struct faelem *bal, *jobb;

    } FAELEM;

    int elemszam( FAELEM *fa ){

    return fa ? elemszam( fa->bal ) + elemszam( fa->jobb ) + 1 : 0;}

    int tokkiegy( FAELEM *fa ){

    return !fa || tokkiegy( fa->bal ) && tokkiegy( fa->jobb) &&abs( elemszam( fa->bal ) - elemszam( fa->jobb ) )

  • 8/2/2019 programozas-peldatar

    37/109

    1.5. FK 35

    1.48. feladat. rjon egy eljrst, amely egy paramterknt megkapott, karaktereket tartalmaz bi-nris fban a kisbetket nagybetre cserli!

    #include

    typedef struct faelem

    {char kar;struct faelem *bal, *jobb;

    } FAELEM;

    void nagybetu( FAELEM *fa ){

    if ( fa ){

    fa->kar = toupper( fa->kar );nagybetu( fa->bal );nagybetu( fa->jobb );

    }}

    1.49. feladat. Adva van egy tetszleges egszeket tartalmaz binris fa. rjon fggvnyt, amelyparamterknt megkapja a binris fa gykrmutatjt, a fban elhelyezett rtkekbl felpt egy kere-sft, s visszaadja annak gykrmutatjt! Az j fa elemeinek szerkezete: kulcs (a klnbz egszrtkek), gyakorisg (az eredeti fban az adott kulcs hnyszor fordult el).

    #include

    typedef struct binfa {int ertek;struct binfa *bal, *jobb;

    } BINFA;

    typedef struct keresofa {int kulcs;int gyakorisag;struct keresofa *bal, *jobb;

    } KERESOFA;

    KERESOFA *keresofa_bovit( KERESOFA *k, int ertek ){

    if ( !k ){

    k = ( KERESOFA * )calloc( 1, sizeof( KERESOFA ) );k->kulcs = ertek;k->gyakorisag = 1;

    }else if ( k->kulcs > ertek )

    k->bal = keresofa_bovit( k->bal, ertek );else if ( k->kulcs < ertek )

    k->jobb = keresofa_bovit( k->jobb, ertek );else

    k->gyakorisag++;return k;

    }

    KERESOFA *binfa_inorder( KERESOFA *k, BINFA *b ){

    i f ( b )

  • 8/2/2019 programozas-peldatar

    38/109

    36 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    {k = binfa_inorder( k, b->bal );k = keresofa_bovit( k, b->ertek );k = binfa_inorder( k, b->jobb );

    }return k;

    }

    KERESOFA *keresofa_epito( BINFA *b ){

    return binfa_inorder( NULL, b );}

    1.50. feladat. rjon eljrst, amely egy paramterknt megkapott, egszeket tartalmaz keres-fbl kitrl egy szintn paramterknt megadott rtket! Az eljrs rjon megfelel hibazenetet akpernyre, ha a trls valamilyen okbl nem hajthat vgre!

    Egy elem trlsnl a kvetkez lehetsgek fordulhatnak el:

    A trlend elem nincs benne a keresfban. Ekkor hibazenetet kell a kpernyre rni.

    A trlend elem levlelem, azaz nincs egyetlen rkvetkezje sem.

    A trlend elemnek csak egy rkvetkezje van.

    A trlend elemnek kt rkvetkezje van.

    A fentieket figyelembe vve a feladat rekurzvan s iteratvan is megoldhat. Az albbiakban hrommegoldst adunk meg.

    (a) Az els megolds rekurzvan oldja meg a feladatot. Egy kln rekurzv eljrsban kezeltk benneazt az esetet, amikor a trlend elemnek kt rkvetkezje van.

    #include #include

    typedef struct faelem {int adat;struct faelem *bal, *jobb;

    } FAELEM;

    void torol_2rakov( FAELEM *torlendo, FAELEM **legjobb ){

    if( ( *legjobb )->jobb )torol_2rakov( torlendo, &( *legjobb )->jobb );

    else{FAELEM *seged = *legjobb;torlendo->adat = ( *legjobb )->adat;*legjobb = ( *legjobb )->bal;free( seged );

    }}

    void torol( FAELEM **gym, int ertek ){

    if( !*gym )fputs( "Nincs ilyen rtk a fban!\n", stderr );

    else if( ( *gym )->adat != ertek )torol( ( *gym )->adat < ertek ? &( *gym )->jobb : &( *gym )->bal, ertek );

    else if( !( *gym )->bal || !( *gym )->jobb )

  • 8/2/2019 programozas-peldatar

    39/109

    1.5. FK 37

    {FAELEM *torlendo = *gym;*gym = ( *gym )->bal ? ( *gym )->bal : ( *gym )->jobb;free( torlendo );

    }else

    torol_2rakov( *gym, &( *gym )->bal );}

    (b) Msodikknt lssuk az iteratv megoldst:

    #include #include

    typedef struct faelem {int adat;struct faelem *bal, *jobb;

    } FAELEM;

    void torol( FAELEM **gym, int ertek ){

    FAELEM *akt = *gym, *szulo = NULL;while ( akt != NULL && akt->adat != ertek ){

    szulo = akt;akt = akt->adat > ertek ? akt->bal : akt->jobb;

    }if ( !akt )

    fputs( "Nincs ilyen rtk a fban!\n", stderr );else if ( !akt->bal || !akt->jobb ){

    if( !szulo )*gym = akt->bal ? akt->bal : akt->jobb;

    else if ( akt->adat < szulo->adat )szulo->bal = akt->bal ? akt->bal : akt->jobb;

    elseszulo->jobb = akt->bal ? akt->bal : akt->jobb;

    free( akt );}else{

    FAELEM *seged = akt->jobb;szulo = akt;

    while ( seged->bal ){szulo = seged;seged = seged->bal;

    }if ( szulo != akt )

    szulo->bal = seged->jobb;else

    szulo->jobb = seged->jobb;akt->adat = seged->adat;free( seged );

    }}

    (c) Vgl lljon itt egy olyan rekurzv megolds, amely iteratv elemeket is tartalmaz (azoknl azelemeknl, amelyeknek kt rkvetkezjk is van):

  • 8/2/2019 programozas-peldatar

    40/109

    38 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    #include #include

    typedef struct faelem {int adat;struct faelem *bal, *jobb;

    } FAELEM;

    void torol( FAELEM **gym, int ertek ){

    if( !*gym )fputs( "Nincs ilyen rtk a fban!\n", stderr );

    else if( ( *gym )->adat != ertek )torol( ( *gym )->adat < ertek ? &( *gym )->jobb : &( *gym )->bal, ertek );

    else if( !( *gym )->bal || !( *gym )->jobb ){

    FAELEM *torlendo = *gym;*gym = ( *gym )->bal ? ( *gym )->bal : ( *gym )->jobb;

    free( torlendo );}else{

    FAELEM *seged = ( *gym )->jobb;while ( seged->bal )

    seged = seged->bal;( *gym )->adat = seged->adat;torol( &( *gym )->jobb, seged->adat );

    }}

    1.6. Kifejezsek1.51. feladat. rjon fggvnyt, amely paramterknt egy olyan sztringet kap, amely egy szablyos,teljesen zrjelezett infix kifejezst tartalmaz, s meghatrozza a kifejezs fjnak magassgt! Akifejezsben csak a +, , , / binris opertorok s maximum 3 jegy egsz szm operandusok fordulnakel.

    int infixmagas( char *s ){

    int magas = 1, max = 0;while ( *s ){

    if ( *s == ( )

    ++magas;else if ( *s == ) )

    --magas;if ( magas > max )

    max = magas;s++;

    }return max;

    }

    1.52. feladat. rjon programot, amely billentyzetrl beolvas egy szablyos, teljesen zrjele-zett C kifejezst, amely operandusknt csak konstansokat s vltozkat tartalmaz, s a kpernyre

    rja azt a rszkifejezst, amelyet elszr kell kirtkelni!#include

  • 8/2/2019 programozas-peldatar

    41/109

    1.6. KIFEJEZSEK 39

    main(){

    char kif[ 200 ], *p;printf( "Krem a kifejezst: " ); gets( kif );for ( p = kif; *p && *p != ); ++p )

    ;if ( *p ){

    while ( *--p != ( );

    while ( *++p != ) )putchar( *p );

    putchar( \n );}else

    puts( kif );}

    1.53. feladat.

    rjon programot, amely billentyzetrl megkap egy szablyos prefix alak kifejezst.A program rja kpernyre az elsnek kirtkelent rszkifejezst infix alakban! A kifejezs csak a +,, , / ktoperandus opertorokat s operandusknt olyan vltozkat tartalmaz, amelyek neve egyetlenkarakterbl ll.

    #include #include #include

    #define FALSE 0#define TRUE !FALSE

    main()

    { char *op = "+-*/", kif[ 3 ];int megvan = FALSE, ch;while ( ( ch = getchar() ) != EOF )

    if ( !megvan && !isspace( ch ) ){

    kif[ 0 ] = kif[ 1 ];kif[ 1 ] = kif[ 2 ];kif[ 2 ] = ch;if ( !strchr( op, kif[ 1 ] ) && !strchr( op, kif[ 2 ] ) )

    megvan = TRUE;}

    if ( megvan )printf( "%c%c%c\n", kif[ 1 ], kif[ 0 ], kif[ 2 ] );

    elseprintf( "%c\n", kif[ 2 ] );

    }

    1.54. feladat. Adott egy csak a +, -, /, * binris opertorokat tartalmaz szablyos kifejezs fjnakpostorder bejrsval kapott sorozat. Az opertorokat s az operandusokat egy szkz vlasztja elegymstl. A sorozatot billentyzetrl kapjuk. rjon programot, amely kpernyre rja a kifejezsprefix alakjt!

    #include #include #include

    typedef struct faelem{

  • 8/2/2019 programozas-peldatar

    42/109

    40 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    char *op;struct faelem *bal, *jobb;

    } FAELEM;

    typedef struct veremelem{

    FAELEM *elem;struct veremelem *kov;

    } VEREMELEM;

    VEREMELEM *verem; /* NULL rtkkel inicializldik */

    void push( FAELEM *elem ){

    VEREMELEM *ujelem = ( VEREMELEM * ) malloc( sizeof( VEREMELEM ) );ujelem->elem = elem;ujelem->kov = verem;verem = ujelem;

    }

    FAELEM *pop(){

    FAELEM *seged = verem->elem;VEREMELEM *torlendo = verem;verem = verem->kov;free( torlendo );return seged;

    }

    void preorder( FAELEM *gyoker ){

    if ( gyoker ){

    printf( "%s ", gyoker->op );free( gyoker->op );preorder( gyoker->bal );preorder( gyoker->jobb );free( gyoker );

    }}

    main(){

    char kif[ 256 ];puts( "Krem a postfix kifejezst:" );while ( scanf( "%s", kif ) != EOF ){

    FAELEM *uj = ( FAELEM * )malloc( sizeof( FAELEM ) );uj->op = ( char * )malloc( ( strlen( kif ) + 1 ) * sizeof( char ) );strcpy( uj->op, kif );if ( strlen( kif ) == 1 && strchr( "+-*/", *kif ) ){

    uj->jobb = pop();uj->bal = pop();

    }

    elseuj->bal = uj->jobb = NULL;push( uj );

  • 8/2/2019 programozas-peldatar

    43/109

    1.6. KIFEJEZSEK 41

    }preorder( pop() );putchar( \n );

    }

    1.55. feladat. rjon programot, amely billentyzetrl beolvas egy olyan teljesen zrjelezett

    kifejezst, mely csak a +, , , / opertorokat s olyan vltoz operandusokat tartalmaz, amelyeknevben csak bet szerepel! Tudjuk, hogy a kifejezsben zrjelhiba van. A program rja kpernyrea kifejezst, s jellje meg a hiba helyt!

    A feladat tbbflekppen is megoldhat.

    (a) Az els megoldsban karakterenknt vgighaladunk a kifejezsen, s minden karakterrl eldntjk,hogy llhat-e az adott helyen. A szkzket tugorva, a vizsglt s az azt megelz karakter alapjnlltjuk be a hiba vltoz rtkt, ha kell.

    #include #include #include

    typedef enum{ OK, OPERANDUS, OPERATOR, NYITO, ZARO, ERVENYTELEN, SOKZARO, KEVESZARO }HIBAOK;

    char operatorok[] = "+-*/";

    main(){

    int zarojel = 0, operandus[ 1000 ] = { 0 }, i = 0;HIBAOK hiba = OK;char kif[ 1000 ], elozo = \0;;printf( "A kifejezs: " );fgets( kif, 1000, stdin );

    while ( kif[ i ] != \n && kif[ i ] != \0 ){

    while ( kif[ i ] == || kif[ i ] == \t )++i;

    if ( isalpha( kif[ i ] ) ){

    if ( isalpha( elozo ) || elozo == ) ){

    hiba = OPERANDUS;break;

    }elozo = kif[ i ];

    while ( isalpha( kif[ i ] ) )++i;++operandus[ zarojel ];

    }else if ( strchr( operatorok, kif[ i ] ) ){

    if ( strchr( operatorok, elozo ) || elozo == ( ||operandus[ zarojel ] == 2 || zarojel == 0 )

    {hiba = OPERATOR;break;

    }elozo = kif[ i++ ];

    }else if ( kif[ i ] == ( ){

  • 8/2/2019 programozas-peldatar

    44/109

    42 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    if ( isalpha( elozo ) || elozo == ) ){

    hiba = NYITO;break;

    }operandus[ ++zarojel ] = 0;elozo = kif[ i++ ];

    }else if ( kif[ i ] == ) ){

    if ( strchr( operatorok, elozo ) || elozo == ( ){

    hiba = ZARO;break;

    }if ( --zarojel < 0 ){

    hiba = SOKZARO;

    break;}++operandus[ zarojel ];elozo = kif[ i++ ];

    }else{

    hiba = ERVENYTELEN;break;

    }}puts( kif );if ( hiba == OK && zarojel > 0 )

    hiba = KEVESZARO;if ( hiba == OK )

    puts( "Nincs hiba a kifejezsben." );else{

    int j;for ( j = 0; j < i; ++j )

    putchar( );printf( "^\n" );switch ( hiba ){

    case OPERANDUS:

    puts( "Itt nem llhat operandus!" );break;

    case OPERATOR:puts( "Itt nem llhat opertor!" );break;

    case NYITO:puts( "Itt nem llhat nyit zrjel!" );break;

    case ZARO:puts( "Itt nem llhat zr zrjel!" );break;

    case ERVENYTELEN:

    puts( "rvnytelen karakter!" );break;case SOKZARO:

  • 8/2/2019 programozas-peldatar

    45/109

    1.6. KIFEJEZSEK 43

    puts( "Tl sok a zr zrjel!" );break;

    case KEVESZARO:puts( "Hinyz zr zrjel!" );break;

    }}

    }

    (b) A kvetkez megoldsban llapottmenet-grfot hasznltunk a kifejezs feldolgozsra.

    #include #include #include #include

    #define HIBA 100#define VEGE 101

    enum { KEZDO, OPERATOR, OPERANDUS, NYITO, ZARO, PARATLANZARO, ERVENYTELEN,BETU, NYITOVEG, OPERANDUSVEG, OPERATORVEG, KETOPERATOR, HIANYZOZARO,SOKOPERATOR };

    main(){

    char kif[ 1000 ];int i, allapot = 1, muvjel, *verem = NULL, darab = 0, hibakod = -1;

    printf( "A kifejezs: " ); fgets( kif, 1000, stdin );

    if ( kif[ strlen( kif ) - 1 ] == \n )

    kif[ strlen( kif ) - 1 ] = \0;

    i = 0 ;while ( allapot != VEGE ){

    char ch = kif[ i ];switch ( allapot ){

    case 1: if ( ch == \0 )allapot = VEGE;

    else if ( isspace( ch ) )putchar( ch );

    else if ( isalpha( ch ) || ch == _ ){putchar( ch );allapot = 2;

    }else if ( ch == ( ){

    putchar( ch ); muvjel = 0;allapot = 4;

    }else{

    printf( "%c", ch );hibakod = KEZDO;allapot = HIBA;

  • 8/2/2019 programozas-peldatar

    46/109

    44 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    }break;

    case 2: if ( ch == \0 )allapot = VEGE;

    else if ( isalpha( ch ) || ch == _ )putchar( ch );

    else if ( isspace( ch ) ){

    putchar( ch );allapot = 3;

    }else{

    printf( "%c", ch );if ( strchr( "+-*/", ch ) )

    hibakod = OPERATOR;else if ( ch == ( )

    hibakod = NYITO;

    else if ( ch == ) )hibakod = ZARO;

    elsehibakod = ERVENYTELEN;

    allapot = HIBA;}break;

    case 3: if ( ch == \0 )allapot = VEGE;

    else if ( isspace( ch ) )putchar( ch );

    else{

    printf( "%c", ch );if ( strchr( "+-*/", ch ) )

    hibakod = OPERATOR;else if ( ch == ( )

    hibakod = NYITO;else if ( ch == ) )

    hibakod = PARATLANZARO;else if ( isalpha( ch ) || ch == _ )

    hibakod = BETU;else

    hibakod = ERVENYTELEN;allapot = HIBA;

    }break;

    case 4: if ( ch == \0 ){

    printf( "" );hibakod = NYITOVEG;allapot = VEGE;

    }else if ( isspace( ch ) )

    putchar( ch );else if ( ch == ( ){

    putchar( ch );++darab;verem = ( int * )realloc( verem, darab * sizeof( int ) );

  • 8/2/2019 programozas-peldatar

    47/109

    1.6. KIFEJEZSEK 45

    verem[ darab - 1 ] = muvjel;}else if ( isalpha( ch ) || ch == _ ){

    putchar( ch );allapot = 5;

    }else{

    printf( "%c", ch );if ( ch == ) )

    hibakod = ZARO;else if ( strchr( "+-*/", ch ) )

    hibakod = OPERATOR;else

    hibakod = ERVENYTELEN;allapot = HIBA;

    }

    break;case 5: if ( ch == \0 )

    {printf( "" );hibakod = OPERANDUSVEG;allapot = VEGE;

    }else if ( isalpha( ch ) || ch == _ )

    putchar( ch );else if ( isspace( ch ) ){

    putchar( ch );allapot = 6;

    }else if ( strchr( "+-*/", ch ) != NULL ){

    putchar( ch ); muvjel = 1;allapot = 7;

    }else{

    printf( "%c", ch );if ( ch == ( )

    hibakod = NYITO;

    else if ( ch == ) )hibakod = ZARO;

    elsehibakod = ERVENYTELEN;

    allapot = HIBA;}break;

    case 6: if ( ch == \0 ){

    printf( "" );hibakod = OPERANDUSVEG;allapot = VEGE;

    }else if ( isspace( ch ) )putchar( ch );

  • 8/2/2019 programozas-peldatar

    48/109

    46 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    else if ( strchr( "+-*/", ch ) != NULL ){

    putchar( ch ); muvjel = 1;allapot = 7;

    }else{

    printf( "%c", ch );if ( isalpha( ch ) || ch == _ )

    hibakod = OPERANDUS;else if ( ch == ( )

    hibakod = NYITO;else if ( ch == ) )

    hibakod = ZARO;else

    hibakod = ERVENYTELEN;allapot = HIBA;

    }break;

    case 7: if ( ch == \0 ){

    printf( "" );hibakod = OPERATORVEG;allapot = VEGE;

    }else if ( ch == ( ){

    putchar( ch );++darab;verem = ( int * )realloc( verem, darab * sizeof( int ) );verem[ darab - 1 ] = muvjel;allapot = 4;

    }else if ( isspace( ch ) )

    putchar( ch );else if ( isalpha( ch ) || ch == _ ){

    putchar( ch );allapot = 8;

    }else{

    printf( "%c", ch );if ( ch == ) )

    hibakod = ZARO;else if ( strchr( "+-*/", ch ) )

    hibakod = KETOPERATOR;else

    hibakod = ERVENYTELEN;allapot = HIBA;

    }break;

    case 8: if ( ch == \0 ){

    printf( "" );hibakod = HIANYZOZARO;allapot = VEGE;

  • 8/2/2019 programozas-peldatar

    49/109

    1.6. KIFEJEZSEK 47

    }else if ( isalpha( ch ) || ch == _ )

    putchar( ch );else if ( isspace( ch ) ){

    putchar( ch );allapot = 9;

    }else if ( ch == ) ){

    putchar( ch );if ( verem != NULL ){

    muvjel = verem[ darab - 1 ];--darab;verem = ( int * )realloc( verem, darab * sizeof( int ) );allapot = muvjel ? 9 : 6;

    }

    elseallapot = 3;

    }else{

    printf( "%c", ch );if ( strchr( "+-*/", ch ) )

    hibakod = SOKOPERATOR;else if ( ch == ( )

    hibakod = NYITO;else

    hibakod = ERVENYTELEN;allapot = HIBA;

    }break;

    case 9: if ( ch == \0 ){

    printf( "" );hibakod = HIANYZOZARO;allapot = VEGE;

    }else if ( isspace( ch ) )

    putchar( ch );else if ( ch == ) ){

    putchar( ch );if ( verem != NULL ){

    muvjel = verem[ darab - 1 ];--darab;verem = ( int * )realloc( verem, darab * sizeof( int ) );if ( muvjel == 0 )

    allapot = 6;}else

    allapot = 3;}

    else{printf( "%c", ch );

  • 8/2/2019 programozas-peldatar

    50/109

    48 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    if ( strchr( "+-*/", ch ) )hibakod = SOKOPERATOR;

    else if ( ch == ( )hibakod = NYITO;

    else if ( isalpha( ch ) || ch == _ )hibakod = OPERANDUS;

    elsehibakod = ERVENYTELEN;

    allapot = HIBA;}break;

    case HIBA: if ( ch == \0 )allapot = VEGE;

    elseputchar( ch );

    break;}++i;

    }putchar( \n );

    switch ( hibakod ){

    case KEZDO: puts( "Szablytalan kezdkarakter." );break;

    case OPERATOR: puts( "Itt nem llhat opertor." );break;

    case OPERANDUS: puts( "Itt nem llhat operandus." );break;

    case NYITO: puts( "Itt nem llhat nyit zrjel." );break;

    case ZARO: puts( "Itt nem llhat zr zrjel." );break;

    case PARATLANZARO: puts( "Nincs nyit prja ennek a zr zrjelnek." );break;

    case ERVENYTELEN: puts( "rvnytelen karakter." );break;

    case BETU: puts( "Itt nem llhat bet." );break;

    case NYITOVEG: puts( "A kifejezs nem vgzdhet nyit zrjellel." );break;

    case OPERANDUSVEG: puts( "Flbehagyott kifejezs, hinyz opertor." );break;

    case OPERATORVEG: puts( "Flbehagyott kifejezs, hinyz operandus." );break;

    case KETOPERATOR: puts( "Kt opertor nem llhat egyms mellett." );break;

    case HIANYZOZARO: puts( "Hinyz zr zrjel." );break;

    case SOKOPERATOR: puts( "Itt nem llhat jabb opertor." );break;

    default: puts( "Szablyos." );break;

    }

    free( verem );}

  • 8/2/2019 programozas-peldatar

    51/109

    1.6. KIFEJEZSEK 49

    1.56. feladat. rjon programot, amely billentyzetrl megkap egy olyan teljesen zrjelezettkifejezst, amely csak a s a + egy- s ktoperandus opertorokat, operandusknt pedig olyan C-beli vltozkat tartalmaz, melyek neve maximum kt karakterbl ll. Ellenrizze le, hogy a kifejezsszablyos-e. A kpernyre rjon rtelemszer hibazeneteket.

    A feladat tbbflekppen is megoldhat.

    (a) A kvetkez program egy krnyezetfggetlen generatv grammatika segtsgvel eldnti, hogy akifejezs szablyos-e vagy sem. Az algoritmus meglehetsen lass (elssorban hossz kifejezsekesetn).

    #include #include #include #include

    #define MERET 1000

    char minta[ MERET + 1 ];int szabalyos;

    void keres( char *s ){

    int i;if ( !strcmp( s, minta ) )

    szabalyos = 1;for ( i = 0; i < strlen( s ); ++i ){

    if ( s[ i ] == S ){

    char uj[ MERET + 1 ];

    /* S -> b szably */strcpy( uj, s );uj[ i ] = b;keres( uj );/* S -> S_ szably */if ( strlen( s ) < strlen( minta ) ){

    strncpy( uj, s, i + 1 );uj[ i + 1 ] = \0;strcat( uj, " " );strcat( uj, s + i + 1 );keres( uj );

    }/* S -> _S szably */if ( strlen( s ) < strlen( minta ) ){

    strncpy( uj, s, i );uj[ i ] = \0;strcat( uj, " " );strcat( uj, s + i );keres( uj );

    }/* S -> bA szably */if ( strlen( s ) < strlen( minta ) ){

    strncpy( uj, s, i );uj[ i ] = \0;strcat( uj, "bA" );

  • 8/2/2019 programozas-peldatar

    52/109

    50 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    strcat( uj, s + i + 1 );keres( uj );

    }/* S -> (MS) szably */if ( strlen( s ) + 2 < strlen( minta ) ){

    strncpy( uj, s, i );uj[ i ] = \0;strcat( uj, "(MS)" );strcat( uj, s + i + 1 );keres( uj );

    }/* S -> (SmS) szably */if ( strlen( s ) + 3 < strlen( minta ) ){

    strncpy( uj, s, i );uj[ i ] = \0;strcat( uj, "(SmS)" );

    strcat( uj, s + i + 1 );keres( uj );

    }}else if ( s[ i ] == A ){

    char uj[ MERET + 1 ];/* A -> b szably */strcpy( uj, s );uj[ i ] = b;keres( uj );/* A -> s szably */strcpy( uj, s );uj[ i ] = s;keres( uj );

    }else if ( s[ i ] == M ){

    char uj[ MERET + 1 ];/* M -> _M szably */if ( strlen( s ) < strlen( minta ) ){

    strncpy( uj, s, i );uj[ i ] = \0;strcat( uj, " " );

    strcat( uj, s + i );keres( uj );

    }/* M -> m szably */strcpy( uj, s );uj[ i ] = m;keres( uj );

    }}

    }

    main()

    { char kif[ MERET + 1 ], szo[ MERET + 1 ];int i;

  • 8/2/2019 programozas-peldatar

    53/109

    1.6. KIFEJEZSEK 51

    printf( "A kifejezs: " ); gets( kif );

    for ( i = 0; i < strlen( kif ); ++i )if ( kif[ i ] == ( || kif[ i ] == ) )

    minta[ i ] = kif[ i ];else if ( isspace( kif[ i ] ) )

    minta[ i ] = ;else if ( isalpha( kif[ i ] ) || kif[ i ] == _ )

    minta[ i ] = b;else if ( isdigit( kif[ i ] ) )

    minta[ i ] = s;else if ( kif[ i ] == + || kif[ i ] == - )

    minta[ i ] = m;else

    minta[ i ] = x; minta[ i ] = \0;

    strcpy( szo, "S" );

    szabalyos = 0;keres( szo );printf( "kifejezs: *%s*\n", kif );printf( "minta: *%s*\n", minta );if ( szabalyos )

    puts( "A kifejezs szablyos." );else

    puts( "A kifejezs nem szablyos." );}

    (b) A msodik megoldsban a levezetsi szablyok Chomsky-fle normlalakak, gy alkalmazhatjuk

    a CockeYoungerKasami-fle algoritmust annak eldntsre, hogy a begpelt kifejezs eleme-e agrammatika ltal generlt nyelvnek.

    #include #include #include #include

    const char *szabaly[] ={ "SSK", "SKS", "SBA", "SNE", "EKE", "EMF", "FSZ", "SNG", "GSE" };

    const int meret = sizeof szabaly / sizeof( char * );

    char **tomb, n;

    void inicializal( char *s ){

    int i;n = strlen( s );tomb = ( char ** )malloc( n * ( n + 1 ) * sizeof( char * ) / 2 );f o r ( i = 0 ; i < n * ( n + 1 ) / 2 ; + + i )

    tomb[ i ] = ( char * )calloc( 1, sizeof( char ) );}

    char *get( int i, int j ){

    return tomb[ n * ( n+1 ) / 2 - ( n-i-1 ) * ( n-i ) / 2 - ( n-i-j ) ];}

  • 8/2/2019 programozas-peldatar

    54/109

    52 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    void set( int i, int j, char ch ){

    char *p = tomb[ n * ( n+1 ) / 2 - ( n-i-1 ) * ( n-i ) / 2 - ( n-i-j ) ];int hossz = strlen( p );p = ( char * )realloc( p, hossz + 2 );p[ hossz ] = ch;p[ hossz + 1 ] = \0;

    }

    void felszabadit(){

    int i;f o r ( i = 0 ; i < n * ( n + 1 ) / 2 ; + + i )

    free( tomb[ i ] );free( tomb );

    }

    main()

    {char kif[ 1000 ];int i, j, min = 0;

    printf( "A kifejezs: " ); gets( kif );

    inicializal( kif );

    for ( i = 0; i < n; ++i ){

    if ( isspace( kif[ i ] ) )set( n - 1 - i, i, K ); /* K -> space */

    else if ( kif[ i ] == ( )set( n - 1 - i, i, N ); /* N -> ( */

    else if ( kif[ i ] == ) )set( n - 1 - i, i , Z ); /* Z -> ) */

    else if ( strchr( "+-", kif[ i ] ) )set( n - 1 - i, i, M ); /* M -> {+,-} */

    else if ( isdigit( kif[ i ] ) )set( n - 1 - i, i, A ); /* A -> {szmjegy} */

    else if ( isalpha( kif[ i ] ) || kif[ i ] == _ ){

    set( n - 1 - i, i, A ); /* A -> {_,bet} */set( n - 1 - i, i, B ); /* B -> {_,bet} */set( n - 1 - i, i, S ); /* S -> {_,bet} */

    }}

    for ( i = n - 2; i >= 0; --i )for ( j = n - 2 - i; j >= 0; --j ){

    int k;f o r ( k = 1 ; k < n - i - j ; + + k ){

    int m;for ( m = 0; m < meret; ++m )

    if ( strchr( get( i + k, j ), szabaly[ m ][ 1 ] ) &&

    strchr( get( i, n - i - k ), szabaly[ m ][ 2 ] ) &&!strchr( get( i, j ), szabaly[ m ][ 0 ] ) )set( i, j, szabaly[ m ][ 0 ] );

  • 8/2/2019 programozas-peldatar

    55/109

    1.6. KIFEJEZSEK 53

    }}

    for ( i = 0; i < n; ++i )for ( j = 0; j < n - i; ++j )

    if ( strlen( get( i, j ) ) > min ) min = strlen( get( i, j ) );

    printf( "A kifejezs%s szablyos.\n", n && strchr( *tomb,S ) ? "" : " nem" );

    felszabadit();}

    (c) llapottmenet-grfot hasznlva hibs kifejezs esetn a hiba okt is meg tudjuk hatrozni.

    #include #include #include #include

    #define VEGE 100#define HIBA 101

    enum { KEZDO, OPERATOR, OPERANDUS, NYITO, ZARO, PARATLANZARO, ERVENYTELEN,BETU, NYITOVEG, SZAMJEGY, OPERANDUSVEG, OPERATORVEG, KETOPERATOR,HIANYZOZARO, SOKOPERATOR, NEMSZAM };

    main(){

    char kif[ 1000 ];int i, allapot = 1, muvjel, *verem = NULL, darab = 0, hibakod = -1;

    printf( "A kifejezs: " ); gets( kif );

    i = 0 ;while ( allapot != VEGE ){

    char ch = kif[ i ];switch ( allapot ){

    case 1: if ( ch == \0 )allapot = VEGE;

    else if ( isalpha( ch ) || ch == _ ){

    putchar( ch );

    allapot = 2;}else if ( isspace( ch ) )

    putchar( ch );else if ( ch == ( ){

    putchar( ch ); muvjel = 0;allapot = 4;

    }else{

    printf( "%c", ch );

    allapot = HIBA;hibakod = KEZDO;

    }

  • 8/2/2019 programozas-peldatar

    56/109

    54 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    break;case 2: if ( ch == \0 )

    allapot = VEGE;else if ( isspace( ch ) || isalnum( ch ) || ch == _){

    putchar( ch );allapot = 3;

    }else{

    printf( "%c", ch );switch ( ch ){

    case +: case -: hibakod = OPERATOR; break;case (: hibakod = NYITO; break;case ): hibakod = ZARO; break;default: hibakod = ERVENYTELEN; break;

    }

    allapot = HIBA;}break;

    case 3: if ( ch == \0 )allapot = VEGE;

    else if ( isspace( ch ) )putchar( ch );

    else{

    printf( "%c", ch );switch ( ch ){

    case +: case -: hibakod = OPERATOR; break;case (: hibakod = NYITO; break;case ): hibakod = PARATLANZARO; break;default:

    if ( isalnum( ch ) || ch == _ )hibakod = BETU;

    elsehibakod = ERVENYTELEN;

    break;}allapot = HIBA;

    }break;

    case 4: if ( ch == \0 ){

    printf( "" );hibakod = NYITOVEG;allapot = VEGE;

    }else if ( isspace( ch ) )

    putchar( ch );else if ( ch == ( ){

    putchar( ch );++darab;

    verem = ( int * )realloc( verem, darab * sizeof( int ) );verem[ darab - 1 ] = muvjel;}

  • 8/2/2019 programozas-peldatar

    57/109

    1.6. KIFEJEZSEK 55

    else if ( isalpha( ch ) || ch == _ ){

    putchar( ch );allapot = 5;

    }else if ( strchr( "+-", ch ) != NULL ){

    putchar( ch ); muvjel = 1;allapot = 7;

    }else{

    printf( "%c", ch );if ( ch == ) )

    hibakod = ZARO;else if ( isdigit( ch ) )

    hibakod = SZAMJEGY;

    elsehibakod = ERVENYTELEN;

    allapot = HIBA;}break;

    case 5: if ( ch == \0 ){

    printf( "" );hibakod = OPERANDUSVEG;allapot = VEGE;

    }else if ( isspace( ch ) || isalnum( ch ) || ch == _){

    putchar( ch );allapot = 6;

    }else if ( strchr( "+-", ch ) != NULL ){

    putchar( ch ); muvjel = 1;allapot = 7;

    }else{

    printf( "%c", ch );

    switch ( ch ){

    case (: hibakod = NYITO; break;case ): hibakod = ZARO; break;default: hibakod = ERVENYTELEN; break;

    }allapot = HIBA;

    }break;

    case 6: if ( ch == \0 ){

    printf( "" );

    hibakod = OPERANDUSVEG;allapot = VEGE;}

  • 8/2/2019 programozas-peldatar

    58/109

    56 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    else if ( isspace( ch ) )putchar( ch );

    else if ( strchr( "+-", ch ) != NULL ){

    putchar( ch ); muvjel = 1;allapot = 7;

    }else{

    printf( "%c", ch );switch ( ch ){

    case (: hibakod = NYITO; break;case ): hibakod = ZARO; break;default:

    if ( isalpha( ch ) || ch == _ )hibakod = OPERANDUS;

    else if ( isdigit( ch ) )hibakod = NEMSZAM;

    elsehibakod = ERVENYTELEN;

    break;}allapot = HIBA;

    }break;

    case 7: if ( ch == \0 ){

    printf( "" );hibakod = OPERATORVEG;allapot = VEGE;

    }else if ( isspace( ch ) )

    putchar( ch );else if ( ch == ( ){

    putchar( ch );++darab;verem = ( int * )realloc( verem, darab * sizeof( int ) );verem[ darab - 1 ] = muvjel;allapot = 4;

    }

    else if ( isalpha( ch ) || ch == _ ){

    putchar( ch );allapot = 8;

    }else{

    printf( "%c", ch );if ( ch == ) )

    hibakod = ZARO;else if ( isdigit( ch ) )

    hibakod = SZAMJEGY;

    else if ( strchr( "+-", ch ) )hibakod = KETOPERATOR;else

  • 8/2/2019 programozas-peldatar

    59/109

    1.6. KIFEJEZSEK 57

    hibakod = ERVENYTELEN;allapot = HIBA;

    }break;

    case 8: if ( ch == \0 ){

    printf( "" );hibakod = HIANYZOZARO;allapot = VEGE;

    }else if ( isspace( ch ) || isalnum( ch ) || ch == _ ){

    putchar( ch );allapot = 9;

    }else if ( ch == ) ){

    putchar( ch );

    if ( darab > 0 ) /* a verem nem res */{

    muvjel = verem[ --darab ];verem = realloc( verem, darab * sizeof( int ) );allapot = muvjel ? 9 : 6;

    }else

    allapot = 3;}else{

    printf( "%c", ch );switch ( ch ){

    case +: case -: hibakod = SOKOPERATOR; break;case (: hibakod = NYITO; break;default: hibakod = ERVENYTELEN; break;

    }allapot = HIBA;

    }break;

    case 9: if ( ch == \0 ){

    printf( "" );hibakod = HIANYZOZARO;

    allapot = VEGE;}else if ( isspace( ch ) )

    putchar( ch );else if ( ch == ) ){

    putchar( ch );if ( darab > 0 ) /* a verem nem res */{

    muvjel = verem[ --darab ];verem = realloc( verem, darab * sizeof( int ) );if ( !muvjel )

    allapot = 6;}else

  • 8/2/2019 programozas-peldatar

    60/109

    58 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    allapot = 3;}else{

    printf( "%c", ch );switch ( ch ){

    case (: hibakod = NYITO; break;case +: case -: hibakod = SOKOPERATOR; break;default:

    if ( isalpha( ch ) || ch == _ )hibakod = OPERANDUS;

    else if ( isdigit( ch ) )hibakod = NEMSZAM;

    elsehibakod = ERVENYTELEN;

    break;}

    allapot = HIBA;}break;

    case HIBA: if ( ch == \0 )allapot = VEGE;

    elseputchar( ch );

    break;}++i;

    }putchar( \n );

    switch ( hibakod ){

    case KEZDO: puts( "Szablytalan kezdkarakter." );break;

    case OPERATOR: puts( "Itt nem llhat opertor." );break;

    case OPERANDUS: puts( "Itt nem llhat operandus." );break;

    case NYITO: puts( "Itt nem llhat nyit zrjel." );break;

    case ZARO: puts( "Itt nem llhat zr zrjel." );break;

    case PARATLANZARO: puts( "Nincs nyit prja ennek a zr zrjelnek." );break;

    case ERVENYTELEN: puts( "rvnytelen karakter." );break;

    case BETU: puts( "Itt nem llhat bet vagy szmjegy." );break;

    case NYITOVEG: puts( "A kifejezs nem vgzdhet nyit zrjellel." );break;

    case SZAMJEGY: puts( "A vltoznv nem kezddhet szmjeggyel." );break;

    case OPERANDUSVEG: puts( "Flbehagyott kifejezs, hinyz opertor." );break;

    case OPERATORVEG: puts( "Flbehagyott kifejezs, hinyz operandus." );break;case KETOPERATOR: puts( "Kt opertor nem llhat egyms mellett." );

  • 8/2/2019 programozas-peldatar

    61/109

    1.7. LLOMNYOK 59

    break;case HIANYZOZARO: puts( "Hinyz zr zrjel." );

    break;case SOKOPERATOR: puts( "Itt nem llhat jabb opertor." );

    break;case NEMSZAM: puts( "Itt nem llhat szmjegy." );

    break;default: puts( "Szablyos." );

    break;}free( verem );

    }

    1.7. llomnyok

    1.57. feladat. rjon programot, amely angol szavakat kr be billentyzetrl *** vgjelig, s kirjaegy szveges llomnyba kzlk azokat, amelyek tartalmazzk a b, c, x, y karaktereket!

    #include #include

    main(){

    FILE *f = fopen( "ki.txt", "w" );char szo[ 100 ];scanf( "%s", szo );while ( strcmp( szo, "***" ) ){

    if ( strchr( szo, b ) && strchr( szo, c ) &&strchr( szo, x ) && strchr( szo, y ) )

    fprintf( f, "%s\n", szo );scanf( "%s", szo );}fclose( f );

    }

    1.58. feladat. rjon programot, amely a billentyzetrl angol szavakat olvas mindaddig, amgres sztringet nem kap. A program rja egy szveges llomnyba azokat a szavakat, amelyekbenegyms mellett van legalbb hrom mssalhangz.

    #include #include #include

    #define angmsh( c ) ( strchr( "bcdfghjklmnpqrstvwxyz", tolower( c ) ) )

    main(){

    FILE *f = fopen( "szavak.txt", "w" );char szo[ 100 ];f o r ( ; ; ){

    char szo[ 100 ];int i;gets( szo );if ( szo[ 0 ] == \0 )

    break;for ( i = 0; i + 2 < strlen( szo ); ++i )

    if ( angmsh( szo[ i ] ) && angmsh( szo[ i + 1 ] ) && angmsh( szo[ i + 2 ] ) )

  • 8/2/2019 programozas-peldatar

    62/109

    60 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    {fprintf( f, "%s\n", szo );break;

    }}fclose( f );

    }

    1.59. feladat. Adva van egy szveges llomny, amely egymstl egy szkzzel elvlasztott kln-bz angol szavakat tartalmaz. rjon programot, amely kpernyre rja azokat a szavakat (ezekblakrmennyi lehet), amelyekben a legtbb magnhangz van.

    #include #include #include

    int mghdarab( char *s ){

    int darab = 0;while ( *s ){

    if ( strchr( "aeiou", tolower( *s ) ) != NULL )++darab;

    s++;}return darab;

    }

    int main(){

    FILE *fin;

    char input[ 256 ], szo[ 100 ];int max = 0;printf( "Az input llomny: " ); scanf( "%s", input );fin = fopen( input, "r" );while ( fscanf( fin, "%s", szo ) != EOF ){

    int mgh = mghdarab( szo );if ( mgh > max )

    max = mgh;}fclose( fin );fin = fopen( input, "r" );

    while ( fscanf( fin, "%s", szo ) != EOF ){int mgh = mghdarab( szo );if ( mgh == max )

    printf( "%s\n", szo );}fclose( fin );

    }

    1.60. feladat. Adott egy szveges llomny, amelyben magyar szavak vannak, minden sz utnegy szkz ll. rjon eljrst, amely kpernyre rja azon sorokat (tbb ilyen is lehet), amelyekben alegkevesebb sz van!

    Felttelezve, hogy a feldolgozand llomny neve be.txt, s az llomny egyetlen sora sem tartalmaz2000-nl tbb karaktert, egy lehetsges megolds a kvetkez:

    #include

  • 8/2/2019 programozas-peldatar

    63/109

    1.7. LLOMNYOK 61

    void kevesszosorok(){

    FILE *f = fopen( "be.txt", "r" );char sor[ 2000 ];int i, min = 2000;while ( fgets( sor, 2000, f ) ){

    int szoszam = 0;for ( i = 0; sor[ i ]; ++i )

    if ( sor[ i ] == )++szoszam;

    if ( szoszam < min ) min = szoszam;

    }f = freopen( "be.txt", "r", f );while ( fgets( sor, 2000, f ) ){

    int szoszam = 0;for ( i = 0; sor[ i ]; ++i )

    if ( sor[ i ] == )++szoszam;

    if ( szoszam == min )printf( sor );

    }fclose( f );

    }

    1.61. feladat. Adva van egy szveges llomny, amely soraiban egymstl egyetlen szkzzel el-vlasztott magyar szavak llnak. rjon eljrst, amely meghatrozza az llomnyban elfordul szavakgyakorisgt! Felttelezhetjk, hogy maximum 200 klnbz sz fordul el.

    #include #include #include

    typedef struct tablaelem{

    char *kulcs;int gyakorisag;

    } TABLA[ 200 ];

    int darab;

    TABLA tomb;

    void gyakszamolo( char *allomany ){

    FILE *f;char szo[ 30 ];darab = 0;f = fopen( allomany, "r" );while ( fscanf( f, "%s", szo ) != EOF ){

    int i;for ( i = 0; i < darab; ++i )

    if ( strcmp( tomb[ i ].kulcs, szo ) == 0 )

    break;if ( i == darab ){

  • 8/2/2019 programozas-peldatar

    64/109

    62 1. FEJEZET. PLDK TEMATIKUS CSOPORTOSTSBAN

    ++darab;tomb[ i ].kulcs = ( char * )malloc( ( strlen( szo ) + 1 ) * sizeof( char ) );strcpy( tomb[ i ].kulcs, szo );tomb[ i ].gyakorisag = 1;

    }else

    ++tomb[ i ].gyakorisag;}fclose( f );

    }

    1.62. feladat. Adva van egy olyan szveges llomny, amely sorai egyetlen szkzzel elvlasztottangol szavakat tartalmaznak. rjon programot, amely meghatrozza s kpernyre rja a szvegbenelfordul szavak gyakorisgt!

    Vegyk szre, hogy a feladat nagyon hasonlt a 1.61. feladatban megfogalmazottakhoz, mindssze any-nyi a klnbsg, hogy most nem ismerjk a szveges llomnyban tallhat, egymstl klnbz szavakmaximlis darabszmt. Ezrt a szavakat s a gyakorisgukat tartalmaz tblzatot dinamikusan clszerltrehozni.

    #include #include #include

    typedef struct tablaelem{

    char *kulcs;int gyakorisag;

    } TABLA;

    main(){

    FILE *fin;char input[ 256 ], szo[ 30 ];TABLA *tabla = NULL;int darab = 0, i;

    printf( "Az input llomny: " ); scanf( "%s", input );

    fin = fopen( input, "r" );while ( fscanf( fin, "%s", szo ) != EOF ){

    for ( i = 0; i < darab; ++i )if ( strcmp( tabla[ i ].kulcs, szo ) == 0 )

    break;if ( i == darab ) /* mg nem szerepelt a sz a tblzatban */{

    ++darab;tabla = ( TABLA * )realloc( tabla, darab * sizeof( TABLA ) );tabla[ i ].kulcs = ( char * )malloc( ( strlen( szo ) + 1 ) * sizeof( char ) );strcpy( tabla[ i ].kulcs, szo );tabla[ i ].gyakorisag = 1;

    }else /* a sz benne volt a tblzatban */

    ++tabla[ i ].gyakorisag;}fclose( fin );

    for ( i = 0; i < darab; ++i )printf( "%s: %d\n", tabla[ i ].kulcs, tabla[ i ].gyakorisag );

  • 8/2/2019 programozas-peldatar

    65/109

    1.7. LLOMNYOK 63

    free( tabla );}

    1.63. feladat. rjon eljrst, amely paramterknt megkap kt szveges llomny nevet s egysztringet, majd az els llomny azon sorait, melyeknek a vge azonos a sztringgel, trja a msik

    llomnyba! Az els llomny ltezik, a msodikat most kell ltrehozni.

    A feladatot tbbflekppen is meg lehet oldani. Azonban minden megoldshoz rdemes felhasznlni akvetkez fggvnyt, amely meghatrozza, hogy egy (ltez) llomnynak milyen hossz a leghosszabbsora:

    #include

    int sorhossz( char *allomany ){

    int hossz = 0, maxhossz = 0, ch;FILE *f = fopen( allomany, "r" );

    while ( ( ch = fgetc( f ) ) != EOF ){

    if ( ch == \n ){

    if ( hossz > maxhossz ) maxhossz = hossz;

    hossz = 0;}else

    ++hossz;}

    if ( hossz > maxhossz ) maxhossz = hossz;

    fclose( f );

    return maxhossz;}

    A fenti fggvny segtsgvel pontosan akkora memriaterletet foglalhatunk le egy llomnybeli sorbeolvasshoz, amennyire ahhoz maximlisan szksg lehet.

    (a) Ezek utn lssuk azt a megoldst, amely az llomnybl beolvasott sorokat karakterenknt htulrlelrefel haladva dolgozza fel:

    #include #include

    void sorvegir( char *innev, char *outnev, char *s ){

    int hossz = sorhossz( innev );char *sor = ( char * )malloc( ( hossz + 2 ) * sizeof( char ) );FILE *in = fopen( innev, "r" ), *