6. Moduláris programtervezés



Hasonló dokumentumok
(A TÁMOP /2/A/KMR számú projekt keretében írt egyetemi jegyzetrészlet):

VII. A határozatlan esetek kiküszöbölése

Számsorozatok. 1. Alapfeladatok december 22. sorozat határértékét, ha. 1. Feladat: Határozzuk meg az a n = 3n2 + 7n 5n létezik.

A figurális számokról (IV.)

Hiba! Nincs ilyen stílusú szöveg a dokumentumban.-86. ábra: A példa-feladat kódolási változatai

( a b)( c d) 2 ab2 cd 2 abcd 2 Egyenlőség akkor és csak akkor áll fenn

Matematika B4 I. gyakorlat

3. SOROZATOK. ( n N) a n+1 < a n. Egy sorozatot (szigorúan) monotonnak mondunk, ha (szigorúan) monoton növekvő vagy csökkenő.

Sorozatok A.: Sorozatok általában

2. Hatványsorok. A végtelen soroknál tanultuk, hogy az. végtelen sort adja: 1 + x + x x n +...

f (M (ξ)) M (f (ξ)) Bizonyítás: Megjegyezzük, hogy konvex függvényekre mindig létezik a ± ben

Statisztika 1. zárthelyi dolgozat március 21.

2. fejezet. Számsorozatok, számsorok

SZÁMELMÉLET. Vasile Berinde, Filippo Spagnolo

Sorozatok, határérték fogalma. Függvények határértéke, folytonossága

1. A radioaktivitás statisztikus jellege

1 k < n(1 + log n) C 1n log n, d n. (1 1 r k + 1 ) = 1. = 0 és lim. lim n. f(n) < C 3

Kalkulus II., második házi feladat

Eötvös Loránd Tudományegyetem Informatikai Kar. Analízis 1. Írásbeli beugró kérdések. Készítette: Szántó Ádám Tavaszi félév

A függvénysorozatok olyanok, mint a valós számsorozatok, csak éppen a tagjai nem valós számok,

24. tétel A valószínűségszámítás elemei. A valószínűség kiszámításának kombinatorikus modellje.

1. Írd fel hatványalakban a következõ szorzatokat!

NUMERIKUS SOROK II. Ebben a részben kizárólag a konvergencia vizsgálatával foglalkozunk.

1. beadandó feladat: Programozási tételek alkalmazása. Közös követelmények:

Rudas Tamás: A hibahatár a becsült mennyiség függvényében a mért pártpreferenciák téves értelmezésének egyik forrása

Villamos gépek tantárgy tételei

Az átlagra vonatkozó megbízhatósági intervallum (konfidencia intervallum)

VÉLETLENÍTETT ALGORITMUSOK. 1.ea.

BIOMATEMATIKA ELŐADÁS

ELEMI PROGRAMOZÁSI TÉTELEK

Matematika I. 9. előadás

Függvényhatárérték-számítás

1. Adatok közelítése. Bevezetés. 1-1 A közelítő függvény

Bevezetés az informatikába

Nevezetes sorozat-határértékek

Kétoldali hibás Monte Carlo algoritmus: mindkét válasz esetén hibázhat az algoritmus, de adott alsó korlát a hibázás valószínűségére.

5. Kombinatorika. 8. Legfeljebb hány pozitív egész számot adhatunk meg úgy, hogy semelyik kettő összege és különbsége se legyen osztható 2015-tel?

Programozási tételek. Dr. Iványi Péter

1. ALGORITMUSOK MŰVELETIGÉNYE

Egyszerű programozási tételek

OEP Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1. Feladat. Elemzés 1

Sorozatok október 15. Határozza meg a következ sorozatok határértékeit!

MATEMATIKA I. KATEGÓRIA (SZAKKÖZÉPISKOLA)

18. Differenciálszámítás

9. előadás. Programozás-elmélet. Programozási tételek Elemi prog. Sorozatszámítás Eldöntés Kiválasztás Lin. keresés Megszámolás Maximum.

V. Deriválható függvények

Ingatlanfinanszírozás és befektetés

Gyakorló feladatok II.

EGYENLETEK ÉS EGYENLETRENDSZEREK MEGOLDÁSA A Z n HALMAZON. egyenletrendszer megoldása a

10.M ALGEBRA < <

Kidolgozott feladatok a nemparaméteres statisztika témaköréből

6. Számsorozat fogalma és tulajdonságai

1. Az absztrakt adattípus

