programozas-peldatar
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" ), *