KZH-k régebbről – megoldásokkal
Régebben kiadott KZH feladatok és megoldásaik, vegyesen a gyakorlati kis zh-kból és a laboron szereplőkből.
1 Ciklusok
Add meg az algoritmus pszeudokódját, és készítsd el a programot C nyelven! A program kötelezően a pszeudokódot valósítsa meg!
1.
Egy program bekér a felhasználótól két pozitív egész számot, és kiírja a két szám közötti összes páratlan számot. A program akkor is helyesen működik, ha a felhasználó előbb a felső, aztán az alsó határt adja meg (és fordítva is).
Megoldás
Első és második szám bekérése Ha első > második alsó = második, felső = első Egyébként alsó = első, felső = második A ciklusváltozó legyen alsó Amíg a ciklusváltozó kisebb vagy egyenlő a felsővel Ha a ciklusváltozó páratlan Írd ki a ciklusváltozót Növeld a ciklusváltozót eggyel
#include <stdio.h> int main() { int elso, masodik, also, felso, i; printf("Elso = "); scanf("%d",&elso); printf("Masodik = "); scanf("%d",&masodik); if (elso > masodik) { also = masodik; felso = elso; } else { also = elso; felso = masodik; } for (i = also; i <= felso; i = i + 1) if (i % 2 == 1) printf("%d ",i); return 0; }
2.
Egy program bekér a felhasználótól két pozitív egész számot, és megszámolja, hogy a két szám között hány 3-mal osztható, de 5-tel nem osztható szám áll, végül kiírja a darabszámot. A program akkor is helyesen működik, ha a felhasználó előbb a felső, aztán az alsó határt adja meg (és fordítva is).
Megoldás
Első és második szám bekérése Ha első > második alsó = második, felső = első Egyébként alsó = első, felső = második Darabszám = 0, ciklusváltozó = alsó Amíg ciklusváltozó kisebb, mint felső Ha alsó osztható hárommal, de nem osztható öttel Darabszám növelése eggyel Alsó növelése eggyel
#include <stdio.h> int main() { int elso, masodik, also, felso, darab,i; printf("Elso = "); scanf("%d",&elso); printf("Masodik = "); scanf("%d",&masodik); if (elso > masodik) { also = masodik; felso = elso; } else { also = elso; felso = masodik; } darab = 0; for (i = also; i <= felso; i = i + 1) if (i%3 == 0 && i%5 != 0) darab = darab + 1; printf("%d ", darab); return 0; }
3.
Egy program bekér a felhasználótól két pozitív egész számot, és kiírja a két szám közötti összes 7-tel osztható páratlan számot. A program akkor is helyesen működik, ha a felhasználó előbb a felső, aztán az alsó határt adja meg (és fordítva is).
Megoldás
Első és második szám bekérése Ha első > második alsó = második, felső = első Egyébként alsó = első, felső = második A ciklusváltozó legyen alsó Amíg ciklusváltozó kisebb, mint felső Ha ciklusváltozó páratlan és osztható 7-tel írd ki ciklusváltozót növeld ciklusváltozó eggyel
#include <stdio.h> int main() { int elso, masodik, also, felso, i; printf("Elso = "); scanf("%d",&elso); printf("Masodik = "); scanf("%d",&masodik); if (elso > masodik) { also = masodik; felso = elso; } else { also = elso; felso = masodik; } for (i = also; i < felso; i = i + 1) if (i % 2 == 1 && i % 7 == 0) printf("%d ", i); return 0; }
4.
Egy program bekér a felhasználótól két pozitív egész számot, és kiszámítja a két szám közötti összes 5-tel osztható páros szám összegét, majd ennyi * karaktert ír a képernyőre. A program akkor is helyesen működik, ha a felhasználó előbb a felső, aztán az alsó határt adja meg (és fordítva is).
Megoldás
Első és második szám bekérése Ha első > második alsó = második, felső = első Egyébként alsó = első, felső = második Összeg = 0, ciklusváltozó = alsó Amíg ciklusváltozó kisebb, mint felső Ha ciklusváltozó osztható 10-zel Összeget növeld ciklusváltozóval növeld ciklusváltozót eggyel Ciklusváltozó = 0 Amíg ciklusváltozó < összeg írj ki egy csillagot ciklusváltozót növeld eggyel
#include <stdio.h> int main() { int elso, masodik, also, felso, sum, i; printf("Elso = "); scanf("%d",&elso); printf("Masodik = "); scanf("%d",&masodik); if (elso > masodik) { also = masodik; felso = elso; } else { also = elso; felso = masodik; } sum = 0; for (i = also; i <= felso; i = i + 1) if (i % 10 == 0) sum += i; for (i = 0; i<sum; i = i + 1) printf("*"); return 0; }
5.
Egy program megkérdezi a felhasználótól, hogy hány darab szám összegét kívánja kiszámolni, majd bekér ennyi darab egész számot. Utána kiírja a számok összegét úgy, hogy az összegben ne legyen benne a felhasználó által megadott legnagyobb szám. (Az összeg így éppen a maximummal kevesebb.) Pl. ha a felhasználó 4 számot ad: -1, 10, 5, 7, akkor a kiírt összeg 11 lesz, mert -1+5+7=11.
Megoldás
Darabszám bekérése Összeg = 0 Ciklusváltozó = 0 Amíg ciklusváltozó kisebb, mint a darabszám Kérd be a következő számot Ha a ciklusváltozó 0, a maximum legyen egyenlő a számmal Egyébkén Ha a szám nagyobb a maximumnál A maximum legyen egyenlő a számmal Az összeghez add hozzá a számot Írd ki az összeg és a maximum különbségét
#include <stdio.h> int main() { int db, sum, max, akt, i; printf("Hany db szamot adsz ossze? "); scanf("%d", &db); sum = 0; for (i = 0; i < db; i = i + 1) { printf("A kovetkezo szam: "); scanf("%d",&akt); if (i == 0) max = akt; else if (akt > max) max = akt; sum += akt; } /* a trükk: a teljes összegből levonjuk a legnagyobbat. */ /* így pont olyan lesz, mintha az kimaradt volna az összegből. */ printf("Osszeg: %d\n", sum - max); return 0; }
2 Rajzolgatás
1.
Írj C programot, amely kér a felhasználótól egy számot, és utána egy akkora, csúcsán álló egyenlőszárú háromszöget rajzol a képernyőre "o" betűkből, hogy annak éppen a megadott számú sora van! Például 3 esetén:
ooooo ooo o
Megoldás
#include <stdio.h> int main() { int n,i,j; printf("Emelet="); scanf("%d",&n); for (i=0; i<n; i++) { for (j=0; j<i; j++) printf(" "); for (j=0; j<2*(n-i)-1; j++) printf("o"); printf("\n"); } return 0; }
2.
Írj C programot, amely kér a felhasználótól egy számot, és utána egy akkora, csúcsán álló egyenlőszárú háromszöget rajzol a képernyőre "o" betűkből, hogy annak éppen a megadott számú sora van! Például 3 esetén:
o oo ooo oo o
Megoldás
#include <stdio.h> int main() { int n,i,j; printf("Emelet="); scanf("%d",&n); for (i=0; i<n; i++) { for (j=0; j<n-i-1; j++) printf(" "); for (j=0; j<=i; j++) printf("o"); printf("\n"); } for (i=1; i<n; i++) { for (j=0; j<i; j++) printf(" "); for (j=0; j<n-i; j++) printf("o"); printf("\n"); } return 0; }
3.
Írj C programot, amely kér a felhasználótól egy szélességet és egy magasságot, és utána egy akkora paralelogrammát rajzol a képernyőre "o" betűkből! Például x=7, y=3 esetén:
ooooooo ooooooo ooooooo
Megoldás
#include <stdio.h> int main() { int x, y, i, j; printf("x="); scanf("%d", &x); printf("y="); scanf("%d", &y); for (i=0; i<y; i++) { for (j=0; j<y-i-1; j++) printf(" "); for (j=0; j<x; j++) printf("o"); printf("\n"); } return 0; }
3 Számelméleti feladatok
1.
Írj C programot, amely kér a felhasználótól egy pozitív egész számot, és utána kiírja az összes, ennél a számnál kisebb olyan pozitív egész számot, amely nem prím!
Megoldás
#include <stdio.h> int main() { int n, i; printf("Max="); scanf("%d",&n); printf("1\n"); for (i=2; i<n; i++) { int prim = 1, j; for (j=2; j<i; j++) if (i%j == 0) prim = 0; if (prim == 0) printf("%d\n",i); } return 0; }
2.
Írj C programot, amely kér a felhasználótól egy pozitív egész számot, és kiírja az összes, a megadott értéknél kisebb tökéletes számot! Tökéletes az a szám, amely megegyezik osztóinak összegével, pl.: 28=1+2+4+7+14.
Megoldás
#include <stdio.h> int main() { int n,i; printf("Max="); scanf("%d",&n); printf("1\n"); for (i=2; i<n; i++) { int sum=0, j; for (j=1; j<i; j++) if (i%j == 0) sum += j; if (sum==i) printf("%d\n",i); } return 0; }
4 Statisztika készítése
Autópálya
Az M7 autópályán traffipax méri az autók sebességét. Minden mérésről három adatot ad: „óra perc sebesség”, szóközzel elválasztva. Pl. „9 39 125” jelentése az, hogy 9:39-kor egy autó 125 km/h-val ment. A 140 km/h feletti sebességért 30 000 Ft a bírság, a 180 km/h felettiért 100 000 Ft. Az adatsor több nap adatait tartalmazza, és a végét 0 0 0 zárja.
Olvassa be a C programod ezeket az adatokat, és írja ki, hogy a nap mely órájában mennyi az összes kirótt bírság! Példa kimenet:
12:00-12:59, 60000 Ft 13:00-13:59, 230000 Ft
Megoldás
#include <stdio.h> int main() { int birsag[24]= {0}; int ora, perc, seb; int i; scanf("%d %d %d", &ora, &perc, &seb); while (seb!=0) { if (seb>180) birsag[ora]+=100000; else if (seb>140) birsag[ora]+=30000; scanf("%d %d %d", &ora, &perc, &seb); } for (i=0; i<24; i+=1) printf("%2d:00-%02d:59, %d Ft\n", i, i, birsag[i]); return 0; }
Bliccelés
Egy busztársaság szeretné tudni, a napok mely óráiban hány
ellenőrt érdemes terepmunkára küldenie. Ehhez összesítik a bírságok
adatait. Egy adat a következőkből áll: „óra perc típus összeg”, ahol
a típusnál h
a helyszíni bírság, c
pedig a
csekk. „9 45 c 6000” jelentése: egy utas 9:45-kor
csekket kapott 6000 forintról. A helyszíni bírságokat az ellenőrök
begyűjtik; a csekkes bírságoknak átlagosan 80%-át tudják behajtani.
(Vagyis egy 6000-es csekk a társaság számára átlagosan csak 4800-at
ér.) Az adatsor végén 0 0 x 0 szerepel.
Olvassa be a C programod ezeket az adatokat! Készítsen kimutatást arról, hogy mely napszakban mennyi a pótdíjakból a bevétel! Példa kimenet:
16:00-16:59, 14800 Ft 17:00-17:59, 12000 Ft
Megoldás
#include <stdio.h> int main() { int birsag[24]= {0}; int ora, perc, osszeg; char tipus; int i; scanf("%d %d %c %d", &ora, &perc, &tipus, &osszeg); while (tipus!='x') { if (tipus=='c') osszeg*=0.8; birsag[ora]+=osszeg; scanf("%d %d %c %d", &ora, &perc, &tipus, &osszeg); } for (i=0; i<24; i+=1) printf("%2d:00-%02d:59, %d Ft\n", i, i, birsag[i]); return 0; }
ZH statisztika
Egy oktató statisztikát szeretne készíteni a megírt ZH-król. A ZH-ban három feladat van, ezek pontszáma nemnegatív egész szám, egyenként max. 10 pont, így az egész max. 30 pontos lehet.
Írj programot, mely a szabványos bemenetéről olvassa be soronként a ZH-k pontszámait. Az adatsort -1 -1 -1 zárja. Írja ki ezután a szabványos kimenetre, hány 0 pontos, hány 1 pontos, … és hány 30 pontos megoldás lett. Ha adott pontszámú dolgozat nem született, a sort ne írja ki.
Példa bemenet:
8 10 7 4 3 5 10 10 9 10 9 10 -1 -1 -1
Példa kimenet:
12 pontos: 1 db 25 pontos: 1 db 29 pontos: 2 db
Megoldás
#include <stdio.h> int main() { int stat[31]= {0}; int p1, p2, p3, x; scanf("%d %d %d", &p1, &p2, &p3); while (p1!=-1) { int szum=p1+p2+p3; ++stat[szum]; scanf("%d %d %d", &p1, &p2, &p3); } for (x=0; x<=30; ++x) if (stat[x]!=0) printf("%2d pontos: %2d db\n", x, stat[x]); return 0; }
Múzeum
Egy múzeumban gazdasági okok miatt heti egy szünnapot szeretnének tartani, ezért keresik a hét azon napját, amikor a legkevesebb a látogató.
Írj programot, mely a szabványos bemenetén fogadja a múzeum napi látogatási adatait úgy, hogy soronként a hét napjának sorszámát kapjuk 1-7 között, majd szóközzel elválasztva a látogatók számát. Az adatok rendezetlenül érkeznek, adott sorszámú naphoz több bejegyzés is tartozhat. A bemenet végét 0 0 jelzi.
Írja ki a program a szabványos kimenetre annak a napnak a sorszámát, amely a legkevesebb látogatót jelenti. Feltételezzük, hogy egy ilyen nap van.
Példa bemenet:
1 7 3 5 6 56 2 3 7 88 5 25 4 7 1 6 0 0
Példa kimenet:
2
Megoldás
#include <stdio.h> int main() { int latogato[7]= {0}; int nap, db, min, x; scanf("%d %d", &nap, &db); while (nap!=0) { latogato[nap-1]+=db; scanf("%d %d", &nap, &db); } min=0; for (x=1; x<7; ++x) if (latogato[x]<latogato[min]) min=x; printf("%d\n", min+1); return 0; }
5 Bitek
1.
Mennyi 27|13 ? Írd le mindkét számot, valamint az eredményt is kettes számrendszerben! Az eredményt tízes számrendszerben is add meg!
Megoldás
27 = 11011 |13 = 01101 ------------ 31 = 11111
Írj függvényt, amely paraméterként kap egy pozitív egész számot, és logikai igazzal tér vissza, ha a szám páros számú 1-es bitet tartalmaz!
Megoldás
int paritas(int szam) { int db=0; for (; szam!=0; szam>>=1) db += szam & 1; return (db & 1) == 0; }
2.
Mennyi 45&57 ? Írd le mindkét számot, valamint az eredményt is kettes számrendszerben! Az eredményt tízes számrendszerben is add meg!
Megoldás
45 = 101101 &57 = 111001 ------------ 41 = 101001
Írj függvényt, amely paraméterként kap egy előjel nélküli egész számot, melyről feltételezzük, hogy 32 bites. A függvény cserélje fel a szám összes szomszédos bitpárját (0. az 1.-vel, 2. a 3.-kal, … 30. a 31.-kel)! A függvény ezt az értéket adja vissza!
Megoldás
Egy egyszerű megoldás:
unsigned csere(unsigned miben) { int i; unsigned eredmeny = 0; for (i = 0; i < 32; i+=2) { if (miben & 1<<i) eredmeny |= 1<<(i+1); if (miben & 1<<(i+1)) eredmeny |= 1<<i; } return eredmeny; }
Egy nagyon trükkös megoldás:
unsigned csere(unsigned szam) { return ((szam & 0xaaaaaaaa)>>1) | ((szam & 0x55555555)<<1); }
3.
Mennyi 27^13 ? Írd le mindkét számot, valamint az eredményt is kettes számrendszerben! Az eredményt tízes számrendszerben is add meg!
Megoldás
27 = 11011 ^13 = 01101 ----------- 22 = 10110
Írj függvényt, amely paraméterként kap egy előjel nélküli egész számot, melyről feltételezzük, hogy 32 bites, és visszatérési értékként adja, hogy a szám hány 0 értékű bitet tartalmaz!
Megoldás
int nullbit(unsigned szam) { int db=0, i; for (i=0; i<32; szam>>=1, i++) db += !(szam & 1); return db; }
4.
Mennyi (~20) & 13 ? Írd le mindkét számot, valamint az eredményt is kettes számrendszerben! Az eredményt tízes számrendszerben is add meg!
Megoldás
20 = 00010100 ~20 = 11101011 &13 = 00001101 --------------- 9 = 00001001
Írj függvényt, amely paraméterként kap egy előjel nélküli egész számot, melyről feltételezzük, hogy 32 bites! A függvény számítsa ki és adja vissza, hogy hány olyan 1-es bit van a számban, amelyet mindkét oldalról 0 bit határol! (Értelemszerűen a legalsó és legfelső bit nem lehet ilyen.) Pl. ha a bemenő bitminta 1011101000010101011001010011111, akkor az eredmény 6.
Megoldás
int egyedulallo(unsigned szam) { int db=0, i; for (i=0; i<30; i++, szam>>=1) if (((szam&7)^2) == 0) db++; return db; }
5.
Mennyi 0x2A | 0x82 ? Írd le mindkét számot, valamint az eredményt is kettes számrendszerben! Az eredményt tizenhatos számrendszerben is add meg!
Megoldás
0x2A = 00101010 |0x82 = 10000010 ---------------- 0xAA = 10101010
Írj függvényt, amely paraméterként kap egy előjel nélküli egész számot, melyről feltételezzük, hogy 16 bites. A függvény tükrözze a szám bitmintáját, az így kapott számot adja vissza! Pl. be: 0011000000000001, ki: 1000000000001100.
Megoldás
int tukroz(int szam) { int eredmeny; for (eredmeny=0; szam!=0; szam>>=1) eredmeny = (eredmeny<<1) + (szam&1); return eredmeny; }
6 Saját sztringkezelő függvények
Összefűzés
Írj függvényt, amely paraméterként vesz át egy cél sztringet, továbbá két másik sztringet és egy elválasztó karaktert! Másolja be a cél sztringbe a másik két sztringet úgy, hogy közéjük az elválasztó karaktert teszi.
Írj főprogramot, amelyben egy példával bemutatod a függvény használatát!
A string.h
függvényei nem használhatóak!
Példa paraméterek: „alma”
és „körte”
, továbbá „;”
Példa eredmény:
„alma;körte”
Megoldás
#include <stdio.h> void osszefuz(char *ide, char *egyik, char *masik, char koze) { int pos, i; pos=0; for (i=0; egyik[i]!='\0'; ++i) ide[pos++]=egyik[i]; ide[pos++]=koze; for (i=0; masik[i]!='\0'; ++i) ide[pos++]=masik[i]; ide[pos++]='\0'; } int main() { char kesz[20]; osszefuz(kesz, "alma", "korte", ';'); printf("%s\n", kesz); return 0; }
Szétválasztás
Írj egy függvényt, amely paraméterként vesz át egy bemeneti sztringet és egy elválasztó karaktert! Legyen még két további paramétere, amelyekbe az eredményt írja. Vágja ketté a függvény a sztringet az első elválasztó karakternél: az eleje menjen az egyik eredmény sztringbe, másik pedig a másikba!
Írj főprogramot, amelyben egy példával bemutatod a függvény használatát!
A string.h
függvényei nem használhatóak.
Példa paraméterek:
„alma;körte”
és „;”
Példa eredmény:
„alma”
és „körte”
Megoldás
#include <stdio.h> void szeletel(char *be, char elvalaszto, char *egyik, char *masik) { int x, pos; x=0; pos=0; while (be[x]!=elvalaszto) egyik[pos++]=be[x++]; egyik[pos]=0; x++; pos=0; while (be[x]!='\0') masik[pos++]=be[x++]; masik[pos]=0; } int main() { char bal[20], jobb[20]; szeletel("alma;korte", ';', bal, jobb); printf("[%s] es [%s]\n", bal, jobb); return 0; }
Karakterek törlése
Írj függvényt, amely átvesz paraméterként egy módosítandó sztringet és még egy karaktert. Alakítsa át úgy a sztringet úgy, hogy a megadott karaktert törölje a sztring elejéről és a végéről is! Mindkét oldalon lehet több is, vagy akár semennyi. A belsejében viszont tudjuk, hogy nincsen.
Írj főprogramot, amelyben egy példával bemutatod a függvény használatát!
A string.h
függvényei nem használhatóak.
Példa bemenet:
„xxxHello hallo elektor kalandorxxxx”
és az „x”
karakter
Példa kimenet:
„Hello hallo elektor kalandor”
Megoldás
#include <stdio.h> void sztring_trim(char *str, char mit) { int eleje, pos, i; eleje=0; while (str[eleje]==mit) eleje++; pos=0; for (i=eleje; str[i]!=mit && str[i]!='\0'; i++) str[pos++]=str[i]; str[pos]='\0'; } int main() { char szoveg[]="xxxHello hallo elektor kalandorxxxx"; sztring_trim(szoveg, 'x'); printf("[%s]\n", szoveg); return 0; }
Bevezető és lezáró karakterek
Írj függvényt, amely paraméterként átvesz egy cél sztringet, továbbá egy forrás sztringet, egy karaktert és egy darabszámot! Másolja át a cél sztringbe a forrást úgy, hogy elé és mögé a megadott karakterből a megadott darabszámút tegye. Ezen kívül a szóközöket is cserélje ki a megadott karakterre.
Írj főprogramot, amelyben egy példával bemutatod a függvény használatát!
A string.h
függvényei nem használhatóak.
Példa bemenet:
„Hello hallo elektor kalandor”
, továbbá az „x”
karakter és 3
Példa kimenet:
„xxxHelloxhalloxelektorxkalandorxxx”
Megoldás
#include <stdio.h> void strelemoge(char *ide, char *mit, char kar, int db) { int pos, x; pos=0; for (x=0; x<db; ++x) ide[pos++]=kar; for (x=0; mit[x]!='\0'; ++x) ide[pos++] = mit[x]==' ' ? kar : mit[x]; for (x=0; x<db; ++x) ide[pos++]=kar; ide[pos]='\0'; } int main() { char novelt[30]; strelemoge(novelt, "Hello hallo elektor kalandor", 'x', 3); printf("[%s]\n", novelt); return 0; }
7 Állapotgépek
Szmájli számláló
Írj állapotgépes programot, amely a szabványos bemenetről olvasott szövegben megszámolja a szomorú :( és a vidám :) szmájlikat. A számlálás után kiírja, hogy a szöveg vidám, szomorú vagy közömbös, azaz több, kevesebb vagy ugyanannyi :) volt, mint :(.
Tervezd meg az állapotgépet állapot- és tevékenységtáblával, utána írd meg a programot! A programra csak akkor jár pont, ha állapotgépes és a leírt állapottáblát valósítja meg.
Megoldás
: | ( | ) | többi | |
---|---|---|---|---|
alap | →kp | - | - | - |
kp | - | szom++, →alap | vid++, →alap | →alap |
#include <stdio.h> int main() { enum Allapot { alap, kp } all; int szom, vid, c; all=alap; szom=vid=0; while ((c=getchar())!=EOF) { switch (all) { case alap: if (c==':') all=kp; break; case kp: if (c==')') vid++; else if (c=='(') szom++; if (c!=':') all=alap; break; } } if (vid>szom) printf("vidam"); else if (szom<vid) printf("szomoru"); else printf("kozombos"); return 0; }
Sz és zs számláló
Írj állapotgépes programot, amely a szabványos bemenetről olvasott szövegben megszámolja az „sz” és a „zs” betűket! (Hosszú ssz és zzs is egynek számítanak, azokkal külön nem kell foglalkozni.) A számlálás után írd ki a szabványos kimenetre mindkettő darabszámát!
Tervezd meg az állapotgépet állapot- és tevékenységtáblával, utána írd meg a programot! A programra csak akkor jár pont, ha állapotgépes és a leírt állapottáblát valósítja meg.
Megoldás
s | z | többi | |
---|---|---|---|
alap | →svolt | →zvolt | - |
svolt | - | sz++, →alap | →alap |
zvolt | zs++, →alap | - | →alap |
#include <stdio.h> int main() { enum Allapot { alap, svolt, zvolt } all; int c, sz, zs; all=alap; sz=zs=0; while ((c=getchar())!=EOF) { switch (all) { case alap: if (c=='s') all=svolt; else if (c=='z') all=zvolt; break; case svolt: if (c=='z') sz++; if (c!='s') all=alap; break; case zvolt: if (c=='s') zs++; if (c!='z') all=alap; break; } } printf("sz: %d, zs: %d\n", sz, zs); return 0; }
Szmájli számláló
Írj állapotgépes programot, amely a szabványos bemenetről olvasott szövegben megszámolja a szomorú :( és a vidám :) szmájlikat. A számlálás után kiírja, hogy a szöveg vidám, szomorú vagy közömbös, azaz több, kevesebb vagy ugyanannyi :) volt, mint :(. A szmájlik zárójelenként egynek számítanak, vagyis :))) három vidámat, :(( két szomorút jelent.
Tervezd meg az állapotgépet állapot- és tevékenységtáblával, utána írd meg a programot! A programra csak akkor jár pont, ha állapotgépes és a leírt állapottáblát valósítja meg.
Megoldás
: | ( | ) | többi | |
---|---|---|---|---|
alap | →kp | - | - | - |
kp | - | szom++ | vid++ | →alap |
#include <stdio.h> int main() { enum Allapot { alap, kp } all; int szom, vid, c; all=alap; szom=vid=0; while ((c=getchar())!=EOF) { switch (all) { case alap: if (c==':') all=kp; break; case kp: if (c==')') vid++; else if (c=='(') szom++; else if (c!=':') all=alap; break; } } if (vid>szom) printf("vidam"); else if (szom<vid) printf("szomoru"); else printf("kozombos"); return 0; }
Dzs számláló
Írj állapotgépes programot, amely a szabványos bemenetről olvasott szövegben megszámolja a „dzs” betűket! (Hosszú ddzs egynek számít, nem kell külön foglalkozni vele.) A számlálás után írd ki a szabványos kimenetre a darabszámot!
Tervezd meg az állapotgépet állapot- és tevékenységtáblával, utána írd meg a programot! A programra csak akkor jár pont, ha állapotgépes és a leírt állapottáblát valósítja meg.
Megoldás
d | z | s | többi | |
---|---|---|---|---|
alap | →dvolt | - | - | - |
dvolt | - | →dzvolt | →alap | →alap |
dzvolt | →dvolt | →alap | dzs++, →alap | →alap |
#include <stdio.h> int main() { enum Allapot { alap, dvolt, dzvolt } all; int c, dzs; all=alap; dzs=0; while ((c=getchar())!=EOF) { switch (all) { case alap: if (c=='d') all=dvolt; break; case dvolt: if (c=='d') ; else if (c=='z') all=dzvolt; else all=alap; break; case dzvolt: if (c=='s') dzs++; if (c=='d') all=dvolt; else all=alap; break; } } printf("dzs: %d\n", dzs); return 0; }
8 Tömbök, pointerek
1.
Írj függvényt, amely paraméterként vesz át egy egészekből álló tömböt, és visszaadja az első olyan tömbelem címét, amelyből legalább kettő található a tömbben! Ha nincs ilyen tömbelem, adjon vissza NULL pointert!
Megoldás
int *dupla(int *tomb, int n) { int i, j; for(i=0; i<n-1; i++) for(j=i+1; j<n; j++) if (tomb[i] == tomb[j] ) return tomb+i; return NULL; }
2.
Írj függvényt, amely paraméterként vesz át egy valós értékekből álló tömböt, melyről biztosan tudjuk, hogy elemei különbözőek! A függvény ellenőrizze, hogy a tömb rendezett-e (akár növekvő, akár csökkenő sorrendben; a feltételezett rendezettség iránya az első két tömbelem vizsgálatával eldönthető). Ha a tömb nem rendezett, a függvény adja vissza az első olyan tömbelem címét, amelyik elrontja a rendezettséget! Ha a tömb rendezett, adjon vissza NULL pointert! Pl. be: {-8.11, -5.3, 0.1, 2.5, 1.4, 6.9, 12.0, 5.7} , a visszaadott érték az 1.4-et tartalmazó tömbelem címe. Pl. be: {7, 1, 2, 3, 4, 5} , a visszaadott érték a 2-t tartalmazó tömbelem címe.
Megoldás
double *rendezette(double *tomb, int n) { int i, no; if (n<3)return NULL; no = tomb[0] < tomb[1]; for(i=3; i<n; i++) { if (no && tomb[i-1] > tomb[i])return tomb+i; else if (!no && tomb[i-1] < tomb[i])return tomb+i; } return NULL; }
3.
Írj függvényt, amely paraméterként vesz át egy sztringet, és visszaadja az első olyan karakter címét, amelyből legalább kettő található a sztringben! Ha nincs ilyen karakter, adjon vissza NULL pointert!
Megoldás
char *duplas(char *string) { int i, j; for(i=0; string[i]!='\0'; i++) for(j=i+1; string[j]!='\0'; j++) if (string[i] == string[j] ) return string+i; return NULL; }
4.
Írj függvényt, amely paraméterként vesz át egy egészekből álló tömböt! A függvény adja vissza paramétersoron (címével átvett változókban) a tömb legkisebb és legnagyobb elemének indexét! Ha több egyforma érték a legkisebb/legnagyobb, akkor ezek közül bármelyik indexét visszaadhatja.
Megoldás
void minmax(int *tomb, int n, int *min, int *max) { int i; *min = *max = 0; for(i = 1; i<n; i++) { if (tomb[i] < tomb[*min] ) *min = i; if (tomb[i] > tomb[*max] ) *max = i; } }
5.
Írj függvényt, amely paraméterként kap egy sztringet! A sztring szöveget tartalmaz, melynek szavait szóközök választják el egymástól (minden szó, ami nem szóköz). A függvény adja vissza paramétersoron (címével átvett változókban) a sztring második szavának indexét, visszatérési értékként (return-nel) pedig a sztring utolsó szavának címét! A paraméterként kapott sztringről biztosan tudjuk, hogy legalább két szóból áll, a szavakat pontosan egy szóköz választja el egymástól, és a sztring első és utolsó karaktere nem szóköz.
Megoldás
char *szavak(char *sztring, int *masodik) { int i, utolso=0; *masodik=0; for (i=0; sztring[i]!='\0'; i++) { if (sztring[i]==' ') { utolso=i; if (*masodik==0) *masodik = i+1; } } return sztring + utolso; }
9 Listák I.
Elejéről a végére
Írj függvényt, amely egy lista legelső elemét a lista végére helyezi át! (Például az 1,2,3,4,5 listából így 2,3,4,5,1 lesz.) A függvény a lista elejére mutató pointert cím szerint kapja. Ha kettőnél kevesebb elem van, akkor ne csináljon semmit.
Definiáld az egyszeresen láncolt lista adatszerkezetét úgy, hogy egész számokat tartalmazzon! Készíts rajzot, amely a listakezelést mutatja számozott lépésekkel! Írj programrészt, amely létrehoz két listaelemet, és meghívja a keletkező listára a függvényt.
Megoldás
typedef struct Lista { int szam; struct Lista *kov; } Lista; void elso_vegere(Lista **peleje) { Lista *iter, *elso; if (*peleje==NULL) return; if ((*peleje)->kov==NULL) return; for (iter=*peleje; iter->kov!=NULL; iter=iter->kov) ; elso=*peleje; iter->kov=elso; *peleje=elso->kov; elso->kov=NULL; } Lista *eleje; eleje=(Lista*) malloc(sizeof(Lista)); eleje->szam=3; eleje->kov=(Lista*) malloc(sizeof(Lista)); eleje->kov->szam=4; eleje->kov->kov=NULL; elso_vegere(&eleje);
Ötödik elem törlése
Írj függvényt, amely egy lista ötödik elemét törli! (A számozás 1-től indul.) Ha nincs ötödik elem, akkor ne történjen semmi. A függvénynek egy paramétere legyen csak, az a lista elejére mutató pointer.
Definiáld az egyszeresen láncolt lista adatszerkezetét úgy, hogy max. 30 karakter hosszúságú szavakat tároljon! Készíts rajzot, amely a listakezelést mutatja számozott lépésekkel! Írj rövid főprogramot, amelyben definiálsz egy listát. Feltételezve, hogy a lista fel van töltve, töröld ki a függvénnyel az 5. elemet!
Megoldás
typedef struct Lista { char szo[30+1]; struct Lista *kov; } Lista; void lista_torol_5(Lista *lista) { Lista *iter, *negyedik, *otodik; int i; for (iter=lista, i=1; iter!=NULL && i<4; iter=iter->kov, ++i) ; negyedik=iter; if (negyedik==NULL) return; otodik=negyedik->kov; if (otodik==NULL) return; negyedik->kov=otodik->kov; free(otodik); } Lista *l=.....; lista_torol_5(l);
Ötödik beszúrása
Írj függvényt, amely egy listába beszúr egy elemet úgy, hogy az az ötödik legyen! (A számozás 1-től indul.) Ha a lista rövidebb, akkor kerüljön a végére az új elem. A függvénynek paraméterei legyenek a lista elejére mutató pointer és a beszúrandó adat. Visszatérési értéke legyen a lista elejét mutató pointer.
Definiáld az egyszeresen láncolt lista adatszerkezetét úgy, hogy az max. 50 karakter hosszúságú neveket tároljon! Készíts rajzot, amely a listakezelést mutatja számozott lépésekkel! Írj rövid főprogramot, amelyben definiálsz egy listát. Feltételezve, hogy a lista fel van töltve, szúrd be az 5. helyre a Mézga Géza nevet!
Megoldás
typedef struct Lista { char nev[50+1]; struct Lista *kov; } Lista; Lista* beszur_5(Lista *eleje, char *nev) { Lista *iter, *uj; int i; uj=(Lista*) malloc(sizeof(Lista)); strcpy(uj->nev, nev); if (eleje==NULL) { uj->kov=NULL; return uj; } for (iter=eleje, i=1; iter->kov!=NULL && i<4; iter=iter->kov, i++) ; uj->kov=iter->kov; iter->kov=uj; return eleje; } Lista *l=.....; l=beszur_5(l, "MezgaGeza");
Utolsó elem az elejére
Írj függvényt, amely egy lista utosó elemét a lista elejére helyezi át! (Például az 1,2,3,4,5 listából így 5,1,2,3,4 lesz.) A függvény a lista elejére mutató pointert cím szerint kapja. Ha kettőnél kevesebb elem van, akkor ne csináljon semmit.
Definiáld az egyszeresen láncolt lista adatszerkezetét úgy, hogy az valós számokat tartalmazzon! Készíts rajzot, amely a listakezelést mutatja számozott lépésekkel! Írj programrészt, amely létrehoz két listaelemet, és meghívja a keletkező listára a függvényt.
Megoldás
typedef struct Lista { double szam; struct Lista *kov; } Lista; void utolso_elore(Lista **peleje) { Lista *iter, *utolso; if (*peleje==NULL) return; if ((*peleje)->kov==NULL) return; for (iter=*peleje; iter->kov->kov!=NULL; iter=iter->kov) ; utolso=iter->kov; utolso->kov=*peleje; *peleje=utolso; iter->kov=NULL; } eleje=(Lista*) malloc(sizeof(Lista)); eleje->szam=3; eleje->kov=(Lista*) malloc(sizeof(Lista)); eleje->kov->szam=4; eleje->kov->kov=NULL; utolso_elore(&eleje);
10 Listák II.
1.
Definiálj egy két irányban láncolt lista elemeinek tárolására alkalmas adatstruktúrát, a lista valós értékű adatokat tárol! Írj függvényt, amely paraméterként kapja egy ilyen elemekből felépülő, mindkét végén strázsával lezárt lista kezdőstrázsájának címét! A függvény töröljön a listából minden olyan elemet, amelynek adata negatív értékű!
Megoldás
typedef struct elem { double ertek; struct elem *prev, *next; } elem; void torol(elem *start) { for (start = start->next; start->next != NULL; start = start->next ) if (start->ertek < 0.0) { elem *torlendo = start; start = start->prev; torlendo->prev->next = torlendo->next; torlendo->next->prev = torlendo->prev; free(torlendo); } }
2.
Definiálj egy irányban láncolt lista elemeinek tárolására alkalmas adatstruktúrát, a lista 20 elemű int tömb adattaggal rendelkezik! Írj függvényt, amely paraméterként kapja egy ilyen elemekből felépülő lista címét! A függvény adja vissza a lista másolatát (a másolt lista kezdőelemének címét)! (Vagyis hozzon létre egy másik listát, amely ugyanazokat az adatokat tartalmazza ugyanolyan sorrendben, mint a paraméterként átvett!)
Megoldás
typedef struct elem { int adat[20]; struct elem *next; } elem; elem *masol(elem *start) { elem *ujstart, *ujfuto; for (ujstart = ujfuto = NULL; start != NULL; start = start->next) { elem *p = (elem*)malloc(sizeof(elem)); *p = *start; p->next = NULL; if (ujstart==NULL) ujstart = ujfuto = p; else { ujfuto->next = p; ujfuto = ujfuto->next; } } return ujstart; }
3.
Definiálj két irányban láncolt lista elemeinek tárolására alkalmas adatstruktúrát, a lista pozitív egész számokat tárol! Írj függvényt, amely paraméterként kapja egy ilyen elemekből felépülő, mindkét végén strázsával lezárt lista címét! A függvény duplázzon meg minden olyan listaelemet, amely páratlan számot tartalmaz, vagyis hozzon létre és fűzzön be minden ilyen listaelem elé vagy mögé egy új listaelemet, melybe a páratlan értéket átmásolja!
Megoldás
typedef struct elem { int adat; struct elem *prev,*next; } elem; void duplaz(elem *start) { for (start = start->next; start->next != NULL; start = start->next) { if (start->adat % 2 == 1) { elem *p = (elem*)malloc(sizeof(elem)); *p = *start; p->next = start; p->next->prev = p; p->prev->next = p; } } }
4.
Definiálj két irányban láncolt lista elemeinek tárolására alkalmas adatstruktúrát, a lista 20 elemű int tömb adattaggal rendelkezik! Írj függvényt, amely paraméterként kapja egy ilyen elemekből felépülő lista címét! A függvény adja vissza a lista másolatát (a másolt lista kezdőelemének címét)! (Vagyis hozzon létre egy másik listát, amely ugyanazokat az adatokat tartalmazza ugyanolyan sorrendben, mint a paraméterként átvett!)
Megoldás
typedef struct elem { int adat[20]; struct elem *prev,*next; } elem; elem *masol(elem *start) { elem *ujstart, *ujfuto; for (ujstart = ujfuto = NULL; start != NULL; start = start->next) { elem *p = (elem*)malloc(sizeof(elem)); *p = *start; p->next = NULL; if (ujstart==NULL) { ujstart = ujfuto = p; p->prev = NULL; } else { ujfuto->next = p; p->prev = ujfuto; ujfuto = ujfuto->next; } } return ujstart; }
5.
Definiálj egy irányban láncolt lista elemeinek tárolására alkalmas adatstruktúrát, a lista valós típusú adattaggal rendelkezik! Írj függvényt, amely paraméterként kapja két, ilyen elemekből felépülő lista címét! A függvény tegye át a két lista elemeit fordított sorrendben egy harmadik listába, és ennek a listának a kezdőcímét adja vissza! (Ne foglalj memóriát, hanem az eredeti listaelemek pointereinek átállításával oldd meg a feladatot!) Például ha a két bemenő lista elemei: {1.0, 3.0, 5.0} és {2.0, 4.0, 6.0}, akkor a kimenő lista {6.0, 4.0, 2.0, 5.0, 3.0, 1.0} legyen!
Megoldás
typedef struct elem { double adat; struct elem *next; } elem; elem *forditvafuz(elem *lista1, elem *lista2) { elem *cel = NULL; while (lista1 != NULL) { elem *temp = lista1->next; lista1->next = cel; cel = lista1; lista1 = temp; } while (lista2 != NULL) { elem *temp = lista2->next; lista2->next = cel; cel = lista2; lista2 = temp; } return cel; }