3. Sztereó kamera. Kató Zoltán. Képfeldolgozás és Számítógépes Grafika tanszék SZTE (

Programozási Módszertan definíciók, stb.

Pályázat címe: Pályázati azonosító: Kedvezményezett: Szegedi Tudományegyetem Cím: 6720 Szeged, Dugonics tér

BIOSTATISZTIKA ÉS INFORMATIKA. Leíró statisztika

Lineáris kódok. u esetén u oszlopvektor, u T ( n, k ) május 31. Hibajavító kódok 2. 1

ALGEBRA. egyenlet megoldásait, ha tudjuk, hogy egész számok, továbbá p + q = 198.

Kvantum párhuzamosság Deutsch algoritmus Deutsch-Jozsa algoritmus

I. FEJEZET BICIKLIHIÁNYBAN

Eseményalgebra, kombinatorika

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

Matematikai játékok. Svetoslav Bilchev, Emiliya Velikova

2. egy iskola tanulói, a változók: magasságuk cm-ben, súlyuk (tömegük) kilóban; 3. egy iskola tanulói, a változó: tanulmányi átlaguk;

Populáció. Történet. Adatok. Minta. A matematikai statisztika tárgya. Valószínűségszámítás és statisztika előadás info. BSC/B-C szakosoknak

4. Test feletti egyhatározatlanú polinomok. Klasszikus algebra előadás NE KEVERJÜK A POLINOMOT A POLINOMFÜGGVÉNNYEL!!!

Kalkulus I. Első zárthelyi dolgozat szeptember 16. MINTA. és q = k 2. k 2. = k 1l 2 k 2 l 1. l 1 l n 6n + 8

6. Elsőbbségi (prioritásos) sor

I. rész. Valós számok

A tárgy címe: ANALÍZIS 1 A-B-C (2+2). 1. gyakorlat

Elsőbbségi (prioritásos) sor

Kombinatorika. Variáció, permutáció, kombináció. Binomiális tétel, szita formula.

Minta JAVÍTÁSI-ÉRTÉKELÉSI ÚTMUTATÓ A MATEMATIKA EMELT SZINTŰ ÍRÁSBELI 2. FELADATSORHOZ

Az új építőipari termelőiár-index részletes módszertani leírása

Matematikai játékok. Svetoslav Bilchev, Emiliya Velikova

A biostatisztika alapfogalmai, konfidenciaintervallum. Dr. Boda Krisztina PhD SZTE ÁOK Orvosi Fizikai és Orvosi Informatikai Intézet

GAZDASÁGI MATEMATIKA 1. ANALÍZIS

Kutatói pályára felkészítı modul

Felvételi tematika INFORMATIKA

Diszkrét matematika II., 3. előadás. Komplex számok

Hanka László. Fejezetek a matematikából

Komplex számok (el adásvázlat, február 12.) Maróti Miklós

SOROK Feladatok és megoldások 1. Numerikus sorok

(d) x 6 3x 2 2 = 0, (e) x + x 2 = 1 x, (f) 2x x 1 = 8, 2(x 1) a 1

Statisztika. Eloszlásjellemzők

ALAPFOGALMAK 1. A reláció az program programfüggvénye, ha. Azt mondjuk, hogy az feladat szigorúbb, mint az feladat, ha

Programozás I. Egyszerű programozási tételek. Sergyán Szabolcs

EGYENLETEK ÉS EGYENLETRENDSZEREK MEGOLDÁSA A Z n HALMAZON. egyenletrendszer megoldása a Z

A FUNDAMENTÁLIS EGYENLET KÉT REPREZENTÁCIÓBAN. A függvény teljes differenciálja, a differenciális fundamentális egyenlet: U V S U + dn 1

2.1. A sorozat fogalma, megadása és ábrázolása

Általános taggal megadott sorozatok összegzési képletei

Debreceni Egyetem, Közgazdaság- és Gazdaságtudományi Kar. Feladatok a Gazdasági matematika I. tárgy gyakorlataihoz. Halmazelmélet

7. el adás Becslések és minta elemszámok fejezet Áttekintés

Előfeltétel: legalább elégséges jegy Diszkrét matematika II. (GEMAK122B) tárgyból

Cserjésné Sutyák Ágnes *, Szilágyiné Biró Andrea ** ismerete mellett több kísérleti és empirikus képletet fel-

Statisztikai hipotézisvizsgálatok

A szórások vizsgálata. Az F-próba. A döntés. Az F-próba szabadsági fokai

Matematikai statisztika

Algoritmizálás, adatmodellezés tanítása 1. előadás

Átírás:

A visszavezetés techikájáak megértése, elsajátítása ömagába köyű feladat. Alkalmazása akkor válik ehézzé, amikor egy összetett probléma megoldásához egyszerre több programozási tételt is fel kell haszáli. Már egy kezdő programozóál is kialakul az a képesség, hogy egy összetett feladatba észrevegye a megoldáshoz szükséges programozási tételeket, de ezek egymáshoz való viszoyát, az egyikek a másikba való beágyazásáak módját még em látja tisztá. Ehhez arra va szükség, hogy a megoldadó feladatot a programozási tételek meté részekre botsuk. A részekre botás pedig ameyibe azt potosa yomo követjük kijelöli a részmegoldások összetevéséek módját. A részfeladatok kijelölését hatékoya támogatja, ha a feladat megfogalmazásakor az egyes fogalmak jelölésére egy-egy alkalmas függvéyt vezetük be. Ezek a kitalált, tehát absztrakt függvéyek a megoldás bizoyos fázisaiba elrejtik azokat a részfeladatokat. A beágyazott részfeladatok elrejtése következtébe világosabba látható, hogy legmagasabb szite milye programozási tétellel oldható meg a feladat. Egy részfeladat megoldása pedig a feladat többi részétől függetleül, a részfeladatot elrejtő függvéy kiszámításával oldható meg. Ezt a függvéyabsztrakciós programozási techikát moduláris programkészítések is evezik, mert az így készült programok kódolásakor, az egyes logikailag jól elkülöíthető részfeladatokat megoldó programokat elkülöítjük, ezáltal a teljes program részprogramokra bomlik. Eek eredméye egy olya programkód lesz, amelybe a külöválasztott programrészek jól átlátható, elleőrzött kapcsolatba állak. Ez áttekithetővé, jól karbatarthatóvá teszi programjaikat. Ameyibe egy részprogram leírását fizikailag is elválasztjuk a teljes programról, akkor azt alprogramak hívjuk. Egy alprogram maga is több alprogramra botható, ami által összetett, hierarchikus szerkezete lesz a programjaikak. Ebbe a fejezetbe először éháy példá keresztül bemutatjuk, hogya alkalmazható többszöröse a visszavezetés techikája az összetett feladatok megoldásáál, és az így kapott programot a feladat részfeladatai meté alprogramokra tördeljük. A második alfejezetbe áttekitjük azokat a program-átalakító szabályokat, úgyevezett program-átalakításokat, amelyek külöböző szempotok alapjá támogatják programkészítésüket. Az utolsó alfejezetbe egy külöleges program-átalakítást mutatuk arra az esetre, amikor egy ciklusba szereplő részfeladat rekurzív függvéyekkel adható meg. 62

6.1. Alprogram 6.1. Alprogram Egy program leírásába szereplő bármelyik részprogram egy jól meghatározott részfeladatot old meg. Ha egy részprogram fizikailag is elkülöül a program leírásába, akkor azt alprogramak evezzük. Struktogrammos jelölés eseté egy részprogramból úgy készíthetük alprogramot, hogy a részprogramot kiemeljük az azt tartalmazó program struktogrammjából, a kiemelt struktogrammot egyedi azoosítóval látjuk el, és a részprogram helyét a program struktogrammjába ezzel az azoosítóval jelöljük. Ez lehetőséget ad arra is, hogy ugyaarra az alprogramra több helye is hivatkozhassuk részprogramkét. Mivel mide feladat megoldható egy (általába em megegedett) értékadással, ezért az alprogramjaik által megoldott részfeladatok is, eél fogva egy alprogram potosa azoosítható ezzel az értékadással. Ezért a továbbiakba az alprogramot leíró struktogrammot ezzel az értékadással azoosítjuk. Ezt evezzük majd az alprogram fejéek. Egy program struktogrammjába, ahol az alprogramot részprogramkét láti kívájuk, ugyaezt az értékadást írjuk. Ezt az alprogram hívó utasításáak, rövide hívásáak evezik. Amikor egy program végrehajtása sorá elérük egy alprogram hívásához, akkor oa kezdve az alprogram határozza meg végrehajtás meetét, azaz átkerül a vezérlés az alprogramhoz. Az alprogram befejeződésekor a hívó utasítás utá folytatódik a hívó program végrehajtása. Más szavakkal, a hívó programak (amely a hívást tartalmazza) a hívás pillaatáig befutott végrehajtása (állapotsorozata) felfüggesztődik, az ekkor elért állapotból az alprogram egy végrehajtásával (állapotsorozatával) folytatódik, majd az így elért állapotból a hívó programak a hívás utái utasításai alapjá folytatódik végrehajtás. Az alprogram kiiduló állapottere tartalmazza a hívó program állapotteréek a hívás pillaatába (segédváltozókkal együtt) meglevő kompoeseit. Más szavakkal az alprogram haszálhatja a hívó program azo változóit, amelyek az alprogram hívásakor élek. Ezeket az alprogram szempotjából globális változókak evezzük. Az alprogram mit mide program bevezethet új változókat is, de ezek az alprogram befejeződésekor megszűek. Ezeket evezzük az alprogram lokális változóiak. Egy lokális változó eve megegyezhet egy globális változó evével, de ekkor godoskodi kell arról, hogy a két ugyaolya evű, de természetese egymástól függetle változót megkülöböztessük valahogya egymástól. Mi erre em vezetük be külö jelölést, ugyaakkor megállapoduk abba, hogy az ilye esetekbe, amikor egy változó eve em azoosítja egyértelműe a változót, akkor azo midig a lokális változót értjük. Természetese az alprogramak em kell mide globális változót haszália. Eél fogva egy alprogram más, eltérő állapotterű programokból is meghívható, feltéve, hogy azok állapotterébe a hívás pillaatába vaak olya változók, amelyeket az alprogram globális változókét haszáli akar. A legrugalmasabb alprogramok ebből a szempotból azok, amelyek egyáltalá em haszálak globális változókat, mert ezeket bármelyik programból meghívhatjuk. De hogya tud ebbe az esetbe az alprogram a hívó program változóba tárolt értékekhez hozzáféri? Az alprogramot meghívó utasításak és az alprogram fejéek em kell betű szerit megegyezie. Midkettő azoos kompoesű értékadás, de a fej változóeveiek helyé a hívásba állhatak más evű (de ugyaolya típusú) változók, sőt a hívásba egy olya változó helyé, amely a fejbe kizárólag az értékadás jobboldalá jeleik meg, állhat olya 63

kifejezés is, amely értéke a megfelelő fejbeli változó típusértékeiek egyike, azaz a kifejezés és a fejbeli változó típusa azoos. Az alprogram fejéek változói az alprogram lokális változói, a hívásba viszot a hívó program változói szerepelhetek csak. A fejbe haszált változók balról jobbra felsorolását (az esetleges ismétlődések megszűtetése utá) formális paraméterlistáak, magukat a változókat paraméterváltozókak szokták hívi. A hívó utasításba a paraméterváltozókak megfeleltetett változók és kifejezések (ismétlődés élküli) felsorolását aktuális paraméterlistáak, elemeit paraméterekek evezzük. A formális és aktuális paraméter lista elemszáma és elemeiek típusa azoos. A paraméterváltozókat két csoportra oszthatjuk: az értékadás jobboldali kifejezésébe lévők a bemeő-változók, az értékadás jelétől balra levők pedig az eredméy-változók. Ezek is az alprogramba jöek létre és az alprogram befejeződésekor szűek meg, de a bemeő-változók az alprogram hívásakor megkapják a hívó utasításba őket helyettesítő változók vagy kifejezések értékét kezdőértékkét, az eredméy-változók értékei pedig az alprogram befejeződésekor átmásolódak a hívó értékadás baloldalá levő megfelelő változókba. Csak a bemeőváltozókak megfeleltetett aktuális paraméter lehet kifejezés. Egy változó lehet egyszerre bemeő és eredméy-változó is, a eki megfelelő aktuális paraméter ilyekor csak változó lehet. A bemeő változók kivételével az alprogram többi lokális változójáak kiiduló értéke em-defiiált. Egy alprogram meghívható függvéyszerűe is. Ilyekor a hívó utasítás csak az alprogramot azoosító értékadás jobboldali kifejezéséből áll, amely a formális paraméterváltozók helyé az aktuális paramétereket tartalmazza. Nem szerepelek viszot a hívásba az eredméy-változókak megfeleltetett változók, mert a hívás em öálló utasításkét, haem egy másik kifejezésbe ágyazva (ami lehet például egy elágazás vagy ciklus feltétele, vagy egy értékadás jobboldala) jeleik meg. Az alprogram azoba ilyekor is egy értékadást valósít meg, ezért redelkezik eredméy-változókkal. Az alprogram befejeződésekor az eredméy-változóik értéke a hívó kifejezés értékekét jeleik meg a hívó programba. Szimultá értékadáskor ez a kifejezés egy több kompoesű érték. A függvéyszerű hívással elidított alprogramot a kokrét programozási yelvek függvéyek, az öálló utasítással (értékadással) meghívott alprogramot eljárásak evezik. 6.2. Beágyazott visszavezetés Ebbe az alfejezetbe a többszörös visszavezetéssel megoldható feladatokkal foglalkozuk, potosabba olyaokkal, amelyek megoldásáál egy programozási tételt egy másikba kell beágyazi. Ezek között köyebbek számítaak azok, amikor a külső programozási tétel (függvéy-kompozíció programozási tétele, vagy az eset-szétválasztásos függvéy programozási tétele) egy szekvecia vagy elágazás, és ebbe ágyazódik be egy másik tétel. Beüket elsősorba azok a feladatok érdekelek, ahol a külső programozási tétel programja egy ciklus, és ebbe ágyazódik be egy ugyacsak ciklust tartalmazó programozási tétel. 6.1. Példa. Egy iskola egyik diákot számláló osztályába m külöböző tatárgyból osztályoztak a félév végé. A jegyek egy táblázat formájába redelkezésükre állak. (A diákokat és a tatárgyakat most sorszámukkal azoosítjuk.) Állapítsuk meg, va-e olya diák, akiek csupa ötöse va! 64

6.2. Beágyazott visszavezetés A feladat egy "va-e olya az elemek között, hogy..." típusú eldötésből áll, ami alapjá sejthető, hogy a lieáris keresés programozási tételére lehet majd visszavezeti. Ebbe a keresésbe a diákokat kell egymás utá megvizsgáli, hogy csupa ötösük va-e. Egy diák megvizsgálása is egy eldötéses feladat, csakhogy itt arra keressük a választ, hogy a diákak mide jegye ötös-e. Az ilye "igaz-e, hogy mide elem olya, hogy..." típusú eldötésekél az optimista lieáris kereséssel adhatjuk meg a választ. A feladat tehát elsősorba egy lieáris keresés lesz, amelyik magába foglalja a "csupa ötös" tulajdoságot eldötő optimista lieáris keresést. Nézzük meg ezt alaposabba! A feladat bemeő adata az osztályzatok táblázata: egy sorú és m oszlopú mátrix, amelyek elemei 1 és 5 közé eső egész számok. Kimeő adata egy logikai érték, amely igaz, ha va kitűő tauló, hamis külöbe. A = (t:n m, l:l ) Ef = ( t=t ) Az utófeltétel megfogalmazásához bevezetük egy függvéyt, amelyik a t táblázat i-edik sora alapjá megmodja, hogy az i-edik diák szíjeles-e. Ez a szíjeles függvéy egy itervallumo értelmezett logikai függvéy, amely akkor ad igazat az i-edik értékre, ha a táblázat i-edik soráak mide eleme ötös. szíjeles : [1..] L szíjeles(i) = j [1..m] : t[i,j]=5 Eek segítségével köye felírható a feladat utófeltétele: az l potosa akkor igaz, ha va olya diák, azaz 1 és közé eső egész szám, amelyre a szíjeles feltétel igazat ad. Uf = ( Ef l = i [1..]: szíjeles(i) ) Ez a feladat visszavezethető a lieáris keresés programozási tételére. A lieáris keresés specifikációs jelöléséél most csak a logikai kompoes va eredméykét feltütetve, hisze csak eek megadása a feladat. m.. ~ (i) ~ 1.. szíjeles(i) l,i:= hamis,1 l i l := szíjeles(i) i := i+1 Ebbe a programba az l:=szíjeles(i) értékadás em-megegedett. Hagsúlyozzuk, hogy a szíjeles(i) ömagába csak egy kifejezés, em tekithető sem feladatak, sem programak, szembe az l:=szíjeles(i) értékadással. Ezt az értékadást, mit részfeladatot, tovább kell fiomítai, azaz végső soro egy megegedett programmal kell majd helyettesítei, azaz meg kell oldai. A megoldást egy alprogram keretébe írjuk majd le, amelyek hívását az l:=szíjeles(i) értékadás jelzi. (Döthettük vola úgy is, hogy az 65

l:=szíjeles(i) értékadást megoldó részprogramot bemásoljuk l:=szíjeles(i) értékadás helyére, de most ikább az alprogramkét való meghívást részesítjük előybe.) A részfeladatak a specifikációja az alábbi lesz. A = (t:n m,, l:l ) Ef = (t=t i=i [1..]) Uf = ( Ef l = szíjeles(i)) Figyelembe véve a szíjeles(i) defiícióját ez a részfeladat is visszavezethető a lieáris keresés programozási tételére, potosabba az optimista lieáris keresésre. Ügyeli kell arra, hogy ciklusváltozóak em haszálhatjuk az i-t, hisze az már foglalt változóév. Nevezzük át az i-t j-re. Eek megfelelőe a visszavezetésél em a (i)-t, haem a (j)-t kell helyettesítei a kokrét t[i,j]=5 feltétellel, amelybe az i a vizsgált diák sorszámára utal. m.. ~ 1..m i ~ j (i) ~ t[i,j]=5 l:=szíjeles(i) l,j:= igaz,1 l j m l := t[i,j]=5 j := j+1 j:n Az alprogram feje az l:=szíjeles(i) értékadás, amely most szóról szóra megegyezik a hívással. Ez e tévessze azoba meg beüket. A hívásba szereplő l és i változók (az aktuális paraméterek) a hívó programba haszált változók, tehát globálisak az alprogramra ézve. A fejbe szereplő l és i változók (a formális paraméterváltozók) viszot az alprogram lokális változói, amelyek a hívás miatt sajátos kapcsolatba állak az ugyaolya evű globális változókkal. (Természetese haszálhattuk vola más lokális változó eveket.) A lokális i (bemeő-változó) a híváskor megkapja a globális i értékét, a lokális l (eredméyváltozó) a hívás (azaz az alprogram) befejeződésekor átadja értékét a globális l-ek. A paraméterváltozók évegyezése miatt az alprogramba em hivatkozhatuk a globális l és i változókra. Haszálhatja ellebe az alprogram a globális t változót. Az alprogram bevezet még egy lokális j változót is, amely az alprogram befejeződésekor megszűik majd. 6.2. Példa. Egy diákot számláló osztályba m külöböző tatárgyból adtak jegyeket a félév végé. Ezek az osztályzatok egy táblázat formájába redelkezésükre állak. (A diákokat és a tatárgyakat most sorszámukkal azoosítjuk.) Tudjuk, hogy az osztályba va kitűő diák, adjuk meg az egyikek sorszámát! Ez a feladat agyo hasolít a 6.1. példához. Ott em tudtuk, hogy va-e kitűő diák, ezért a lieáris keresés programozási tételére vezettük vissza a feladatot, itt viszot tudjuk, hogy va, és egy ilye diákot keresük, ezért elegedő a feladatot a kiválasztás tételére visszavezeti. (Természetese a 6.1. példáál kapott program is alkalmazható, hisze a lieáris keresés emcsak azt döti el, hogy va-e kitűő diák, haem az elsőt meg is keresi.) 66

6.2. Beágyazott visszavezetés A = (t:n m, ) Ef = ( t=t k [1..]: szíjeles(k) ) Itt már az előfeltétel megfogalmazásához bevezetjük a szíjeles függvéyt. Uf = ( Ef i [1..] szíjeles(i) ) = ( i select szíjeles(i ) ) Ez a feladat visszavezethető a kiválasztás programozási tételére. m ~ 1 (i) ~ szíjeles(i) i:= 1 szíjeles(i) i := i+1 Ebbe a programba em-megegedett feltétel a szíjeles(i) kifejezést, amely értékét az előző példába elkészített l:=szíjeles(i) alprogram meghatározza. Most erre az alprogramra egy függvéyszerű hívást aduk. Amikor a ciklusfeltétel kiértékelésére kerül sor, akkor meghívódik az alprogram, és a lokális eredméy-változójáak (l:l) értéke közvetleül a ciklusfeltétel adódik vissza. Hagsúlyozzuk, hogy az alprogram em lesz más attól, hogy függvéyszerűe vagy eljárásszerűe hívjuk meg. Az alprogram midig egy értékadás által kijelölt feladatot oldja meg (va eredméy-változója), azaz egy értékadást valósít meg. A 6.1. példába éppe ezért függvéyszerű hívásról is és eljárásszerű hívásról is beszélhetük, ics e kettő között látható külöbség, hisze egy eljárásszerű hívás midig felfogható függvéyszerű hívásak is. Fordítva ez már em igaz, habár midig átalakítható a hívó program úgy, hogy egy függvéyszerű hívást eljárásszerű hívással helyettesíthessük. Ezt akkor tesszük meg, ha ezt valamilye más szempot (például hatékoyság) idokolja. Az aktuális példákba ics ilye érv, de a játék kedvéért mutassuk meg ezt az átalakítást. A cél az, hogy olya a hívó programmal ekvivales programot készítsük, ahol a szíjeles(i) em-megegedett kifejezés explicit módo egy l:=szíjeles(i) em-megegedett értékadásba kerüljö át. Ehhez be kell vezetük egy új logikai változót, és a hívó programot az alábbi változatok valamelyikére kell alakítauk. i, l:= 1, szíjeles(1) l:l i, l:= 0, hamis l:l l l i := i+1 i := i+1 l := szíjeles(i) l := szíjeles(i) 67

6.3. Példa. Egy iskola diákot számláló osztályába m külöböző tatárgyból osztályoztak a félév végé. Ezek a jegyek egy táblázat formájába redelkezésükre állak. (A diákokat és a tatárgyakat most sorszámukkal azoosítjuk.) Igaz-e, hogy mide diákak va legalább három tárgyból égyese? A feladat most egy "igaz-e, hogy mide elem olya, hogy..." típusú eldötés, ami az optimista lieáris keresés programozási tételére utal. Ebbe a keresésbe is a diákokat kell egymás utá megvizsgáli, de most a vizsgálat tárgya az, hogy va-e legalább három égyese az illetőek. Ehhez meg kell számoli mide diákál a égyes osztályzatok számát. Vegyük észre, hogy ezeket a számlálásokat em kell a feladatot megoldó optimista lieáris keresés előtt egy előfeldolgozással elvégezi, hisze a keresésbe midig csak az aktuális diák égyeseiek száma kell, amit ott helybe kiszámolhatuk, majd utáa el is felejthetük. Az így kapott megoldás emcsak a tárigéy és futási idő szempotjából lesz hatékoyabb, haem a program előállítása is egyszerűbb. Arra va csupá szükségük, hogy a égyesek számát előállító részfeladatot egy absztrakt függvéy mögé rejtsük. Ez a függvéy a táblázat i-edik sora alapjá megadja, hogy az i-edik diákak háy égyese va. Arra a kérdésre, hogy miért pot erre a fogalomra vezettük be egy új függvéyt miért em arra, hogy va-e legalább három égyese az i-edik diákak az a válasz, hogy az általuk választott függvéy kiszámolását közvetleül visszavezethetjük majd a számlálás programozási tételére. A feladat adatai hasolítaak az előző feladatéra, ami az állapottér, a paramétertér és az előfeltétel felírásába tükröződik: A = (t:n m, l:l ) Ef = ( t=t ) A feladat utófeltétele a kimeő adatkompoest írja le: az l akkor igaz, ha mide diákak három vagy aál több égyese va. Bevezetve a égyesdb függvéyt, amelyre a égyesdb(i) az i-edik diák égyeseiek számát adja meg a t táblázat i-edik sora alapjá, az utófeltétel az alábbi módo írható fel: Uf = ( Ef l = i [1..]: égyesdb(i) 3 ) = (Ef l search égyesdb ( i) 3)) ahol égyesdb : [1..m] N égyesdb(i) = m j 1 t[ i, j] 4 1 Ez a feladat egy optimista lieáris keresés: l,i:= igaz,1 l i l := égyesdb(i) 3 i := i+1 68

