Programozási alapismeretek 3. előadás
Tartalom Ciklusok specifikáció+ algoritmika +kódolás Egy bevezető példa a tömbhöz A tömb Elágazás helyett tömb Konstans tömbök 2/42
Ciklusok Feladat: Határozzuk meg egy természetes szám (N>1) 1-től különböző legkisebb osztóját! Specifikáció: Bemenet: N Egész Kimenet: O Egész Előfeltétel: N>1 Utófeltétel: 1<O N és O N és i (2 i<o): i ł N 3/42
Ciklusok A megoldás ötlete: Próbáljuk ki a 2-t; ha nem jó, akkor a 3-at, ha az sem, akkor a 4-et, ; legkésőbb az N jó lesz! Az ezt kifejező algoritmus: i:=2 i ł N i:=i+1 O:=i Változó i:egész 4/42
Ciklusok Feladat: Határozzuk meg egy természetes szám (N>1) 1-től különböző legkisebb és önmagától különböző legnagyobb osztóját! Specifikáció: Bemenet: N Egész Kimenet: Lko,Lno Egész Előfeltétel: N>1 Utófeltétel: 1<Lko N és 1 Lno<N és Lko N és i (2 i<lko): i ł N és Lno N és i (Lno<i<N): i ł N 5/42
Ciklusok Megjegyzés: Az Lno az utófeltételben az Lko ismeretében másképp is megfogalmazható: Lko*Lno=N! Az ehhez illeszkedő algoritmus: i:=2 i ł N i:=i+1 Lko:=i Lno:=N Div Lko Változó i:egész 6/42
Ciklusok Feladat: Határozzuk meg egy természetes szám (N>1) 1-től és önmagától különböző legkisebb osztóját (ha van)! Specifikáció: Bemenet: N Egész Kimenet: O Egész, Van Logikai Előfeltétel: N>1 Utófeltétel: Van= i (2 i<n): i N és Van O N és 2 O<N és i (2 i<o): i ł N 7/42
Algoritmus: Ciklusok i:=2 i<n és i ł N i:=i+1 Van:=i<N Van O:=i Változó i:egész Megjegyzés: Ha i osztója N-nek, akkor (N Div i) is osztója, azaz elég az osztókat a szám gyökéig keresni! 8/42 i N I N 2 i N Div i N Div 2 i*i azaz N azaz i N
Ciklusok Feladat: Határozzuk meg egy természetes szám (N>1) osztói összegét! Specifikáció: Bemenet: N Egész Kimenet: S Egész Előfeltétel: N>1 N Utófeltétel: S i i 1 N i 9/42
Ciklusok Algoritmus: S:=0 i=1..n I i N S:=S+i N Változó i:egész 10/42
Ciklusok Feladat: Határozzuk meg egy természetes szám (N>1) páratlan osztói összegét! Specifikáció: Bemenet: N Egész Kimenet: S Egész Előfeltétel: N>1 N Utófeltétel: S= i páratlan(i)=??? i 1 i N és páratlan(i) 11/42
Ciklusok Algoritmus 1 : S:=0 i=1..n I i N és páratlan(i) S:=S+i Algoritmus 2 : S:=0 i=1..n; 2-esével I i N S:=S+i N N Változó i:egész Változó i:egész 12/42
Ciklusok Feladat: Határozzuk meg egy természetes szám (N>1) prímosztói összegét! Specifikáció: Bemenet: N Egész Kimenet: S Egész Előfeltétel: N>1 Utófeltétel: S= prím(i)=??? i N i és N i 2 prím(i) 13/42
Ciklusok Algoritmus: a legkisebb osztó biztosan prím; ha N-t osztjuk vele ahányszor csak tudjuk, a következő osztója (a redukált N-nek) megint prím lesz. S:=0 i:=2 I i N i N S:=S+i i N N:=N Div i i:=i+1 14/42 N Változó i:egész
Ciklusok Feladat: Határozzuk meg azon i,j (i,j>1) természetes számok számát, amelyekre i*j<n (N>1)! Specifikáció: Bemenet: N Egész Kimenet: S Egész Előfeltétel: N>1 Utófeltétel: S= N Div 2 15/42 i 2 N Div 2 1 j 2 i j N N Div2 i 2 (N-1) Divi i j j 2 1 N
Ciklusok Algoritmus 1 : S:=0 i=2..n Div 2 j=2..n Div 2 I i*j<n S:=S+1 N Változó i,j:egész (N-1) Div i S:=S+1 16/42
Algoritmus 2 : Ciklusok S:=0 i=2..n Div 2 j:=2 i*j<n S:=S+1 j:=j+1 Algoritmus 3 : S:=0 i=2..n Div 2 S:=S+((N-1) Div i)-1 Változó i,j:egész Változó i:egész 17/42
Ciklusok Tanulságok: Ha az utófeltételben,, vagy jel van, akkor a megoldás mindig ciklus! Ha az utófeltételben vagy jel van, akkor a megoldás sokszor feltételes ciklus! Ha az utófeltételben jel van, akkor a megoldás sokszor számlálós ciklus! ( is ) Két egymásba ágyazott jel esetén két ciklus lesz egymás belsejében, általában. Feltételes esetén a ciklusban elágazás lesz. 18/42
Tipikus előfordulás: a beolvasás ellenőrzésénél (l. 2.ea.-ban) Ciklusok algoritmus kód Feltételes ciklus: feltétel utasítások utasítások feltétel Számlálós ciklus: i=1..n utasítások while (feltétel){ utasítások } do{ utasítások }while (feltétel); for (int i=1;i<=n;++i){ utasítások } i=1..n; x-esével utasítások for (int i=1;i<=n;i+=x){ utasítások } 19/42
Feladat elágazásra, vagy más megoldás kell? Feladat: A japán naptár 60 éves ciklusokat tartalmaz, az éveket párosítják, s mindegyik párhoz valamilyen színt rendelnek (zöld, piros, sárga, fehér, fekete). o o o o o 1,2,11,12,,51,52: zöld évek 3,4,13,14,,53,54: piros évek 5,6,15,16, 55,56: sárga évek 7,8,17,18, 57,58: fehér évek 9,10,19,20,,59,60: fekete évek Tudjuk, hogy 1984-ben indult az utolsó ciklus, amely 2043-ban fog véget érni. Írjunk programot, amely megadja egy M évről (1984 M 2043), hogy milyen színű! 20/42
A Szín halmaz definiálása, visszavezetés a Szöveg Feladat elágazásra, vagy más megoldás kell? Specifikáció 1 : Bemenet: év Egész Kimenet: s Szín Előfeltétel: 1984 év és év 2043 Egy még ismeretlen halmaz Utófeltétel: ((év-1984) Mod 10) Div 2=0 és s= zöld vagy ((év-1984) Mod 10) Div 2=1 és s= piros vagy Definíció: Szín:=( zöld, piros, sárga, fehér, fekete ) Szöveg halmazra 21/42
Feladat elágazásra, vagy más megoldás kell? Specifikáció 2 : Bemenet: év Egész Kimenet: s Szín A Szín halmaz definiálása itt is lehetséges Szín=( zöld, piros, sárga, fehér, fekete ) Szöveg Előfeltétel: 1984 év és év 2043 Utófeltétel: ((év-1984) Mod 10) Div 2=0 és s= zöld vagy ((év-1984) Mod 10) Div 2=1 és s= piros vagy 22/42
Feladat elágazásra, vagy más megoldás kell? Specifikáció 2 : Bemenet: év Egész Kimenet: s Szín A Szín halmaz definiálása itt is lehetséges Szín=( zöld, piros, sárga, fehér, fekete ) Szöveg Előfeltétel: 1984 év és év 2043 Utófeltétel: (((év-1984) Mod 10) Div 2=0 s= zöld ) és (((év-1984) Mod 10) Div 2=1 s= piros ) és 23/42
Feladat elágazásra, vagy más megoldás kell? Algoritmus: y:=((év-1984) Mod 10) Div 2 y=0 y=1 y=2 y=3 y=4 s:= s:= s:= piros sárga fehér s:= zöld s:= fekete Változó y:egész Kérdés: Akkor is ezt tennénk, ha 5 helyett 90 ágat kellene írnunk? A válasz előtt egy új adatszerkezet: a tömb. 24/42
Tömbök Kapcsolódó fogalmak: Sorozat: azonos típusú elemek egymásutánja, az elemei sorszámozhatók. Tömb: véges hosszúságú sorozat, a sorozat i- edik tagjával végezhetünk műveleteket (adott a legkisebb és a legnagyobb index, vagy az elemszám). Index: sokszor 1..N, máskor 0..N 1. Tömbelem-műveletek: elemérték-hivatkozás, elemérték-módosítás (az elem indexeléssel kiválasztva). 25/42
Tömbök (algoritmusban) Deklarációs példák: X:Tömb[1..N:Egész] Y:Tömb[0..4:Szöveg] Az előbbi példa színek halmazát reprezentálhatjuk egy konstans tömbbel: Konstans Színek:Tömb[0..4:Szöveg]= ( zöld, piros, sárga, fehér, fekete ) Hivatkozási példák: X[1]:=X[N]; Y[i]:=Színek[0] Y:=Színek 26/42
Tömbök (algoritmusban+kódban) Tömb-elemszám indexelés 0..??? indexelés 0..N Tömb-elemszám Deklarációs példák X:Tömb[1..N:Egész] Y:Tömb[0..4:Szöveg] a C++ kódjukkal: int X[N+1] string Y[5] Az előbbi példa Szín halmazát reprezentálhatjuk egy konstans tömbbel: Konstans Színek:Tömb[0..4:Szöveg]= ( zöld, piros, sárga, fehér, fekete ) const string Szinek[5]={"zöld","piros", "sárga","fehér","fekete"}; 27/42
Tömbök (C++ kódban áttekintés) Statikus tömbök: Deklaráció: const int MaxN=???;//tömb max.elemszáma típus tömb[maxn]; //tömbdeklaráció //0..MaxN-1 közötti indexekkel Hivatkozások: Eltérés a specifikációban és az algoritmusban szokásostól! tömb[ind] //tömbérték-hivatkozás tömb[ind]=kif;//tömbérték-módosítás 28/42
Tömbök (C++ kódban áttekintés) Statikus tömb konstansok: Deklaráció: Figyeljünk a sizeof szintaxisára: más adatra, és más típusra! const int N=???;//tömb elemszáma const típus tömb[n]={t1,t2,,tn}; //konstans tömb deklarációja, //0..N-1 közötti indexekkel vagy const típus tömb[]={t1,t2,,tn}; //konstans tömb deklarációja const int N=sizeof tömb/sizeof(típus); //tömb elemszáma //indexek: 0..N-1 közötti 29/42
Tömbök (C++ kódban áttekintés) Dinamikus tömbök: Deklaráció: int N; Létrehozás: Hivatkozások (nincs változás): //tömb aktuális elemszám N=???;//N meghatározása, pl. beolvasása típus tömb[n];//tömbhelyfoglalás N db //típus típusú elem számára tömb[ind] //tömbérték-hivatkozás tömb[ind]=kif;//tömbérték-módosítás 30/42
Tömbök (C++ kódban áttekintés) Tömb beolvasása (ellenőrzéssel): Algoritmikusan: Be: N [HelyesN(N))] A HelyesN-be beleértem a szintaktikus és szemantikus ellenőrzést is. bool hiba; //van-e hiba? do{ cout << "Elemszám:"; cin >> N; hiba=!helyesn(n); if (hiba) { cout << "hibaüzet" << endl; } }while (hiba); L. még korábban! 31/42
Tömbök (C++ kódban áttekintés) Tömb beolvasása (ellenőrzéssel): Algoritmikusan: Be: v(1..n) [Helyes(v(1..N))] A Helyes-be beleértem a szintaktikus és szemantikus ellenőrzést is. bool hiba; for (int //van-e i=0;i<n;++i) hiba? { do{ do{ cout << cout "Elemszám:"; << i+1 << cin ".:"; >> cin N; >> v[i]; hiba=!helyesn(n); hiba=!helyes(v[i]); if (hiba) if (hiba) { { cout << cout "hibaüzet" << "hibaüzenet" << endl; << endl; } } }while }while (hiba); (hiba); } Térjünk vissza a kérdésre L. még korábban! 32/42
Elágazás helyett tömb Specifikáció: Bemenet: év Egész Kimenet: s Szín Szín=( zöld, piros, sárga, fehér, fekete ) Szöveg Konstans Színek Tömb[0..4:Szín]= ( zöld, piros, sárga, fehér, fekete ) Előfeltétel: 1984 év és év 2043 Utófeltétel: s=színek[((év-1984) Mod 10) Div 2] 33/42
Elágazás helyett tömb Algoritmus: y:=((év-1984) Mod 10) Div 2 s:=színek[y] Változó y:egész 34/42
Leglogikusabb helyre téve. Az algoritmus szempontjából bemenet Konstans tömbök alkalmazása Feladat: Írjunk programot, amely egy 1 és 99 közötti számot betűkkel ír ki! Specifikáció: Bemenet: N Egész Konstans egyes Tömb[0..9:Szöveg]= (, egy,, kilenc ) Konstans tizes Tömb[0..9:Szöveg]= (, tizen,, kilencven ) Kimenet: S Szöveg Előfeltétel: 1 N 99 35/42
Konstans tömbök alkalmazása Utófeltétel: N=10 S= tíz és N=20 S= húsz és N {10,20} S=tizes[N Div 10]+ egyes[n Mod 10] Algoritmus: N=10 N=20 N {10,20} S:= tíz S:= húsz S:=tizes[N Div 10]+ egyes[n Mod 10] 36/42
Konstans tömbök alkalmazása Feladat: Írjunk programot, amely egy hónapnévhez a sorszámát rendeli! Specifikáció: Bemenet: H Szöveg Konstans HóNév Tömb[1..12:Szöveg]= ( január,, december ) Kimenet: S Egész Előfeltétel: H HóNév Utófeltétel: 1 S 12 és HóNév[S]=H 37/42
Konstans tömbök alkalmazása Algoritmus: i:=1 HóNév[i] H i:=i+1 S:=i Változó i:egész Kérdés: mi lenne, ha az ef. nem teljesülne? Futási hiba? Végtelen ciklus? 38/42
Konstans tömb mit tárolunk? Feladat: Egy nap a nem szökőév hányadik napja? Specifikáció 1 : Bemenet: H,N Egész Konstans hó Tömb[1..12:Egész]= (31,28,31,,31) Kimenet: S Egész Előfeltétel: 1 H 12 és 1 N hó[h] Utófeltétel: S N H i 1 1 hó[i] 39/42
Konstans tömb mit tárolunk? Algoritmus: S:=N i=1..h 1 S:=S+hó[i] Változó i:egész Megjegyzés: Szökőév esetén H 3 esetén S- et 1-gyel meg kellene növelni! (És az előfeltétel is módosul.) 40/42
Konstans tömb mit tárolunk? Egy másik megoldás: Tároljuk minden hónapra, hogy az előző hónapokban összesen hány nap van! Specifikáció 2 : Bemenet: Konstans hó Tömb[1..12:Egész]= (0,31,59,90,,334) Utófeltétel: S=N+hó[H] Kérdés: Ez jobb megoldás? Mi lesz az előfeltétellel? 41/42
Programozási alapismeretek 3. előadás vége