6.2. Beágyazott visszavezetés A visszavezetéssel előállított programba azoba az l:=égyesdb(i) 3 értékadás emmegegedett. Ha tüzetesebbe megvizsgáljuk az értékadás jobboldalá álló kifejezést, akkor észrevehetjük, hogy aak égyesdb(i) részkifejezése a em-megegedett. Készíthetük eek kiszámolására egy s:=égyesdb(i) értékadást megvalósított alprogramot, ahol az s egy darabszámot tartalmazó eredméy-változó. (Alteratív megoldás, ha a hívó programba bevezetük egy s:n segédváltozót, és az l:=égyesdb(i) 3 értékadást az (s:=égyesdb(i); l:=s 3) szekveciára botjuk fel.) Az s:=égyesdb(i) értékadás által kijelölt részfeladat specifikációja: A = (t:n m,, s:n ) Ef = ( t=t i=i [1..] ) Uf = ( Ef s = égyesdb(i) ) = ( Ef s = m j 1 t[ i, j] 4 Ez visszavezethető a számlálás programozási tételére az [1..m] itervallumo, és a (j)-t a t[i,j]=4 feltétel helyettesíti. A részfeladatot megoldó alprogram: 1 ) s:=égyesdb(i) s:=0 j :=1..m t[i,j]=4 s:=s+1 SKIP j:n 6.4. Példa. Egy iskola diákot számláló egyik osztályába m külöböző tatárgyból adtak jegyeket a félév végé. Ezek az osztályzatok egy táblázat formájába állak redelkezésükre. (A diákokat és a tatárgyakat most sorszámukkal azoosítjuk.) Számoljuk meg, háy kitűő diák va az osztályba! A szövegéből egyértelműe kiderül, hogy egy számlálással meg lehet oldai a feladatot. A számlálást a diákok között, tehát az [1..] itervallum felett végezzük, és azt a feltételt vizsgáljuk, amely megmodja egy diákról, hogy csupa ötöse va-e. Eek a feltételek a jelölésére a korábba már bevezetett szíjeles logikai függvéyt haszáljuk. ahol Lássuk a specifikációt! A = (t:n m, s:n) Ef = ( t=t ) Uf = ( Ef s = szíjeles( i) 1 ) 69

szíjeles : [1..] L szíjeles(i) = j [1..m] : t[i,j]=5 A feladatot tehát egy számlálásra vezetjük vissza az [1..m] itervallumo, és a (i) feltételt a szíjeles(i) helyettesíti. s:=0 i :=1.. szíjeles(i) s:=s+1 SKIP A szíjeles(i) em-megegedett feltétel kiértékelésére kézefekvő a korábba defiiált alprogram függvéyszerű hívásával. 6.5. Példa. Egy iskola diákot számláló egyik osztályába m külöböző tatárgyból osztályoztak a félév végé. Ezek a jegyek egy táblázat formájába állak redelkezésükre.(a diákokat és a tatárgyakat most sorszámukkal azoosítjuk.) Melyik diákak va a legtöbb égyese? Azokat a feladatokat, amelyekbe a "legtöbb", "legagyobb", "legdrágább", "legtávolabbi" stb. szófordulatokkal találkozuk, a maximum-kiválasztással társítjuk. (Természetese a "legkevesebb", "legagyobb", "legolcsóbb", "legközelebb" mellékevek a miimum-kiválasztásra utalak.) Eél a feladatál is a maximum-kiválasztás programozási tételét fogjuk haszáli. A maximum-kiválasztással társítható feladatok megítéléséél körültekitőe kell eljári. Egyfelől azért, mert hasoló szófordulatok jelezhetik a feltételes maximum kiválasztást is, ahol em egy itervallumhoz hozzáredelt összes elem között, haem csak bizoyos tulajdoságú elemek között keressük a maximumot. Másfelől a maximum-kiválasztásál ügyeli kell az előfeltételre, amely szerit a maximális elem kiválasztásához létezie kell legalább egy elemek, azaz az itervallum em lehet üres. Ilyekor vagy egy elágazásba építjük be a maximum-kiválasztást azért, hogy csak em-üres itervallum eseté kerüljö sor a maximum-kiválasztásra, vagy feltételes maximum kiválasztást haszáluk. Mivel egy iskolai osztályhoz biztos tartozak diákok, így a maximum-kiválasztás értelmes. A maximális értéket most em közvetleül egy itervallum potjai közül, haem az itervallum potjaihoz (azaz a diákokhoz) redelt értékek (egy diák égyeseiek száma) közül kell kiválasztai. Tehát téyleg maximum-kiválasztásról va szó. A feladatba jól körülvoalazódik az 6.3. példából már ismert részfeladat is, amely egy diák égyeseiek számát állítja elő. 70

6.2. Beágyazott visszavezetés A = (t:n m, id:n ) Ef = ( t=t >0 m>0 ) Uf = ( Ef égyesdb(id) = max égyesdb ( i) ) A feladatot egy maximum kiválasztásra vezetjük vissza, ahol az itervallum az [1..], és az f(i) kifejezést a égyesdb(i) helyettesíti. max,id:=égyesdb(1),1 i :=2.. max<égyesdb(i) max,id:= égyesdb(i), i SKIP max:n Mivel redelkezük az s:=égyesdb(i) alprogrammal, amelyet speciálisa a égyesdb(1) kiszámolására is felhaszálhatuk, léyegébe késze vagyuk. Hatékoysági okból azoba célszerű a ciklusmagba a égyesdb(i)-t egy értékadásba kiemeli, mert az i így egy rögzített értékére em kell a égyesdb(i) értékét kétszer is kiszámoli, elég lesz azt csak egyszer megtei. max,id:=égyesdb(1),1 i :=2.. s:=égyesdb(i) max<s max,id:=s,i SKIP max:n s:n 6.6. Példa. Egy iskola diákot számláló egyik osztályába m külöböző tatárgyból osztályoztak a félév végé. Ezek a jegyek egy táblázat formájába állak redelkezésükre.(a diákokat és a tatárgyakat most sorszámukkal azoosítjuk.) Ki az a diák, aki a csak 4-es illetve 5-ös osztályzatú diákok között a legjobb átlagú? Ha va ilye, adjuk meg az átlagát is! Ez a feladat egy feltételes maximumkereséssel oldható meg, hisze csak az adott tulajdoságú diákok átlagai között keressük a legjobbat. 1 Eze belül öálló részfeladatot alkot aak eldötése, hogy egy diák csak 4-es illetve 5-ös osztályzatú-e, illetve öálló részfeladat 1 Itt hívjuk fel a figyelmet az olya feladatokra is, amelyekbe egy itervallum potjai között keressük a legagyobb adott tulajdoságút. Ilye például a legagyobb közös osztó keresése. Ezeket a feladatokat em érdemes feltételes maximumkeresésre visszavezeti, tökéletese megfelel az itervallumba egy fordított iráyú kiválasztás vagy lieáris keresés is. 71

egy diák átlagáak kiszámolása is. Az előbbi a feltételes maximum keresés feltételét adja, az utóbbi a maximumkeresésél haszált f függvéyt. Ezeket a részfeladatokat egy-egy absztrakt függvéyel jelöljük ki. Bevezetjük a "csak 4-es illetve 5-ös osztályzatú" tulajdoságot eldötő jó logikai függvéyt, amely az i-edik diák eseté akkor ad igaz értéket, ha a táblázat i-edik sorába csak égyesek vagy ötösök állak. Bevezetjük továbbá az összeg függvéyt, amely megadja az i-edik diák jegyeiek összegét. Azért az összegét, és em az átlagát, mert a maximum keresés szempotjából ez léyegtele. Természetese a végeredméy előállításához külö kell majd godoskodi a legjobb diák átlagáak kiszámolásáról. A = (t:n m, l:l, id:n, átl:r ) Ef = ( t=t ) Uf = ( Ef l,max,id = max összeg( i) (l átl=max/) ) jó( i) ahol és jó:[1..] L jó(i) = j [1..m] : (t[i,j]=5 t[i,j]=4) összeg:[1..] N összeg(i) = m t [ i, j ] j 1 A feladat az utófeltétel alapjá két részre botható: egy [1..] itervallumú, jó(i) feltételű és összeg(i) függvéyű feltételes maximumkeresések, valamit egy elágazásak a szekveciájára. Az elágazás feltétele az l, igaz ága az átl:=max/ értékadás, hamis ága a SKIP lesz. l:=hamis i :=1.. jó(i) l jó(i) l jó(i) SKIP max<összeg(i) l, max, id := átl:=max/ max, id:= összeg(i), i l SKIP SKIP igaz, összeg(i), i max:n 72

6.2. Beágyazott visszavezetés A jó(i) kiszámolásához az u:=jó(i) értékadást megoldó alprogramra va szükség, ahol az u egy logikai változó. A u:=jó(i) értékadás egy optimista lieáris kereséssel oldható meg, amelybe futóidexek a j-t haszáljuk. Ezt érdemes a hatékoyság érdekébe kiemeli. A hatékoyság érdekébe a ciklusmag elágazásáak középső ágába az össz:=összeg(i) kiemelést is mideképpe tegyük meg. Ez az értékadás egy összegzéssel oldható meg. u:=jó(i) össz:=összeg(i) u,j:= igaz,1 össz:=0 u j m j:n j := 1..m j:n u := t[i,j]=5 t[i,j]= össz:= össz +t[i,j] 4j := j+1 l:=hamis i :=1.. u:=jó(i) u l u l u SKIP összeg := összeg(i) l, max, id := max<összeg igaz, összeg(i), i max, id:= összeg, i SKIP l átl:=max/ SKIP u:l összeg,max:n 6.7. Példa. Adott egy egész számokat tartalmazó vektor, és aak egy k idexe úgy, hogy a k legalább 2. (Ekkor ez a k idex két em üres részre vágja ketté a vektor elemeit.) Igaz-e, hogy va olya elem a megadott idex előtt a vektorba, amelyik agyobb vagy egyelő az idextől kezdődő elemek midegyikéél! A feladat talá em tűik túl érdekesek, de a gyakorlás szempotjából ézve ige haszos, mert agyo sokféleképe lehet megoldai. A feladat állapottere, előfeltétele köye megfogalmazható: A = (t:z, k:n, l:l) Ef = ( v=v k=k k 2 ) Az utófeltétel azoba számos más-más programot eredméyező változatba lehet felíri. Ezek közül bemutatuk éháyat. Az egyes utófeltételekhez tartozó programok megadását az olvasóra bízzuk. 73

Az első megoldás a feladat szószeriti értelmezéséből születik: "Va olya elem a vektor első részébe, amelyik a vektor hátsó részéek midegyik eleméél agyobb vagy egyelő." A feladatot tehát egy lieáris keresésbe ágyazott optimista kereséssel oldhatjuk meg. Eek specifikációját láthatjuk itt: Uf = ( Ef l= i [1..k 1]: j [k..]: v[i] v[k] ) A megoldásba szereplő két programozási tétel egymáshoz való viszoya megcserélhető. A feladat úgy is megfogalmazható, hogy igaz-e, hogy a vektor hátsó részéek mide eleme kisebb, a vektor első részéek legalább egy eleméél. Ilyekor a megoldás egy optimista lieáris keresésbe ágyazott lieáris keresés lee. Ez rávilágít arra, hogy a két részfeladat ics alá- illetve föléredelt viszoyba. Eek a két változatak a futási ideje (a v[i] és v[j] elemek összehasolításaiak száma) legrosszabb esetet feltételezve: (k 1)*( k+1). A második megoldás már egy kis ötletet igéyel: Ha a vektor első részéek legagyobb eleme agyobb vagy egyelő a hátsó rész legagyobb eleméél, akkor va az első részbe olya elem, amelyik a hátsó rész mide eleméél agyobb vagy egyelő. Nem kell mást tei, mit a vektor első részébe is, és a hátsó részébe is kiválasztai a maximális elemet, és a kapott maximumokat összehasolítai. Itt tehát két maximum-kiválasztásak, és egy összehasolításak a szekveciájáról va szó. Ebből az is kiolvasható, hogy ehhez a változathoz potosa összehasolítást kell végezi. k 1 Uf = ( Ef l = max v[ i] max v[ j] ) j k A harmadik megoldás is a maximum-kiválasztással kapcsolatos, de új ötlete alapul. Válasszuk ki a maximális elemet a vektorból úgy, hogy a maximum-kiválasztás több maximális elem eseté a legelsőek az idexét adja meg. Ha ez az idex a vektor első részébe esik, akkor igelő választ adhatuk a feladat kérdésére. A vektor első részébe eső maximális elem ugyais mide elemél agyobb vagy egyelő, így a vektor hátsó részéek elemeiél is. Ehhez a megoldáshoz csak úgy, mit az előzőhöz potosa összehasolítást kell végezi. Uf = ( Ef max, id = max v[ i] l = id<k ) A egyedik megoldás az eredeti megfogalmazáshoz yúl vissza: a vektor első részébe keres alkalmas tulajdoságú elemet. Az alkalmasságot azoba és itt a második megoldás ötlete jeleik meg újra a hátsó rész legagyobb elemével való összehasolítással dötjük el: keresük az első részbe a hátsó rész maximális eleméél agyobb vagy egyelő elemet. Az Uf = ( Ef l = i [1..k 1]: v[i] max v[ j] ) j k utófeltétel azoba ügyetle, mert a lieáris keresésbe ágyazza be a maximum-kiválasztást, holott a hátsó rész maximum-kiválasztása függetle a kereséstől az első és hátsó rész feldolgozása ics alá- illetve föléredelt viszoyba, ezért elég, ha a maximumkiválasztást a lieáris keresés előtt (szekveciába) egyszer végezzük el: 74

6.2. Beágyazott visszavezetés Uf = ( Ef max = max v[ j] j k l = i [1..k 1]: v[i] max ) Ebbe a megoldásba az összehasolítások száma legrosszabb esetbe is csak 1 lesz. 6.3. Program-átalakítások Az előző feladat-megoldásokba gyakra alkalmaztuk program-átalakításokat. A program-átalakítás sorá egy programból egy olya másik programot állítuk elő, amely megoldja midazokat a feladatokat, amelyeket az eredeti program is megold. Ezt gyakra ekvivales átalakítással értjük el, azaz úgy, hogy az új program hatása megegyezik az eredeti program hatásával. Sok esetbe viszot megelégszük azzal, hogy az új program megoldja az eredeti program hatása által kijelölt feladatot. Nyilvávaló, hogy midkét esetbe az új program mide olya feladatot megold majd, amit az eredeti program meg tud oldai. Példakét emlékeztetük arra, ahogya 6.2. példába a kiválasztás programozási tételét kétféleképpe is átalakítottuk azért, hogy explicit módo egy értékadásba emeljük ki a ciklusfeltételébe szereplő em-megegedett kifejezést. Egy-egy program-átalakításak a helyessége a programozási modellük eszközeivel belátható, de itt em bizoyítjuk be az alkalmazott program-átalakítás helyességét, haem a lustább látszik rajta, hogy jó magyarázatot haszáljuk. Egy program-átalakításak ige sokféle célja lehet. Esetekét csak szebbé, áttekithetőbbé akarjuk formáli a programukat, éha az implemetáció, azaz a kokrét számítógépes köryezetbe ültetés végett va rá szükség. A program-átalakítással a programok hatékoyságá is lehet javítai feltéve, hogy defiiáljuk a hatékoyság fogalmát. Habár az előbb felsorolt szempotok (hatékoyság, implemetálás, áttekithetőség) mid fotosak, a program-átalakítás számukra elsősorba abból a szempotból érdekes, hogy meyibe segíti a program előállítását a programtervezés fázisába. Láthattuk, hogy a részfeladat kijelölését támogató átalakítások a programtervezést támogató eszközök. Ebbe a fejezetbe em is egy olya megoldással találkoztuk, ahol egy új változó bevezetéséek segítségével emeltük ki em-megegedett kifejezést, feltételt egy értékadásból, vagy egy elágazásak a feltételéből illetve programágából, esetleg egy ciklus feltételéből. Programtervezést támogató átalakításokak tekitjük a rekurzív függvéyek kiemelését is, amelyre több példát is láthattuk az előző alfejezetbe. A szimultá értékadás egyszerű értékadások szekveciájára törtéő felbotása a részfeladat kijelöléssel (lásd 6.5. példa) támogathatja a programtervezést is, de többyire egy implemetálást támogató átalakítás, ameyibe egy olya programozási yelve kell leíruk a programukat, amelyik em ismeri (és többyire em ismerik) a szimultá értékadást. Eddig többyire olya szimultá értékadásokkal találkoztuk, amelyet alkotó egyszerű értékadások függetleek voltak egymástól. Egy egyszerű értékadás akkor függ egy másiktól, ha a jobboldali kifejezésébe szerepel a másik értékadás baloldali változója. Ha ilye függés em áll fe a szimultá értékadást alkotó egyszerű értékadások között, akkor azokat tetszőleges sorredbe végrehajtva a szimultá értékadással azoos hatású szekveciához jutuk. Ha va függő viszoy, de ezek redszere em alkot kört, akkor az egyszerű értékadásokat olya sorredbe kell végrehajtai, hogy előre azt az egyszerű 75

értékadást vesszük, amelyiktől seki más em függ, majd midig azt, amelyiktől csak az előtte végrehajtottak függek. Egy teljese általáos szimultá értékadás felbotásához azoba amelybe mide egyszerű értékadás mide egyszerű értékadástól függ új változókra va szükség: x 1,, x := F 1 (x 1,, x ),, F (x 1,, x ) helyett y 1 :=x 1 y 1 :=x 1 y -1 :=x -1 y -1 :=x -1 x 1 :=F 1 (x 1, x 2,, x -1, x ) vagy x 1 :=F 1 (y 1, y 2,, y -1, x ) x 2 :=F 2 (y 1, x 2,, x -1, x ) x 2 :=F 2 (y 1, y 2,, y -1, x ) x -1 :=F -1 (y 1, y 2,, y -1, x ) x -1 :=F -1 (y 1, y 2,, y -1, x ) x :=F (y 1, y 2,, y -1, x ) x :=F (y 1, y 2,, y -1, x ) Program hatékoyságát támogató átalakítások közé soroljuk a külöféle összevoási és kiemelési szabályokat. Összevoással találkozhattuk a 6.8. példába, amikor egymáshoz hasoló ciklusok szekveciájából egyetle ciklust készítettük úgy, hogy az új ciklus magja az eredeti ciklusmagok szekveciája lett. Majd ugyaitt az új ciklusmag sok kétágú elágazást tartalmazó szekveciáját egyetle sokágú elágazássá votuk össze. (Az már a példa specialitása volt, hogy ezt a sokágú elágazást egy értékadással helyettesíthettük.) A rekurzív függvéy kiemelése is a hatékoyságot támogatta. Kiemelési szabály alkalmazására mutat speciális példát az alábbi átalakítás: i := 0..10 S 1 i=0 helyett i :=1..10 S 1 S 2 S 2 Összevoásra példa az, amikor egymás utá szekveciába több ugyaolya lépésszámú ciklust kell végrehajtai úgy, hogy eze ciklusok eredméye ics egymásra hatással. Ilyekor egyetle ciklussal helyettesíthetjük a ciklusok szekveciáját, ahol a ciklusmag a korábbi ciklusok magjaiak szekveciája lesz. Az összevoásokkal illetve kiemelésekkel emcsak hatékoyságot lehet javítai, haem a program áttekithetőségé, olvashatóságá is. Az alábbi példa jól illusztrálja ezt. 76

6.3. Program-átalakítások 6.8. Példa. Soroljuk fel azokat a műkorcsolyázó verseyzőket, akik holtverseybe az első helye végeztek a kötelező gyakorlatuk bemutatása utá. Az verseyző programját m tagú zsűri potozta, amelyből egy verseyző összesített potszámát úgy kapjuk, hogy a legjobb és legrosszabb potot elvéve a többi potszám átlagát képezzük. A = (t:r m, s:n * ) Ef = (t=t >0 m>2) Uf = (Ef s = pot( i) max i max = max pot(i) ) m ahol pot:[1..] R és pot(i) = ( t[ i, j] - max t[ i, j] - mi t[ i, j] )/(m-2) Az előfeltételbeli megszorítást a pot(i) kiszámításáál törtéő m-2-vel való osztás, valamit a végrehajtadó maximum kiválasztások idokolják. Az utófeltételbe bevezettük egy max:r változót. Világos, hogy először eek az értékét kell meghatározi, és csak ezutá tudjuk a kiválogatást elvégezi. A megoldás tehát egy maximum kiválasztás és egy összegzés (kiválogatás) szekveciája lesz, amelyeke belül a pot(i)-t egy összegzés, egy maximum és egy miimum kiválasztás segítségével határozhatjuk meg. m j 1 m j 1 max:= pot(1) max:r d := pot(i) i := 2.. o:= 0 o:r d := pot(i) d:r j := 1..m j:n d>max o := o+t[i,j] max:= d SKIP maxi := t[i,1] maxi:r s:= <> j := 2..m i := 1.. t[i,j]>maxi max = pot(i) maxi:= t[i,j] SKIP s:=s <i> SKIP mii := t[i,1] mii:r j := 2..m t[i,j]<mii mii:= t[i,j] SKIP d := (o-maxi-mii)/(m-2) Az így kapott program azoba jeletőse javítható. Egyrészt összevohatjuk a pot(i)-t kiszámoló három programozási tételt egyetle ciklusba. Ehhez az összegzés ciklusát is (j=2..m) formájúra kell alakítai. Másrészt bevezethetük egy új adatot, a verseyzők potszámait tartalmazó p:r tömböt, amelyet a program elejé feltöltük a pot(i) értékekkel, 77

hogy később midehol a pot(i) helyett a p[i]-t haszálhassuk. A p tömb feltöltése, azaz a i [1..]:p[i]=pot(i) feladat léyegébe egy p= pot(i) összegzés lesz, amely viszot összevoható a max értékét meghatározó maximum kiválasztással, ha az összegzés ciklusát is (i=2..) formájúra alakítjuk. Az átalakítással kapott változat az alábbi: max, p = iicializálás s:= <> i := 1.. max=p[i] s:=s <i> SKIP p:r, max:r max, p := iicializálás d := pot(i) maxi, mii, max, p[1] := t[1,1], pot(1) o,maxi,mii := t[i,1], t[i,1], t[i,1] o:r i := 2.. j := 2..m j:n p[i]:=pot(i) o := o+t[i,j] p[i]>max t[i,j]>maxi max:= p[i] SKIP maxi:= t[i,j] SKIP t[i,j]<mii mii:= t[i,j] SKIP d := (o-maxi-mii)/(m-2) 78

6.3. Rekurzív függvéy kibotása 6.4. Rekurzív függvéy kibotása A beágyazott visszavezetésekél láthattuk, hogy a problémamegoldás sorá egy-egy új függvéyek a bevezetése meyire jól szolgálja egy feladat részfeladatokra botását. Az ilye függvéyek kitalálása, absztrakciója a visszavezetéses techika alkalmazásáak katalizátora. Ebbe az alfejezetbe olya szellemes, trükkös megoldásokat mutatuk be, amelyekhez úgy jutuk, hogy a visszavezetés sorá bevezetett absztrakt függvéyek rekurzív függvéyek leszek. A bemutatott megoldásokba azoba ezeket a rekurzív függvéyeket sokszor em a rájuk voatkozó programozási tétellel számítjuk ki, haem egy ügyes programátalakítási techikát alkalmazuk. 6.9. Példa. Két táblázat (be és ki vektorok) azt mutatja, hogy az i-edik órába háy látogató értkezett egy múzeumba (be[i]) és háy látogató távozott (ki[i]) a múzeumból. Melyik órába (óra végé) volt a legtöbb látogató a múzeumba? (Feltehetjük, hogy az adatok em hibásak.) Feltehetjük, hogy kezdetbe üres volt a múzeum. Az első óra végé be[1]-ki[1] látogató volt bet. A második órába ehhez hozzájött még be[2] látogató, és elmet ki[2]; tehát a második óra végé be[1]-ki[1]+be[2]-ki[2] látogató volt bet. Így tovább folytatva megkostruálhatuk egy függvéyt, amelyik azt mutatja meg, hogy az i-edik óra végé háy látogató volt be a múzeumba. Ezt a függvéyt összegzéskét is megfogalmazhaták, de legkéyelmesebbe egy rekurzív defiícióval adhatjuk meg: az i-edik óra végé a múzeumba levő látogatók száma az i-1-edik óra végé be levők plusz az i-edik órába érkezők (be[i]), miusz a távozók száma (ki[i]). f:[1..] N f(1) = be[1]-ki[1] f(i) = f(i 1)+be[i] ki[i] i [2..] A feladat ezek utá az, hogy keressük meg, hol veszi fel ez a függvéy a maximumát. Eek megfelelőe a specifikáció: A = (be:n, k, id:n) Ef = ( be=be ki=ki ) Uf = ( Ef id=( max f (i) ) id ) A feladatot visszavezetjük a maximum kiválasztás programozási tételére max,id:=f(1),1 i := 2.. max<f(i) max,id:= f(i), i SKIP max:n 79

Amely ciklusmagjába egy rekurzív függvéy értékét kell kiszámoli. Ezt azoba hatékoysági okból most e egy olya alprogrammal végezzük el, amely a rekurzív függvéy helyettesítési értékét számolja ki, haem egy speciális techikát a rekurzív függvéy kibotását alkalmazzuk. Eek alapötlete az, hogy az f(i) kiszámolásához felhaszálja a ciklusmag előző végrehajtásakor kiszámoltuk f(i-1)-et, hisze az f egy rekurzív függvéy. Emeljük ki a em-megegedett f(1) illetve f(i) kifejezéseket egy s segédváltozó segítségével egy értékadásba. s:=f(1) max,id:=s,1 i := 2.. s:=f(i) max<s max,id:=s, i SKIP s:n max:n Az f(1) kifejezés az f függvéy defiíciója alapjá yilvá helyettesíthető a megegedett be[1]-ki[1] kifejezéssel. Köyű beláti továbbá azt, hogy a feti ciklus ivariás állítása kiegészíthető az s=f(i 1) feltétellel. Ez a feltétel a ciklus előtti s:=be[1]-ki[1] értékadás miatt már a ciklusba lépéskor teljesül. A ciklusmag lefutása utái fe állását pedig az s:=f(i) értékadás és az utáa végrehajtódó i:=i+1 értékadás együttese biztosítja. Kihaszálva, hogy a ciklusmag elejé s=f(i 1), valamit hogy az f(i) kifejezés az s+be[i] ki[i] kifejezéssel helyettesíthető, az s:=f(i) értékadás az s:=s+be[i] ki[i] értékadással kiváltható. Ezek alapjá a program végleges változata már köye elkészíthető. s:= be[1]-ki[1] max,id:=s,1 i := 2.. s:= s+be[i] ki[i] max<s max,id:=s, i SKIP s:n max:n 6.10. Példa. Egy repülőgéppel elrepültük a Csedes Óceá szigetvilágáak egy része felett, és meghatározott távolságokét megmértük a felszí tegerszit feletti magasságát. Az így kapott em-egatív valós értékeket egy hosszúságú x vektorba tároljuk. Adjuk meg a mérések alapjá, hogy mekkora a leghosszabb sziget, és a repülés háyadik méréséél kezdődik illetve végződik ezek közül az egyik. 80

6.3. Rekurzív függvéy kibotása Eek a feladatak többféle megoldása is va, amelyek közül most egy rekurzív függvéyt bevezető megoldást ismertetük. Képzeljük el azt a függvéyt, amelyik a repülés sorá végzett mérési potoko va értelmezve; sziget felett azt mutatja meg, hogy a sziget kezdete óta háy mérési potot tett meg a repülő, a teger felett viszot ulla az értéke. f:[0..] N f(0) = 0 f ( i 1) 1 ha x[ i] 0 f(i) = 0 ha x[ i] 0 i [1..] A feladat megoldásához elég eek a függvéyek megtaláli a maximumát. Ahol ez a függvéy a maximális értékét felveszi, ott va a leghosszabb sziget végpotja, amelyből és a szigethosszából a sziget kezdőpotja is köye meghatározható. (Megjegyezzük, hogy ha a rekurzív függvéyt em a vektor elejéről hátrafelé haladva képezék, haem a végéről az eleje felé, akkor egy ugyacsak hátulról előre haladó maximum-kiválasztással közvetleül a leghosszabb sziget elejét találák meg.) A = (x:n, hossz:n, kezd:n, végz:n ) Ef = ( x=x ) Uf = ( Ef hossz,végz = max f ( i) kezd=végz hossz+1) A feladat maximum kiválasztás és egy értékadás szekveciájával oldható meg. h:=f(1) hossz,id:=h,1 i := 2.. h:=f(i) hossz<h hossz,id:=h, i SKIP kezd := végz hossz+1 h:n A maximum-kiválasztásba a em-megegedett f(i) kifejezéseket egy segédváltozó segítségével kiemeltük. A h:= f(1) egy elágazással helyettesíthető; ha x[1] pozitív, akkor az f(1) értéke 1 lesz, külöbe 0. Mivel a h mid a ciklus előtt, mid a ciklusmag végrehajtásai utá az f(i 1) értéket tartalmazza, az f(i) értéke a rekurzív képlet alapjá egy elágazással egyszerűe kiszámítható. A program végleges változata: 81

x[1]>0 h:=1 h:=0 h:n hossz,id:=h,1 i := 2.. x[i]>0 h:= h+1 h:=0 hossz<h hossz,id:=h, i SKIP kezd := végz hossz+1 6.11. Példa. Egy m hosszúságú karakterekből álló sorozatot (evezzük ezt szövegek) kódoli szereték egy másik, hosszúságú karaktersorozat (evezzük ezt táblázatak) segítségével. A kód egy olya m hosszúságú szigorúa övekedő számsorozat legye, amelyikek i-edik értéke idexkét mutat a táblázatak arra a karakterére, amely éppe a szöveg i-edik karaktere. Dötsük el, va-e ilye kód egy adott szöveghez és táblázathoz. A feladat megoldásához azt kell megvizsgáli, hogy a szöveg mide karaktere megfelelőe kódolható-e. A = (szöveg:k m, tábla:k, l:l) Ef = ( szöveg=szöveg tábla=tábla ) Uf = ( Ef ( l= i [1..]: kódolható(i) ) ) A szöveg[i]-t a táblázat akkor kódolja, ha az bee va a táblázatba, mégpedig azo karakter utá, amelyikkel a szöveg[i-1]-et kódoltuk. Ha tehát ismerjük, hogy a táblázat háyadik karakterével (jelöljük ezt j-vel) kódoltuk a szöveg[i-1]-et, akkor a táblázatba a j+1- edik pozíciótól elidulva kell megkeresi a szöveg[i]-t. Ha találuk ilyet, akkor a szöveg[i] kódolható és a találat pozíciója lesz majd a következő keresés kiiduló potja, az új j. Ide tehát egy olya lieáris keresés kell, amelyik em a teljes táblázatba, haem csak aak j+1- edik idexétől keres. Vezessük be egy rekurzív defiíciójú függvéyt eek a lieáris keresések a leírására. Tekitettel a lieáris keresés kétféle kimeetelére, a rekurzív függvéy is kétértékű, két kompoesű lesz. Az f(i) első kompoese (f(i) 1 ) egy logikai érték, amely azt mutatja meg, hogy sikerült-e a szöveg[i]-t kódoli; a második kompoes (f(i) 2 ) pedig a táblázat azo idexe, amelyik pozíció a táblázatba a a szöveg[i]-t találjuk. Ezt a két értéket az a lieáris keresés állítja elő, amelyik az előző sikeres lieáris keresés által talált pozíció (f(i-1) 2 ) utái helyről idít egy j idexet, és keresi a szöveg[i]=tábla[j] feltételek eleget tevő j-t. A rekurzív függvéyt a 0-ba is defiiáljuk, egybe ez lesz a függvéy bázisa. 82

6.3. Rekurzív függvéy kibotása i [1..m] f : [0..m] L N f(0)= (igaz, 1) f(i) = search szöveg[ i] tábla[ j] j f2 ( ) A korábba bevezetett kódolható(i) feltétel tehát megegyezik a rekurzív függvéy i-edik helye felvett logikai értékével. Eek megfelelőe a feladat utófeltétele: Uf = ( Ef (l= i [1..m]: f 1 (i)) ) Formába is írható, amelyből látható, hogy egy optimista lieáris keresésbe ágyazott rekurzív függvéyel oldható meg a feladat. A megoldás sorá a rekurzív függvéyt természetese kiemeljük majd egy l logikai változó és egy j egész változó segítségével. i,l:=1,igaz i,l,j:=1, igaz, 1 i,j:n l i m l:=f 1 (i) i:=i+1 l i m l,j:= search szöveg[ i] tábla[ j] j i:=i+1 Az első megoldás tehát: i,l,j:=1,igaz,1 l i m l:=hamis l j l:=szöveg[i]=tábla[j] j:=j+1 i:=i+1 i,j:n Ameyibe a rekurzív függvéyre azt is megköveteljük, hogy ha f 1 (i) valamely i-re hamis, akkor az f 2 (i) legye az (a lieáris keresés éppe így működik), akkor ameyibe az szöveg i-dik karaktere már em kódolható, akkor az i-re és az azt követő összes egészre a hamis értéket adja majd, speciálisa az -re is. Ezért az utófeltétel az alábbi formába is megfogalmazható: 83

Uf = ( Ef l=f 1 (m) ) Ez egy rekurzív függvéy adott helye felvett helyettesítési értékéek kiszámításáak programozási tételére vezethető vissza, amely egy másik megoldását adja a feladatak. Megjegyezzük, hogy ez a megoldás futási idő szempotjából rosszabb az előzőél. l,j:=igaz,1 i :=1..m l:=hamis l j l:=szöveg[i]=tábla[j] j:=j+1 j:n Keressük most egy harmadik megoldást! Vezessük be egy másik f függvéyt, ahol az f(j) azt mutatja meg, hogy a táblázat első j darab elemével a szöveg háy karakterét sikerült már eddig kódoli. Ha az f() felveszi a szöveg hosszát értékül, akkor ez azt jeleti, hogy a szöveg kódolható a táblázattal. Uf = ( Ef l = (f()=m) ) Az f függvéyt most is rekurzív módo lehet legegyszerűbbe defiiáli. Ehhez először azt kell láti, hogy a táblázat első ulla darab elemével egyetle szövegbeli karaktert sem lehet kódoli, azaz f(0)=0. Ha feltesszük, hogy ismerjük azt a számot (f(j 1)), hogy háy karakter kódolható a táblázat első j 1 elemével, akkor az a kérdés, hogy a j-edik elemmel kódolható-e a szöveg soro következő eleme, a szöveg[f(j 1)]. Ha ige, akkor f(i) = f(j 1)+1. f:[0..] N f(0)= 0 f ( j 1) 1ha f ( j 1) m tábla[ j] szöveg[ f ( j 1) 1] f(j) = f ( j 1) külöbe j [1..] A feladatot az f függvéy értéke kiszámolásáak és egy értékadásak a szekveciájával lehet megoldai. Az első részt a rekurzív függvéy helyettesítési értéke kiszámításáak programozási tételére vezetjük vissza. i:=0 j :=1.. tábla[j]=szöveg[i+1] i:=i+1 SKIP l:=i=m j:n 84

6.3. Rekurzív függvéy kibotása A hatékoyabb egyedik megoldáshoz úgy juthatuk, ha észrevesszük azt, hogy ics midig szükség a rekurzív függvéy -edik helye felvett értékére, hisze ha a függvéy korábba felveszi az m-et, akkor az már a sikeres kódolás jele. Eek megfelelőe az utófeltétel: Uf = ( Ef l = j [1..]: f(j)=m ) A feladat most visszavezethető a lieáris keresés programozási tételére, amelyből kiemeljük a rekurzív függvéyt. l,j:=hamis,1 j:n l,j,i:=hamis,1,0 i,j:n l j l j l:= f (j)=m t[j]=sz[i+1] j:=j+1 i:=i+1 SKIP l:=i=m j:=j+1 85

6.5. Feladatok 6.1. Volt-e a lóverseye olya apuk, amikor úgy yertük, hogy a megelőző k apo midig veszítettük (Oldjuk meg kétféleképpe likerbe a liker, likerbe rekurzív függvéy) 6.2. Egymást követő apoko délbe megmértük a levegő hőmérsékletét. Állapítsuk meg, hogy melyik érték fordult elő leggyakrabba! 6.3. A toraórá évsor szerit sorba állítottuk a diákokat, és megkérdeztük a testmagasságukat. Háyadik diákot előzi meg a legtöbb ála magasabb? 6.4. Állapítsuk meg, hogy egy adott szó (egy karakterlác) előfordul-e egy adott szövegbe (egy másik karakterlácba)! 6.5. Keressük meg a t égyzetes mátrixak azt az oszlopát, amelybe a főátlóbeli és a feletti elemek összege a legagyobb! 6.6. Egy határállomáso feljegyezték az átlépő utasok útlevélszámát. Melyik útlevélszámú utas fordult meg leghamarabb másodszor a határo? A feladat kétféleképpe is értelmezhető. Vagy azt az utast keressük, akiről legelőször derül ki, hogy korábba már átlépett a határo, vagy azt, akiek két egymást követő átlépése közt a lehető legkevesebb másik utast találjuk. 6.7. Egymást követő hétvégeke feljegyeztük, hogy a lóverseye meyit yertük illetve veszítettük (ez egy előjeles egész szám). Háyadik héte fordult elő először, hogy az összesített yereségük (az addig yert illetve veszített pézek összege) egatív volt? 6.8. Dötsük el, hogy egy természetes számokat tartalmazó mátrixba a) va-e olya sor, amelybe előfordul prím szám (va-e a mátrixba prím szám) b) va-e olya sor, amelybe mide szám prím c) mide sorba va-e legalább egy prím d) mide sorba mide szám prím (a mátrix mide eleme prím) 6.9. Egy kutya kiállításo kategóriába m kutya vesz részt. Mide kutya mide kategóriába egy 0 és 10 közötti potszámot kap. Va-e olya kategória, ahol a kutyák között holtversey (azoos potszám) alakult ki? 6.10. Madarak életéek kutatásával foglalkozó szakemberek külöböző települése m külöböző madárfaj előfordulását taulmáyozzák. Egy adott időszakba megszámolták, hogy az egyes települése egy madárfajak háy egyedével találkoztak. Háy települése fordult elő midegyik madárfaj? 86