You are on page 1of 336

Gregorics Tibor

PROGRAMOZS
1. ktet

TERVEZS

egyetemi jegyzet

2011

ELSZ

TARTALOM
ELSZ ...................................................................................................................... 4 BEVEZETS .............................................................................................................. 6 I. RSZ PROGRAMOZSI FOGALMAK ............................................................. 9 1. ALAPFOGALMAK................................................................................................. 10 1.1. Az adatok tpusa ......................................................................................... 10 1.2. llapottr ................................................................................................... 14 1.3. Feladat fogalma ......................................................................................... 15 1.4. Program fogalma ....................................................................................... 17 1.5. Megolds fogalma ...................................................................................... 21 1.6. Feladatok ................................................................................................... 25 2. SPECIFIKCI...................................................................................................... 28 2.1. Kezdllapotok osztlyozsa...................................................................... 28 2.2. Feladatok specifikcija ............................................................................ 31 2.3. Feladatok ................................................................................................... 37 3. STRUKTURLT PROGRAMOK ............................................................................... 38 3.1. Elemi programok ........................................................................................ 40 3.2. Programszerkezetek ................................................................................... 43 3.3. Helyes program, megengedett program ..................................................... 55 3.4. Feladatok ................................................................................................... 58 II. RSZ PROGRAMTERVEZS MINTK ALAPJN .................................... 61 4. PROGRAMOZSI TTELEK ................................................................................... 63 4.1. Analg programozs .................................................................................. 64 4.2. Programozsi ttel fogalma ....................................................................... 69 4.3. Nevezetes mintk ........................................................................................ 72 4.4. Feladatok ................................................................................................... 84 5. VISSZAVEZETS .................................................................................................. 85 5.1. Termszetes visszavezets .......................................................................... 85 5.2. ltalnos visszavezets ............................................................................... 86 5.3. Alteres visszavezets ................................................................................... 87 5.4. Paramteres visszavezets.......................................................................... 91 5.5. Visszavezetsi trkkk ................................................................................ 94 5.6. Rekurzv fggvny kiszmtsa ................................................................... 99 5.7. Feladatok ................................................................................................. 105 6. TBBSZRS VISSZAVEZETS ........................................................................... 106 6.1. Alprogram ................................................................................................ 108 6.2. Begyazott visszavezets .......................................................................... 111 6.3. Program-talaktsok .............................................................................. 129 6.4. Rekurzv fggvny kibontsa .................................................................... 136 6.5. Feladatok ................................................................................................. 147 III. RSZ TPUSKZPONT PROGRAMTERVEZS................................... 149

ELSZ

7. TPUS ................................................................................................................ 151 7.1. A tpus fogalma ........................................................................................ 152 7.2. Tpus-specifikcit megvalst tpus ...................................................... 157 7.3. Absztrakt tpus .......................................................................................... 162 7.4. Tpusok kztti kapcsolatok ..................................................................... 171 7.5. Feladatok ................................................................................................. 180 8. PROGRAMOZSI TTELEK FELSOROL OBJEKTUMOKRA ................................... 181 8.1. Gyjtemnyek ........................................................................................... 183 8.2. Felsorol tpus specifikcija .................................................................. 185 8.3. Nevezetes felsorolk ................................................................................. 188 8.4. Programozsi ttelek ltalnostsa ........................................................ 194 8.5. Visszavezets nevezetes felsorolkkal ...................................................... 204 8.6. Feladatok ................................................................................................. 216 9. VISSZAVEZETS EGYEDI FELSOROLKKAL ....................................................... 217 9.1. Egyedi felsorol ....................................................................................... 218 9.2. Felttel fennllsig tart felsorols ....................................................... 219 9.3. Csoportok felsorolsa .............................................................................. 222 9.4. sszefuttats ............................................................................................ 234 9.5. Rekurzv fggvny feldolgozsa ............................................................... 248 9.6. Felsorol gyjtemny nlkl .................................................................... 254 9.7. Feladatok ................................................................................................. 257 10. FELADATOK MEGOLDSA ............................................................................... 260 IRODALOM JEGYZK ....................................................................................... 336

ELSZ
Ez a knyv az Etvs Lornd Tudomnyegyetem programtervez informatikus szaknak azon tantrgyaihoz ajnlom, amelyeken a hallgatk az els benyomsaikat szerezhetik meg a programozs szakmjrl. A knyvre ersen rnyomja blyegt az a gondolkodsmd, amely C. A. R. Hoare s E. W. Dijkstra munkira plve alakult s csiszoldott ki az informatika oktatsnak sorn az ELTE Informatika Karn (illetve annak jogeldjn). A nyolcvanas vek eleje ta tart kutat s oktat munkban rszt vev hazai alkotcsapatbl magasan kiemelkedik Fthi kos, aki ttr s vezet szerepet jtszott s jtszik egy sajtos programozsi szemlletmd kialaktsban, aki a sz klasszikus rtelmben iskolt teremtett maga krl. Ennek a szemlletmdnak, programozsi mdszertannak sok eleme tudomnyos kzlemnyekben is megjelent mr, ugyanakkor igen szmottev tudomnyos folyiratokban nem kzlhet eredmny gylt ssze a mindennapos oktats sorn hasznlt pldatrak, segdanyagok, didaktikai elemek (bevezet pldk, segdttelek, demonstrcis feladatok) formjban. Hangslyozom, hogy az alapgondolat s szmos tlet Fthi kostl szrmazik, de sok rszletet msok dolgoztak ki. Hadd emltsem meg ezek kzl Kozics Sndort, aki akrcsak Fthi kos, tanrom volt. Ma mr igen nehz azt pontosan meghatrozni, hogy egy-egy rszlet kitl szrmazik: egyrszt azrt, mert bizonyos tletek megszletse s kidolgozsa nem mindig ugyanahhoz a szemlyhez fzdnek, msrszt pedig a szakfolyiratokban nem kzlhet elemek szerzinek neve sehol nincs dokumentlva. A legteljesebb nvsort azokrl, akik ennek a csapatmunknak rszvevi voltak, valsznleg a Workgroup on Relation Models of Programming: Some Concepts of a Relational Model of Programming,Proceedings of the Fourth Symposium on Programming Languages and Software Tools, Ed. prof. Varga, L., Visegrd, Hungary, June 9-10, 1995. 434-44. publikciban talljuk. Ez a knyv, amely a programozshoz kapcsold munkim els ktete, a Tervezs cmet viseli, s az ELTE IK programtervez informatikus szak Programozs trgynak azon eladsaihoz s gyakorlataihoz szolgl jegyzetknt, ahol a programtervezsrl esik sz.

ELSZ

(A msodik ktetben majd a program futtathat vltozatnak ellltsrl, teht az implementlsrl s a tesztelsrl lesz sz.) Mivel az emltett tantrgynak nem clja a tervezsnl hasznlt mdszertan elmleti htternek bemutatsa (ezt egy msik tantrgy teszi meg), ezrt ez a ktet nem is tr ki erre rszleteiben, csak nagy vonalakban emlti meg a legfontosabb fogalmakat. A ktet elssorban a visszavezets technikjnak gyakorlati alkalmazsra fkuszl, arra, amikor algoritmus mintk, gynevezett programozsi ttelek segtsgvel oldunk meg feladatokat. A megolds egy absztrakt program formjban szletik meg, amelyet aztn tetszs szerinti programozsi krnyezetben lehet megvalstani. A knyv didaktikjnak sszelltsakor elssorban sajt eladsaimra s gyakorlataimra tmaszkodtam, de felhasznltam Fthi kossal folytatott beszlgetseknek tapasztalatait is. A didaktika, a bevezetett jellsek kialaktsban sokat segtettek azok a kollgk is, akikkel kzsen tartjuk a fent emltett trgy gyakorlatait. Kln ksznettel tartozom kzttk Szabn Nacsa Rozlinak, Sike Sndornak, Veszprmi Annnak s Nagy Srnak. Ksznet jr azoknak a hallgatknak is, akik a knyv kzirathoz helyesbt szrevteleket tettek, kztk klnsen Mt Gergelynek. A jegyzet tananyagnak kialaktsa az Eurpai Uni tmogatsval, az Eurpai Szocilis Alap trsfinanszrozsval valsult meg (a tmogats szma TMOP 4.2.1./B-09/1/KMR-2010-0003). A jegyzet megjelentetst az ELTE IK tmogatta.

BEVEZETS
A programozs az a mrnki tevkenysg, amikor egy feladat megoldsra programot ksztnk, amelyet azutn szmtgpen hajtunk vgre. E ltszlag egyszer meghatrozsnak a htterben tbb figyelemre mlt gondolat rejtzik. Az egyik az, hogy a programkszts clja egy feladat megoldsa, ezrt a programozs sorn mindig a kitztt feladatot kell szem eltt tartanunk; abbl kell kiindulnunk, azt kell elemeznnk, rszleteiben megismernnk. A msik gondolat az, hogy a program fogalma nem ktdik olyan szorosan a szmtgphez, mint azt hinnnk. A programozs valjban egymstl jl elklnthet br a gyakorlatban sszefond rsztevkenysgekbl ll: elszr kitalljuk, megtervezzk a programot (ez az igazn nehz lps), aztn tfogalmazzuk, azaz kdoljuk azt egy szmtgp szmra rthet programozsi nyelvre, vgl kiprbljuk, teszteljk. Nyilvnval, hogy az els a lpsben, a programtervezsben szinte kizrlag a megoldand feladatra kell sszpontostanunk, s nem kell, nem is szabad trdnnk azzal, hogy a program milyen programozsi krnyezetbe gyazdik majd be. Nem veszhetnk el az olyan krdsek rszletezsben, hogy mi is az a szmtgp, hogyan mkdik, mi az opercis rendszer, mi egy programozsi nyelv, hogyan lehet egy programot valamely szmtgp szmra rthetv, vgrehajthatv tenni. A program lnyegi rsze ugyanis nevezetesen, hogy a feladatot megoldja nem fgghet a programozsi krnyezettl. A programtervezst egy olyan folyamatnak tekintjk, amely sorn a feladatot jabb s jabb, egyre rszletesebb formban fogalmazzuk meg, miltal egyre kzelebb kerlnk ahhoz a szmtgpes krnyezethez, amelyben majd a feladatot megold program mkdik. Ehhez azt vizsgljuk, hogyan kell egy feladatot felbontani rszekre, majd a rszeket tovbbfinomtani egszen addig, amg olyan egyszer rszfeladatokhoz jutunk, amelyekre mr knnyen adhatk azokat megold programok. Ennek a knyvnek a gyakorlati jelentsge ezeknek a finomt (ms szval rszletez, rszekre bont, idegen szval dekomponl) technikknak a bemutatsban rejlik. A programtervezsnek s a programozsi krnyezetnek a sztvlasztsa nemcsak a programozs tanulsa szempontjbl hasznos,

BEVEZETS

hanem a programozi mestersgnek is elengedhetetlen felttele. Aki a programozst egy konkrt programozsi krnyezettel sszefggsben sajttja el, az a megszerzett ismereteit mind trben, mind idben ersen korltozottan tudja csak alkalmazni. Az llandan vltoz technikai krnyezetben ugyanis pontosan kell ltni, melyik ismeret az, amit vltoztats nlkl tovbb hasznlhatunk, s melyik az, amelyet idrl idre le kell cserlnnk. A programtervezsnek az alapelvei, mdszerei, egyszval a gondolkodsmd nem vltozik olyan gyorsan, mint a programozsi krnyezet, amelyben dolgoznunk kell. A bevezet mondathoz kapcsold harmadik gondolat a mrnki jelzben rejlik. E szerint a programksztst egy vilgosan rgztett technolgia mentn, szabvnyok alapjn kell vgezni. A legsszetettebb feladat is megfelel elemzs sorn felbonthat olyan rszekre, amelyek megoldsra mr rendelkeznk korbbi mintkkal. Ezek olyan rszmegoldsok, amelyek helyessge, hatkonysga mr bizonytott, hasznlatuk ezrt biztonsgos. Kzenfekv, hogy egy j feladat megoldshoz ezeket a korbban mr bevlt mintkat felhasznljuk, ahelyett, hogy mindent teljesen elejrl kezdjnk el kidolgozni. Ha megfelel technolgit alkalmazunk a mintk jrafelhasznlsnl, akkor a biztonsgos mintkbl garantltan biztonsgos megoldst tudunk pteni. Ebben a ktetben a programtervezst lltottam kzppontba: a feladatok specifikcijbl kiindulva azokat megold absztrakt programokat ksztnk. Clom egy olyan programozsi mdszertan bemutatsa, amelyik feladat orientlt, elvlasztja a program tervezst a terv megvalststl, s a tervezs sorn programozsi mintkat kvet. A programozsi mintknak egy specilis csaldjval foglalkozom csak, mgpedig algoritmus mintkkal vagy ms nven a programozsi ttelekkel. Szmos plda segtsgvel mutatom be ezek helyes hasznlatt, amely szavatolja az ellltott programnak, mint termknek a minsgt. Ez a ktet hrom rszre tagoldik, amelyet a kitztt feladatot megoldsainak gyjtemnye zr le. Az els rsz a legfontosabb programozsi fogalmakat vezeti be, meghatrozza, hogy a feladataink lershoz milyen eszkzt, gynevezett specifikcis jellst hasznljunk, bevezeti a strukturlt programok fogalmt (elemi programok, programszerkezetek) s egy jellsrendszert (struktogramm) az absztrakt strukturlt programok lersra. A msodik rsz ismerteti a gyakran alkalmazott programozsi tteleket, pldkat

BEVEZETS

mutat azok alkalmazsra, vgl sszetett feladatokon mutatja be azt a tervezsi folyamatot, ahogyan a megoldst olyan rszprogramok sszessgeknt ksztjk el, amelyek egy-egy programozsi ttel mintjra kszltek. A harmadik rszben olyan feladatok megoldsra kerl sor, amelyekben sszetett tpus adatokat hasznlunk. Definiljuk a korszer adattpus fogalmt, mutatunk egy rendszerezsi szempontot az sszetett tpusok csoportostsra, s klns figyelemmel fordulunk az gynevezett gyjtemnyek (trolk) tpusai fel. ltalnostjuk a programozsi tteleket felsorolra, azaz olyan objektumra, amely pldul egy gyjtemny elemeit kpes bejrni s egyms utn felmutatni. Vgl a felsorolra ltalnostott programozsi ttelek segtsgvel sszetett feladatokat fogunk megoldani. A knyv klnsen a msodik s harmadik rsze tulajdonkppen egy pldatr, szmos feladat megoldsnak rszletes lerst tartalmazza. Az egyes fejezetek vgn kitztt gyakorl feladatok megoldsai a tizedik fejezetben tallhatk.

I. RSZ PROGRAMOZSI FOGALMAK


Ebben a rszben egy programozsi modellt mutatunk be, amelynek keretben a programozssal kapcsolatos fogalmainkat vezetjk be. Ez valjban egy matematikai modell, de itt kerlni fogjuk a pontos matematikai defincikat, ugyanis ennek a knyvnek nem clja a programozsi modell matematikai aspektusainak rszletes ismertetse. Ehelyett sokkal fontosabb megltni azt, hogy ez a modell egy sajtos s nagyon hasznos gondolati htteret szolgltat a ktetben trgyalt programtervezsi mdszereknek. Fontos pldul azt megrteni s ebben ez a matematikai modell segt , hogy mit tekintnk megoldand feladatnak, mire kell egy feladat megfogalmazsban figyelni, hogyan rdemes az szrevteleinket rgzteni. Tisztzni kell tovbb, hogy mi egy program, hogyan lehet azt ltalnos eszkzkkel lerni gy, hogy ez a lers ne ktdjn konkrt programozsi krnyezetekhez (teht absztrakt programot rjunk), de knnyedn lehessen belle konkrt programokat kszteni. Vlaszt kell kapnunk arra is, mikor lesz helyes egy program, azaz mikor oldja meg a kitztt feladatot. E ktet ksbbi rszeiben alkalmazott klnfle programtervezsi mdszereknek ugyanis ebben az rtelemben lltanak el garantltan helyes programokat. Vgl, de nem utols sorban, a programozsi modell jells rendszere alkalmas eszkzt nyjt a tervezs dokumentlsra. Az 1. fejezet a programozsi modell alapfogalmait vezeti be. A 2. fejezet egy a feladatok lersra szolgl formt, a feladat specifikcijt mutatja be. A 3. fejezet a strukturlt program fogalmt definilja, s vzolja, hogy hogyan lehet matematikai korrektsggel igazolni azt, hogy egy strukturlt program megold egy feladatot. A fejezet vgn fogalmazzuk meg azt az ignynket, hogy egy program ne csak helyes legyen, hanem megengedett is, amely azt garantlja, hogy egy absztrakt programot egyszeren kdolhassunk egy konkrt programozsi krnyezetben.

1. Alapfogalmak
Induljunk ki a bevezets azon megllaptsbl, amely szerint a programozs egy olyan tevkenysg, amikor egy feladat megoldsra programot ksztnk. Ennek rtelmben a programozs hrom alapfogalomra pl: a feladat, a program s a megolds fogalmaira. Mi az a feladat, mi az a program, mit jelent az, hogy egy program megold egy feladatot? Ebben a fejezetben erre adjuk meg a vlaszt. 1.1. Az adatok tpusa Egy feladat megoldsa azzal kezddik, hogy megismerkednk azzal az informcival, amelyet a problma megfogalmazsa tartalmaz. Nem jdonsg, nemcsak a programozsi feladatokra rvnyes, hogy a megolds kulcsa a feladat kitzse sorn megjelen informci rtelmezsben, rendszerezsben s lersban rejlik. Feladatokkal mindenki tallkozott mr. A tovbbiakban felvetd gondolatok szemlltetse kedvrt most egy iskolai feladatot tznk ki, amely a kvetkezkppen hangzik: Egy nyolc kilogrammos, zld szem szimi macska stlgat egy belvrosi brhz negyedik emeleti ablakprknyn. Az es zuhog, gy az ablakprkny skos. A cica megcsszik, majd a mintegy 12.8 mteres magassgbl lezuhant. Szerencsre a talpra esik! Mekkora fldet rskor a (becsapdsi) sebessge? A feladat ltal kzvettett informci els pillantsra igen sszetett. Vannak lnyeges s lnyegtelen elemei; szerepelnek kzttk konkrt rtkeket hordoz adatok s az adatok kztti kapcsolatokat ler sszefggsek; van, ami kzvetlenl a feladat szvegbl olvashat ki, de van, ami rejtett, s csak a szvegkrnyezetbl kvetkeztethetnk r. A macsks feladatban lnyegtelen adat pldul a macska szemnek szne, hiszen a krds megvlaszolsa, azaz a becsapdsi sebessg kiszmolsa szempontjbl ez nem fontos. Lnyeges adat viszont a magassg, ahonnan a cica leesett. A kinematikt jl ismerk szmra nyilvnval, hogy egy zuhan test becsapdsi sebessgnek kiszmolshoz nincs szksg a test tmegre sem. Felttelezve ugyanis azt, hogy a macsknak pontszer teste a Fldn csapdik be, a becsapds sebessgt a feladatban kzvetlenl nem emltett, teht

10

1.1. Az adatok tpusa

rejtett v 2 g h kplet (h a magassg, g a nehzsgi gyorsuls) segtsgvel szmolhatjuk ki. Itt a nehzsgi gyorsuls is egy rejtett adat, amelynek az rtkt llandknt 10 m/s2-nek vehetjk, ennek 20 h -ra mdosul. megfelelen a fenti kplet v Abban van nmi szabadsgunk, hogy a feladat szvegben nem pontosan lert elemeket hogyan rtelmezzk. Pldul a nehzsgi gyorsulst is kezelhetnnk bemeneti adatknt ugyangy, mint a magassgot. St magt a becsapdsi sebessg kiszmtsnak kplett is be lehetne adatknt krni annak minden paramtervel (pl. nehzsgi gyorsulssal, srldsi egytthatval, stb.) egytt, ha a problmt nemcsak a fent lert egyszersts (pontszer test zuhansa lgres trben) felttelezse mellett akarnnk megoldani Ezek s az ehhez hasonl eldntend krdsek teszik a feladat megrtst mr egy ilyen viszonylag egyszer pldnl is bonyolultt. A feladat elemzst a benne szerepl lnyeges adatok sszegyjtsvel kezdjk, s az adatokat a tulajdonsgaikkal jellemezzk. Egy adatnak igen fontos tulajdonsga az rtke. A pldban szerepl magassgnak a kezdeti rtke 12.8 mter. Ez egy gynevezett bemen (input) adat, amelynek rtkt felttlenl ismerni kell ahhoz, hogy a feltett krdsre vlaszolhassunk. Kzenfekv a kitztt feladatnak egy olyan ltalnostsa, amikor a bemeneti adathoz nem egy konkrt rtket rendelnk, hanem egy tetszlegesen rgztett kezdeti rtket. Ehhez fontos tudni azt, hogy milyen rtkek jhetnek egyltaln szba; melyek lehetnek a bemeneti adatnak a kezdrtkei. A pldnkban szerepl magassg adat egy nem-negatv vals szm. Furcsnak tnhet, de adatnak tekintjk az eredmnyt is, azaz a feladatban feltett krdsre adhat vlaszt. Ennek konkrt rtkt nem ismerjk elre, hiszen ppen ennek az rtknek a meghatrozsa a clunk. A pldban a becsapdsi sebessg egy ilyen az eredmnyt megjelent gynevezett eredmny vagy kimeneti (output) adat, amelynek rtke kezdetben definilatlan (tetszleges), ezrt csak a lehetsges rtkeinek halmazt adhatjuk meg. A becsapdsi sebessg lehetsges rtkei is (nem-negatv) vals szmok lehetnek. Az adatok msik jellemz tulajdonsga az, hogy az rtkeikkel mveleteket lehet vgezni. A pldnkban a vals szmokhoz kapcsold mveletek a szoksos aritmetikai mveletek, a feladat megoldsnl ezek kzl a szorzsra s a ngyzetgykvonsra lesz szksgnk. Az adatokrl tovbbi jellemzket is ssze lehetne gyjteni

11

1. Alapfogalmak

(mrtkegysg, irny stb.), de a programozs szempontjbl ezek nem lnyegesek. Egy adat tpust az adat ltal felvehet lehetsges rtkek halmaza, az gynevezett tpusrtk-halmaz, s az ezen rtelmezett mveletek, az gynevezett tpusmveletek egyttesen hatrozzk meg, ms szval specifikljk1. Tekintsnk most nhny nevezetes adattpust, amelyeket a tovbbiakban gyakran fogunk hasznlni. A tpus s annak tpusrtkhalmazt tbbnyire ugyanazzal a szimblummal jelljk. Ez nem okoz ksbb zavart, hiszen a szvegkrnyezetbl mindig kiderl, hogy pontosan mikor melyik jelentsre is gondolunk. Termszetes szm tpus. Tpusrtk-halmaza a termszetes szmokat (pozitv egsz szmokat s a nullt) tartalmazza, jele: . (+ a nullt nem tartalmaz termszetes szmok halmazt jelli.) Tpusmveletei az sszeads (+), kivons (), szorzs (*), az egsz oszts (div), az osztsi maradkot elllt mvelet (mod), esetleg a hatvnyozs, ezeken kvl megengedett mg kt termszetes szm sszehasonltsa ( , , , , , ). Egsz szm tpus. Tpusrtk-halmaza (jele: ) az egsz szmokat tartalmazza (+ a pozitv, a negatv egsz szmok halmaza), tpusmveletei a termszetes szmoknl bevezetett mveletek. Vals szm tpus. Tpusrtk-halmaza (jele: ) a vals szmokat tartalmazza (+ a pozitv, a negatv vals szmok halmaza, 0+ a pozitv vals szmokat s a nullt tartalmaz halmaz), tpusmveletei az sszeads (+), kivons (), szorzs (*), oszts (/), a hatvnyozs, ezeken kvl megengedett kt vals szm sszehasonltsa ( , , , , , ) is. Logikai tpus. Tpusrtk-halmaza (jele: ) a logikai rtkeket tartalmazza, tpusmveletei a logikai s ( ), logikai vagy ( ), a logikai tagads ( ) s logikai egyenlsg ( ) illetve nem-egyenlsg ( ).
1

A tpus korszer defincija ennl jval rnyaltabb, de egyelre ez a szktett vltozat is elegend lesz az alapfogalmak bevezetsnl. A rszletesebb meghatrozssal a 7. fejezetben tallkozunk majd.

12

1.1. Az adatok tpusa

Karakter tpus. Tpusrtk-halmaza (jele: ) a karaktereket (a nagy s kisbetk, szmjegyek, rsjelek, stb.) tartalmazza, tpusmveletei a kt karakter sszehasonltsai ( , , , , , ). Halmaz tpus. Tpusrtkei olyan vges elemszm halmazok, amelyek egy meghatrozott alaphalmaz rszei. E alaphalmaz esetn a jele: 2E. Tpusmveletei a szoksos elemi halmazmveletek: halmaz ressgnek vizsglata, elem kivlasztsa halmazbl, elem kivtele halmazbl, elem beraksa a halmazba. Sorozat tpus. Tpusrtkei olyan vges hosszsg sorozatok, amelyek egy meghatrozott alaphalmaz elemeibl llnak. E alaphalmaz esetn a jele: E*. Tpusmveletei: egy sorozat hossznak (elemszmnak) lekrdezse (|s|); sorozat adott sorszm elemre trtn hivatkozs (si), azaz egy elem kiolvassa illetve megvltozatsa; sorozatba j elem beillesztse; adott elem kitrlse. Vektor tpus. (Egydimenzis tmb) Tpusrtkei olyan vges, azonos hosszsg sorozatok, ms nven vektorok, amelyek egy meghatrozott alaphalmaz elemeibl llnak. A sorozatokat m-tl n-ig terjed egsz szmokkal szmozzuk meg, ms nven indexeljk. Az ilyen vektorok halmazt E alaphalmaz esetn az Em..n jelli, m 1 esetn egyszeren E n . Tpusmvelete egy adott index elemre trtn hivatkozs, azaz az elem kiolvassa illetve megvltoztatsa. A vektor els s utols eleme indexnek (az m s az n rtknek) lekrdezse is lnyegben egy-egy tpusmvelet. Mtrix tpus. (Ktdimenzis tmb) azaz Vektorokat tartalmaz vektor, amely specilis esetben azonos mdon indexelt El..m-beli vektoroknak (gynevezett soroknak) a vektora (El..m)k..n vagy mskpp jellve El..mk..n, ahol E az elemi rtkek halmazt jelli), s amelyet k=l=1 esetn egyszeren Emn-knt is rhatunk. Tpusmvelete egy adott sor adott elemre (oszlopra) trtn hivatkozs, azaz az elem kiolvassa, illetve megvltoztatsa. Tpusmvelet mg a mtrix egy teljes sorra trtn hivatkozs, valamint a sorokat tartalmaz vektor indextartomnynak, illetve az egyes sorok indextartomnynak lekrdezse.

13

1. Alapfogalmak

1.2. llapottr Amikor egy feladat minden lnyeges adata felvesz egy-egy rtket, akkor ezt az rtk-egyttest a feladat egy llapotnak nevezzk. A macsks feladat egy llapota pldul az, amikor a magassg rtke 12.8, a sebessg 16. Vezessnk be kt cmkt: a h-t a magassg, a v-t a sebessg jellsre, s ekkor az elz llapotot a rvidtett (h:12.8, v:16) formban is rhatjuk. Az itt bevezetett cmkkre azrt van szksg, hogy meg tudjuk klnbztetni egy llapot azonos tpus rtkeit. A (12.8, 16) jells ugyanis nem lenne egyrtelm: nem tudnnk, hogy melyik rtk a magassg, melyik a sebessg. Ugyanennek a feladatnak llapota mg pldul a (h:5, v:10) vagy a (h:0, v:10). St mivel az adatok kztt kezdetben semmifle sszefggst nem tteleznk fel, csak a tpusrtk-halmazaikat ismerjk a (h:0, v:10.68)-t s a (h:25, v:0)-t is llapotoknak tekintjk, noha ez utbbiak a feladat szempontjbl rtelmetlenek, fizikai rtelemben nem megvalsul llapotok. Az sszes lehetsges llapot alkotja az llapotteret. Az llapotteret megadhatjuk gy, hogy felsoroljuk a komponenseit, azaz az llapottr lnyeges adatainak tpusrtk-halmazait egyedi cmkkkel elltva. Az llapottr cmkit a tovbbiakban az llapottr vltozinak hvjuk. Mivel a vltoz egyrtelmen azonostja az llapottr egy komponenst, ezrt alkalmas arra is, hogy egy konkrt llapotban megmutassa az llapot adott komponensnek rtkt. A macsks pldban az llapottr a (h:0+, v:0+). Tekintsk ennek a (h:12.8, v:16) llapott. Ha megkrdezzk, hogy mi itt a h rtke, akkor vilgos, hogy ez a 12.8. Ha elrjuk, hogy vltozzon meg az llapot v komponense 31-re, akkor a (h:12.8, v:31) llapotot kapjuk. Egy llapot komponenseinek rtkt teht a megfelel vltoz nevnek segtsgvel krdezhetjk le vagy vltoztathatjuk meg. Ez utbbi esetben egy msik llapotot kapunk. llapottere nemcsak egy feladatnak lehet. Minden olyan esetben bevezethetjk ezt a fogalmat, ahol adatokkal, pontosabban adattpusokkal van dolgunk, gy pldul egy matematikai kifejezs vagy egy program esetben is.

14

1.3. Feladat fogalma

1.3. Feladat fogalma Amikor a macsks feladatot meg akarjuk oldani, akkor a feladatnak egy olyan llapotbl indulunk ki, ahol a magassg ismert, pldul 12.8, a sebessg pedig ismeretlen. Ilyen kezdllapot tbb is van az llapottrben, ezeket (h:12.8, v:*)-gal jellhetjk, ami azt fejezi ki, hogy a msodik komponens definilatlan, teht tetszleges. A feladatot akkor oldottuk meg, ha megtalltuk azt a clllapotot, amelyiknek sebessgkomponense a 16. Egy fizikus szmra a logikus clllapot a (h:0, v:16) lenne, de a feladat megoldshoz nem kell a valdi fizikai clllapot megtallnunk. Az informatikus szmra a magassg-komponens egy bemen adat, amelyre elrhatjuk pldul, hogy rizze meg a kezdrtket a clllapotban. Ebben az esetben a (h:12.8, v:16) tekinthet clllapotnak. Ha ilyen elrs nincs, akkor minden (h: *, v:16) alak llapot clllapotnak tekinthet. llapodjunk meg ennl a pldnl abban, hogy megrizzk a magassg-komponens rtkt, teht csak egy clllapotot fogadunk el: (h:12.8, v:16). Ms magassg-rtk kezdllapotokhoz termszetesen ms clllapot tartozik. (Megjegyezzk, hogy ha az llapottr felrsnl nem zrtuk volna ki a negatv vals szmokat, akkor most ki kellene ktni, hogy a feladatnak nincs rtelme olyan kezdllapotokon, amelyek magassg-komponense negatv, pldul (h:-1, v: *), hiszen ekkor a becsapdsi sebessget kiszmol kpletben negatv szmnak kellene vals ngyzetgykt kiszmolni.). ltalnosan lerva az rtelmes kezd- s clllapot kapcsolatokat, a kvetkezt mondhatjuk. A feladat egy (h:h0, v: *) kezdllapothoz, ahol h0 egy tetszlegesen rgztett (nem-negatv vals) szm, a * pedig egy tetszleges nemdefinilt rtk, a (h:h0, v: 20 h0 ) clllapotot rendeli. Tekintsnk most egy msik feladatot! Adjuk meg egy sszetett szm egyik valdi osztjt! Ennek a feladatnak kt lnyeges adata van: az adott termszetes szm (cmkje legyen n) s a vlaszknt megadand oszt (cmkje: d). Mindkt adat termszetes szm tpus. A feladat llapottere teht: (n:, d:). Rgztsk az llapottr komponenseinek sorrendjt: megllapods szerint az llapotok jellsnl elsknt mindig az n, msodikknt a d vltoz rtkt adjuk meg, gy a tovbbiakban hasznlhatjuk az (n:6, d:1) llapot-jells helyett a rvidebb (6,1) alakot. A feladat kezdllapotai kztt talljuk

15

1. Alapfogalmak

pldul a (6,*) alakakat. Ezekhez tbb clllapot is tartozik: (6,2) s (6,3), hiszen a 6-nak tbb valdi osztja is van. Nincs rtelme a feladatnak viszont a (3,*) alak kezdllapotokban, hiszen a 3 nem sszetett szm, azaz nincs valdi osztja. A feladat ltalban az (x,*) kezdllapothoz, ahol x egy sszetett termszetes szm, azokat az (x,k) llapotokat rendeli, ahol k az x egyik valdi osztja. A feladat egy olyan kapcsolat (lekpezs), amelyik bizonyos llapotokhoz (kezdllapotokhoz) llapotokat (clllapotokat) rendel. Ez a lekpezs ltalban nem egyrtelm, ms szval nemdeterminisztikus, hiszen egy kezdllapothoz tbb clllapot is tartozhat. (Az ilyen lekpezst a matematikban relcinak hvjk.) rdekes tanulsgokkal jr a kvetkez feladat: Adjuk meg egy nem-nulla termszetes szm legnagyobb valdi osztjt! Itt bemeneti adat az a termszetes szm, aminek a legnagyobb valdi osztjt keressk. Tudjuk, hogy a krdsre adott vlasz is adatnak szmt, de azt mr nehz szrevenni, hogy a vlasz itt kt rszbl ll. A feladat megfogalmazsbl kvetkezik, hogy nemcsak egy sszetett szm esetn vrunk vlaszt, hanem egy prmszm vagy az 1 esetn is. De ilyenkor nincs rtelme legnagyobb valdi osztt keresni! A szmszer vlaszon kvl teht szksgnk van egy logikai rtk adatra, amely megmutatja, hogy van-e egyltaln szmszer megoldsa a problmnak. A feladat llapottere ezrt: (n:, l: , d:). A feladat ebben a megkzeltsben brmelyik olyan llapotra rtelmezhet, amelyiknek az n komponenshez tartoz rtke nem nulla. Az olyan (x,*,*) llapotokhoz (itt is az n,l,d sorrendre pl rvid alakot hasznljuk), ahol x nem sszetett szm, a feladat az (x,hamis,*) alak clllapotokat rendeli; ha x sszetett, akkor az (x,igaz,k) clllapotot, ahol k a legnagyobb valdi osztja az xnek. A feladatok vltozit megklnbztethetjk aszerint, hogy azok a feladat megoldshoz felhasznlhat kezd rtkeket tartalmazzk-e (bemen- vagy input vltozk), vagy a feladat megoldsnak eredmnyei (kimen-, eredmny- vagy output vltozk). A bemen vltozk sokszor megrzik a kezdrtkket a clllapotban is, de ez nem alapkvetelmny. A kimen vltozk kezdllapotbeli rtke kzmbs, tetszleges, clllapotbeli rtkk megfogalmazsa viszont a feladat lnyegi rsze. Szmos olyan feladat is van, ahol egy vltoz egyszerre lehet bemen s kimen is, st lehetnek olyan (segd)

16

1.3. Feladat fogalma

vltozi is, amelyek csak a felttelek knnyebb megfogalmazshoz nyjtanak segtsget. 1.4. Program fogalma A szakknyvek tbbsge a programot utastsok sorozataknt definilja. Nyilvnval azonban, hogy egy utastssorozat csak a program lersra kpes, s nmagban semmit sem rul el a program termszetrl. Ehhez ugyanis egyfell ismerni kellene azt a szmtgpet, amely az utastsokat rtelmezi, msfell meg kellene adni, hogy az utastsok vgrehajtsakor mi trtnik, azaz lnyegben egy programozsi nyelvet kellene definilnunk. A program fogalmnak ilyen bevezetse mg akkor is hosszadalmas, ha programjainkat egy absztrakt szmtgp szmra egy absztrakt programozsi nyelven rjuk le. A program fogalmnak bevezetsre ezrt mi nem ezt az utat kvetjk, hiszen knyvnk bevezetjben ppen azt emeltk ki, hogy milyen fontos elvlasztani a programtervezsi ismereteket a szmtgpeknek s a programozsi nyelveknek a megismerstl. A fenti rvek ellenre idzznk el egy pillanatra annl a meghatrozsnl, hogy a program utastsok sorozata, s vegynk szemgyre egy gy megadott programnak a mkdst! (Ez a plda egy absztrakt gp s absztrakt nyelv ismerett felttelezi, m az utastsok megrtse itt remlhetleg nem okoz majd senkinek sem gondot.) 1. Legyen d rtke vagy az n-1 vagy a 2. 2. Ha d rtke megegyezik 2-vel akkor amg d nem osztja n-t addig nveljk d rtkt 1-gyel, klnben amg d nem osztja n-t addig cskkentsk d rtkt 1-gyel. A program kt termszetes szm tpus adattal dolgozik: az elsnek cmkje n, a msodik d, azaz a program (adatainak) llapottere az (n:, d:). Vizsgljuk meg, mi trtnik az llapottrben, ha ezt a programot vgrehajtjuk! Mindenekeltt vegyk szre, hogy a program brmelyik llapotbl elindulhat. Pldul a (6,8) kiindul llapot esetn (itt is alkalmazzuk a rvidebb, az n,d sorrendjt kihasznl alakot az llapot jellsre) a

17

1. Alapfogalmak

program els utastsa vagy a (6,2), vagy a (6,5) llapotba vezet el. Az els utasts ugyanis nem egyrtelm, ettl a program mkdse nemdeterminisztikus lesz. Termszetesen egyszerre csak az egyik vgrehajts kvetkezhet be, de hogy melyik, az nem szmthat ki elre. Ha az els utasts a d-t 2-re lltja be, akkor a msodik utasts elkezdi nvelni azt. Ellenkez esetben, d=5 esetn, cskkenni kezd a d rtke addig, amg az nem lesz osztja az n-nek. Ezrt az egyik esetben amikor d rtke 2 rgtn meg is ll a program, a msik esetben pedig rintve a (6,5), (6,4) llapotokat a (6,3) llapotban fog terminlni. Brmelyik olyan kiindul llapotbl elindulva, ahol az els komponens 6, az elzekhez hasonl vgrehajtsi sorozatokat kapunk: a program a mkdse sorn egy (6,*) alak llapotbl elindulva vagy a (6,*) (6,2) llapotsorozatot, vagy a (6,*) (6,5) (6,4), (6,3) llapotsorozatot futja be. Ezek a sorozatok csak a legels llapotukban klnbznek egymstl, hiszen egy vgrehajtsi sorozat els llapota mindig a kiindul llapot. Induljunk el most egy (5,*) alak llapotbl. Ekkor az els utasts eredmnytl fggen vagy a (5,*) (5,2) (5,3) (5,4) (5,5) , vagy a (5,*) (5,4) (5,3) (5,2) (5,1) vgrehajts kvetkezik be. A (4,*) alak llapotbl is kt vgrehajts indulhat, de mindkett ugyanabban az llapotban ll meg: (4,*) (4,2) , (4,*) (4,3) (4,2) rdekes vgrehajtsok indulnak az (1,*) alak llapotokbl. Az els utasts hatsra vagy az (1,2) , vagy az (1,0) llapotba kerlnk. Az els esetben a msodik utasts elkezdi a d rtkt nvelni, s mivel az 1-nek nincs 2-nl nagyobb osztja, ez a folyamat soha nem ll le. Azt mondjuk, hogy a program a (1,*) (1,2) (1,3) (1,4) vgtelen vgrehajtst futja be, mert vgtelen ciklusba esik. A msik esetben viszont rtelmetlenn vlik a msodik utasts, hiszen azt kell vizsglni, hogy a nulla rtk d osztja-e az n rtkt, de a nullval val oszts nem rtelmezhet. Ez az utasts teht itt illeglis, abnormlis lpst eredmnyez. Ilyenkor a program abnormlisan mkdik tovbb, amelyet az (1,*) (1,0) (1,0) vgtelen vgrehajtsi sorozattal modelleznk. Ez azt fejezi ki, mintha a program megprbln jra s jra vgrehajtani az illeglis lpst, majd mindig visszatr az utols leglis llapothoz. Hasonl a helyzet a (0,*) kiindul llapotokkal is, amelyekre az els utasts megksrli a d rtkt (ennek tetszleges rtkk rgztsk s jelljk y-nal) -1-re lltani. A (0,-1) ugyanis nem tartozik bele az llapottrbe, gy az els utasts a program abnormlis

18

1.4. Program fogalma

mkdst eredmnyezheti, amelyet a (0,y) (0,y) (0,y) vgtelen sorozattal jellemezhetnk. Mintha jra s jra megprblnnk a hibs utasts vgrehajtst, de a (0,-1) illeglis llapot helyett mindig visszatrnk a (0,y) kiindul llapothoz.. Termszetesen itt is lehetsges egy msik vgrehajts, amikor az els lpsben a (0,2) llapotba kerlnk, ahol a program rgtn le is ll, hiszen a 2 osztja a nullt. A program ltal egy llapothoz rendelt llapotsorozatot vgrehajtsnak, mkdsnek, a program futsnak hvunk. A vgrehajtsok lehetnek vgesek vagy vgtelenek; a vgtelen mkdsek lehetnek normlisak (vgtelen ciklus) vagy abnormlisak (abortls). Ha a vgrehajts vges, akkor azt mondjuk, hogy a program vgrehajtsa megll, azaz terminl. A normlis vgtelen mkdst nem lehet biztonsggal felismerni, csak abbl lehet sejteni, ha a program mr rgta fut. Az abnormlis mkds akkor kvetkezik be, amikor a vgrehajts sorn egy rtelmezhetetlen utastst (pldul nullval val oszts) kellene vgrehajtani. Ezt a programunkat futtat krnyezet (opercis rendszer) fel szokta ismerni, s erszakkal lelltja a mkdst. Innen szrmazik az abortls kifejezs. A modellnkben azonban nincs futtat krnyezet, ezrt az abnormlis mkdst olyan vgtelen llapotsorozattal brzoljuk, amelyik az rtelmetlen utasts vgrehajtsakor fennll llapotot ismtli meg vgtelen sokszor. A ksbbiekben bennnket egy programnak csak a vges mkdsei fognak rdekelni, s mind a normlis, mind az abnormlis vgtelen vgrehajtsokat megprbljuk majd elkerlni. Egy program minden llapotbl indt vgrehajtst, st egy llapotbl akr tbb klnbzt is. Az, hogy ezek kzl ppen melyik vgrehajts kvetkezik be, nem definilt, azaz a program nemdeterminisztikus. Vegynk szemgyre egy msik programot! Legyen ennek az llapottere az (a:, b:, c:). Az llapotok lershoz rgztsk a tovbbiakban ezt a sorrendet. 1. Vezessnk be egy j vltozt (i:) s legyen az rtke 1. 2. Legyen c rtke kezdetben 0. 3. Amg az i rtke nem haladja meg az a rtkt addig adjuk a c rtkhez az b rtkt, majd nveljk meg i rtkt 1-gyel.

19

1. Alapfogalmak

Ez a program pldul a (2,3,2009) llapotbl indulva az albbi llapotsorozatot futja be: (2,3,2009), (2,3,2009,1), (2,3,0,1), (2,3,3,1), (2,3,3,2), (2,3,6,2), (2,3,6,3), (2,3,6) . A vgrehajtsi sorozat els lpse kiegszti a kiindul llapotot egy j komponenssel s kezdrtket is ad neki. Megllapods szerint az ilyen futs kzben felvett j komponensek a program befejezdsekor megsznnek: ezrt jelenik meg a fenti vgrehajtsi sorozat legvgn egy specilis lps. A program llapottere teht a vgrehajts sorn dinamikusan vltozik, mert a vgrehajtsnak vannak olyan lpsei, amikor egy llapotbl attl eltr komponens szm (eltr dimenzij) llapotba kerlnk. Az j llapot lehet bvebb, amikor a megelz llapothoz kpest extra komponensek jelennek meg (lsd a fenti programban az i: megjelenst elidz lpst), de lehet szkebb is, amikor elhagyunk korbban ltrehozott komponenseket (erre plda a fenti vgrehajts utols lpse). Megllapodunk abban, hogy a vgrehajts kezdetn ltez komponensek, azaz a kiindul llapot komponensei vgig megmaradnak, nem sznhetnek meg. A program kiindul- s vgllapotainak kzs tert a program alap-llapotternek nevezzk, vltozi az alapvltozk. A mkds sorn megjelen jabb komponenseket segdvltozknak fogjuk hvni. A program tartalmazhat segdvltozt megszntet specilis lpseket is, de az utols lps minden segdvltozt automatikusan megszntet. A segdvltoz megjelensekor annak rtke mg nem felttlenl definilt. A program az ltala befuthat sszes lehetsges vgrehajts egyttese. Rendelkezik egy alap-llapottrrel, amelyiknek brmelyik llapotbl el tud indulni, s ahhoz olyan vges vagy vgtelen vgrehajtsi sorozatokat rendel, amelyik els llapota a kiindul llapot. Ugyanahhoz a kiindul llapothoz akr tbb vgrehajtsi sorozat is tartozhat. Egy vgrehajtsi sorozat tovbbi llapotai az alap-llapottr komponensein kvl segd komponenseket is tartalmazhatnak, de ezek a vges hossz vgrehajtsok esetn legksbb az utols lpsben megsznnek, gy a vges vgrehajtsok az alap-llapottrben terminlnak. Egy program mkdse nem vltozik meg attl, ha mdostjuk az alap-llapotert. Egy alapvltoz ugyanis egyszeren tminsthet segdvltozv (ezt nevezzk az alap-llapottr leszktsnek), s

20

1.4. Program fogalma

ekkor csak a program elindulsakor jn ltre, a program befejezdsekor pedig megsznik. Fordtva, egy segdvltozbl is lehet alapvltoz (ez az alap-llapottr kiterjesztse), ha azt mr eleve lteznek tekintjk, ezrt nem kell ltrehozni s nem kell megszntetni. A program alap-llapottert megllapods alapjn jelljk ki. Ebbe nemcsak a program ltal tnylegesen hasznlt, a program utastsaiban elfordul vltozk szerepelhetnek, hanem egyb vltozk is. Az ilyen vltozknak a kezd rtke tetszleges, s azt vgig megrzik a program vgrehajtsa sorn. Azt is knny beltni, hogy az alapllapottr vltozinak neve is lecserlhet anlkl, hogy ettl a program mkdse megvltozna. 1.5. Megolds fogalma Mivel mind a feladat fogalmt, mind a program fogalmt az llapottr segtsgvel fogalmaztuk meg, ez lehetv teszi, hogy egyszer meghatrozst adjunk arra, mikor old meg egy program egy feladatot. Tekintsk jra azt a feladatot, amelyben egy sszetett nem-nulla termszetes szm egyik valdi osztjt keressk. A feladat llapottere: (n:, d:), s egy (x,*) kezdllapothoz (ahol x pozitv s sszetett) azokat az (x,y) clllapotokat rendeli, ahol a y rtke osztja az x-et, de nem 1 s nem x. Az elz alfejezet els programjnak llapottere megegyezik e feladatval. A feladat brmelyik kezd llapotbl is indtjuk el a program mindig terminl, s olyan llapotban ll meg, ahol a d rtke vagy a legkisebb, vagy a legnagyobb valdi osztja az n kezdrtknek. Pldul a program a (12,8) kiindul llapotbl elindulva nem-determinisztikus mdon vagy a (12,2), vagy a (12,6) vgllapotban fog megllni, mikzben a feladat a (12,8) kezdllapothoz a (12,2), (12,3), (12,4), (12,6) clllapotokat jelli ki. A program egy vgrehajtsa teht ezek kzl tall meg mindig egyet, azaz megoldja a feladatot. Egy program akkor old meg egy feladatot, ha a feladat brmelyik kezdllapotbl elindulva biztosan terminl, s olyan llapotban ll meg, amelyet clllapotknt a feladat az adott

21

1. Programozsi alapfogalmak

kezdllapothoz rendel.2 Ahhoz, hogy a program megoldjon egy feladatot, nem szksges, hogy egy adott kezdllapothoz tartoz sszes clllapotot megtallja, elg csak az egyiket. A program nem-determinisztikussga azt jelenti, hogy ugyanazon llapotbl indulva egyszer ilyen, msszor olyan vgrehajtst futhat be. A megoldshoz az kell, hogy brmelyik vgrehajts is kvetkezik be, az megfelel clllapotban lljon meg. Nem oldja meg teht a program a feladatot akkor, ha a feladat egy kezdllapotbl indt ugyan egy clllapotba vezet mkdst, de emellett egy msik, nem clllapotban megll vagy egyltaln nem terminl vgrehajtst is produkl. A megolds vizsglata szempontjbl kzmbs, hogy azokbl az llapotokbl indulva, amelyek nem kezdllapotai a feladatnak, hogyan mkdik a program. Ilyenkor mg az sem szmt, hogy meglle egyltaln a program. Ezrt nem baj, hogy a (0,*) s az (1,*) alak llapotokbl indulva a vizsglt program nem is biztos, hogy terminl. Az is kzmbs, hogy egy olyan (x,*) llapotbl indulva, ahol x egy prmszm, a program vagy az x-et, vagy az 1-et tallja meg, azaz nem tall valdi osztt. A megolds tnyt az sem befolysolja, hogy a program a mkdse kzben mit csinl, mely llapotokat rinti, milyen segdvltozkat vezet be; csak az szmt, hogy honnan indulva hov rkezik meg, azaz a feladat kezdllapotaibl indulva megll-e, s hol. A (4,*) alak llapotokbl kt klnbz vgrehajts is indul, de mindkett a (4,2) llapotban ll meg, hiszen a 2 a 4-nek egyszerre a legkisebb s legnagyobb valdi osztja. A (6,*) alak llapotokbl kt olyan vgrehajts indul, amelyeknek a vgpontja is klnbzik, de mindkett a (6,*)-hoz tartoz clllapot. A programnak azt a tulajdonsgt, amely azt mutatja meg, hogy mely llapotokbl indulva fog biztosan terminlni, s ezen llapotokbl indulva mely llapotokban ll meg, a program hatsnak nevezzk. Egy program hatsa figyelmen kvl hagyja azokat az llapotokat s az abbl indul sszes vgrehajtst, amely llapotokbl vgtelen hossz vgrehajts is indul, a tbbi vgrehajtsnak pedig nem mutatja meg a
2

Ismert a megoldsnak ennl gyengbb meghatrozsa is, amelyik nem kveteli meg a lellst, csak azt, hogy ha a program lell, akkor egy megfelel clllapotban tegye azt.

22

1.5. Megolds fogalma

belsejt, csak a vgrehajts kiindul s vgllapott. Egy program hatsa termszetesen attl fggen vltozik, hogy mit vlasztunk a program alap-llapotternek. Ekvivalensnek akkor mondunk kt programot, ha brmelyik kzs alap-llapottren megegyezik a hatsuk. Ahhoz, hogy egy feladatot megoldjunk egy programmal, a program alapvltozinak a feladat (bemen s eredmny) vltozit kell vlasztanunk. A program ugyanis csak az alapvltozin keresztl tud a krnyezetvel kapcsolatot teremteni, csak egy alapvltoznak tudunk kvlrl kezdrtket adni, s egy alapvltozbl tudjuk a terminls utn az eredmnyt lekrdezni. Ezrt a megolds defincijban feltteleztk, hogy a feladat llapottere megegyezik a program alapllapottervel. A programozsi gyakorlatban azonban sokszor elfordul, hogy egy feladatot egy olyan programmal akarunk megoldani, amelyik llapottere nem azonos a feladatval, bvebb vagy szkebb annl. A megolds fogalmt ezekben az esetekben gy ellenrizzk, hogy elszr a program alap-llapottert a feladathoz igaztjuk, vagy kiterjesztjk, vagy leszktjk (esetleg egyszerre mindkettt) a feladat llapotterre. Abban az esetben, amikor a program alap-llapottere bvebb, mint feladat, azaz van a programnak olyan alapvltozja, amely nem szerepel a feladat llapotterben (ez a vltoz nem kommunikl a feladattal: nem kap tle kezd rtket, nem ad neki eredmnyt), akkor ezt a vltozt a program segdvltozjv minstjk. J plda erre az, amikor rendelkeznk egy programmal, amely egy napon keresztl rnknt mrt hmrskleti adatokbl ki tudja szmolni a napi tlaghmrskletet s a legnagyobb hingadozst, ugyanakkor a megoldand feladat csak az tlaghmrsklet kiszmolst kri. A program alap-llapottere teht olyan komponenst tartalmaz, amely a feladatban nem szerepel (ez a legnagyobb hingadozs), ez a feladat szempontjbl rdektelen. A program els lpsben hozzveszi a feladat egy kezdllapothoz a legnagyobb hingadozst, ezutn a program ugyangy szmol vele, mint eredetileg, de a meglls eltt elhagyja ezt a komponenst, hiszen a feladat clllapotban ennek nincs helye; a legnagyobb hingadozs teht segdvltoz lett. A msik esetben amikor a feladat llapottere bvebb a program alap-llapotternl a program llapottert kiegsztjk a feladat llapotternek azon komponenseivel, amelyek a program llapotterben nem szerepelnek. Ha egy ilyen j komponens segdvltozknt szerepelt az eredeti programban, akkor ez a kiegszts a segdvltozt

23

1. Programozsi alapfogalmak

a program alapvltozjv emeli. Ha az j vltoz segdvltozknt sem szerepelt eddig a programban, akkor ez a vltoz a program ltal nem hasznlt j alapvltoz lesz, azaz kezdeti rtke vgig megrzdik egy vgrehajts sorn. De vajon van-e olyan feladat, amelyet gy meg lehet oldani? Taln meglep, de van. Ilyen az, amikor egy sszetett feladat olyan rsznek a megoldsval foglalkozunk, ahol az sszetett feladat bizonyos komponenseit ideiglenesen figyelmen kvl hagyhatjuk, de attl mg azok a rszfeladat llapotternek komponensei maradnak, s szeretnnk, ha az rtkk nem vltozna meg a rszfeladatot megold program mkdse sorn. Az itt bevezetett megolds definci egy logikus, a gyakorlatot jl modellez fogalom. Egyetlen problma van vele: a gyakorlatban trtn alkalmazsa szinte lehetetlen. Nehezen kpzelhet ugyanis az el, hogy egy konkrt feladat s program ismeretben (miutn a program alap-llapottert a feladat llapotterhez igaztottuk), egyenknt megvizsgljuk a feladat sszes kezdllapott, hogy az abbl indtott program ltali vgrehajtsok megfelel clllapotban llnak-e meg. Ezrt a kvetkez kt fejezetben bevezetnk mind a feladatok, mind a programok lersra egy-egy sajtos eszkzt, majd megmutatjuk, hogy ezek segtsgvel hogyan lehet igazolni azt, hogy egy program megold egy feladatot.

24

1.6. Feladatok

1.6. Feladatok 1.1. Mi az llapottere, kezdllapotai, adott kezdllapothoz tartoz clllapotai az albbi feladatnak? Egy egyenes vonal egyenletesen halad piros Opel s kilomtert t id alatt tesz meg. Mekkora az tlagsebessge? 1.2. Mi az llapottere, kezdllapotai, adott kezdllapothoz tartoz clllapotai az albbi feladatnak? Adjuk meg egy termszetes szmnak egy valdi prm osztjt! 1.3. Tekintsk az A = (n:, f:) llapottren az albbi programot! 1. Legyen f rtke 1 2. Amg n rtke nem 1 addig 2.a. Legyen f rtke f*n 2.b. Cskkentsk n rtkt 1-gyel! rjuk fel e program nhny vgrehajtst! Hogyan lehetne a vgrehajtsokat ltalnosan jellemezni? Megoldja-e a fenti program azt a feladatot, amikor egy pozitv egsz szmnak kell a faktorilist kiszmolni? 1.4. Tekintsk az A = (x:, y:) llapottren az albbi programot! 1. Legyen x rtke x-y 2. Legyen y rtke x+y 3. Legyen x rtke y-x rjuk fel e program nhny vgrehajtst! Hogyan lehetne a vgrehajtsokat ltalnosan jellemezni? Megoldja-e a fenti program azt a feladatot, amikor kt, egsz tpus vltoz rtkt kell kicserlni? 1.5. Tekintsk az albbi kt feladatot: 1) Adjuk meg egy 1-nl nagyobb egsz szm egyik osztjt! 2) Adjuk meg egy sszetett termszetes szm egyik valdi osztjt! Tekintsk az albbi hrom programot az A = (n:, d:) llapottren:

25

1. Programozsi alapfogalmak

1) Legyen a d rtke 1 2) Legyen a d rtke n 3) Legyen a d rtke n-1. Amg a d nem osztja n-t addig cskkentsk a d-t. Melyik program melyik feladatot oldja meg? Vlaszt indokolja! 1.6. Tekintsk az A=(m:+, n:+, x:) llapottren mkd albbi programokat! 1) Ha m<n, akkor legyen az x rtke elszr a (-1)m, majd adjuk hozz a (-1)m+1-t, utna a (-1)m+2-t s gy tovbb, vgl a (-1)n-t! Ha m=n, akkor legyen az x rtke a (-1)n! Ha m>n, akkor legyen az x rtke elszr a (-1)n, majd adjuk hozz a (-1)n+1-t, utna a (-1)n+2-t, s gy tovbb, vgl a (-1)m-t! 2) Legyen az x rtke a ((-1)m+ (-1)n)/2! rjuk fel e programok nhny vgrehajtst! Lssuk be, hogy mindkt program megoldja az albbi feladatot: Kt adott nem nulla termszetes szmhoz az albbiak szerint rendelnk egsz szmot: ha mindkett pros, adjunk vlaszul 1-et; ha pratlanok, akkor -1-et; ha paritsuk eltr, akkor 0-t! 1.7. Tekintsk az A 1,2,3,4,5 llapottren az albbi fiktv programot. (Itt tnyleg egy programot adunk meg, amelybl kiolvashat, hogy az egyes llapotokbl indulva az milyen vgrehajtsi sorozatot fut be.)

1 S 2 4 5

1,2,4,5 2,1 4,1,5,1,4 5,2,4

1 2 4 5

1,4,3,5,2 2,4 4,3,1,2,5,1 5,3,4

1 3 4 5

1,3,2,... 3,3,... 4,1,5,4,2 5,2,3,4

Az F feladat az albbi kezd-clllapot prokbl ll: {(2,1) (4,1) (4,2) (4,4) (4,5)}. Megoldja-e az S program az F feladatot? 1.8. Legyen S olyan program, amely megoldja az F feladatot! Igaz-e, hogy

26

1.6. Feladatok

a) ha F nem determinisztikus, akkor S sem az? b) ha F determinisztikus, akkor S is az? 1.9. Az S1 bvebb, mint az S2, ha S2 minden vgrehajtst tartalmazza. Igaz-e, hogy ha az S1 program megoldja az F feladatot, akkor azt megoldja az S2 is. 1.10. Az F1 bvebb, mint az F2, ha F2 minden kezd-clllapot prjt tartalmazza. Igaz-e, hogy ha egy S program megoldja az F1 feladatot, akkor megoldja az F2-t is.

27

2. Specifikci
Ebben a fejezetben azzal foglalkozunk, hogy hogyan lehet egy feladat kezdllapotait a megolds ellenrzsnek szempontjbl csoportostani, halmazokba rendezni gy, hogy elg legyen egy-egy ilyen halmaznak egy tetszleges elemre ellenrizni azt, hogy onnan indulva az adott program megfelel helyen ll-e meg. Ehhez a feladatnak egy sajtos formj megfogalmazsra, a feladat specifikcijra lesz szksg. 2.1. Kezdllapotok osztlyozsa A megolds szempontjbl egy feladat egy kezdllapotnak legfontosabb tulajdonsga az, hogy milyen clllapotok tartoznak hozz. Megfigyelhet, hogy egy feladat klnbz kezdllapotokhoz sokszor ugyanazokat a clllapotokat rendeli. Kzenfekvnek ltszik, hogy ha egy csoportba vennnk azokat a kezdllapotokat, amelyekhez ugyanazok a clllapotok tartoznak, akkor a megolds ellenrzst nem kellene a kezdllapotokon kln-kln elvgezni, hanem elg lenne az gy keletkez csoportokat egyben megvizsglni: azt kell beltni, hogy a feladat kezdllapotainak egy-egy ilyen csoportjbl elindulva a program megfelel clllapotban ll-e meg. Tekintsnk pldaknt egy mr korbban szerepl feladatot: Egy adott sszetett szmnak keressk egy valdi osztjt! A feladat llapottere (n:, d:). Az llapotok egyszerbb jellse rdekben rgztsk a fenti sorrendet a komponensek kztt: egy llapot els komponense a megadott szm, a msodik a valdi oszt. Kssk ki, hogy az els komponens kezdrtke a clllapotokban is megmaradjon. Az 2.1. brn egy derkszg koordintarendszer I. negyedvel brzoljuk ezt az llapotteret, hiszen ebben minden egsz koordintj rcspont egy-egy llapotot szimbolizl. (A feladat csak azokban az llapotokban rtelmezett, ahol az els komponens sszetett szm.) Kln koordintarendszerbe rajzoltuk be a feladat nhny kezdllapott, s kln egy msikban az ezekhez hozzrendelt clllapotokat. Az bra jl tkrzi vissza azt, hogy a feladat llapotokhoz llapotokat rendel lekpezs.

28

2.1. Kezdllapotok osztlyozsa

{(0, *)}

{(4, *)} {(6, *)}

d
(6,8)

(6,3)

n
1 2 3 4 5 6

d F

{(0, *)}

(4,2)

(6,3) (6,2)

n
1 2 3 4 5 6
2.1. bra Egy feladat: Keressk egy sszetett szm valdi osztit.

A feladat pldul a (6,8) kezdllapothoz a (6,3) s a (6,2) clllapotokat rendeli. De ugyanezek a clllapotok tartoznak a (6,6), a (6,3) vagy a (6,127) kezdllapotokhoz is, mivel ezek els komponensben ugyancsak a 6 ll. Teht az sszes (6,*) alak llapot (a * itt egy tetszleges rtket jell) ugyanazon csoportba (halmazba) sorolhat az alapjn, hogy hozzjuk egyformn a (6,3) s a (6,2) clllapotokat rendeli a feladat. gyis fogalmazhatunk, hogy a feladat a

29

2. Specifikci

{(6,*)} halmaz elemeihez a {(6,3), (6,2)} halmaz elemeit rendeli. Ezen megfontols alapjn kln csoportot kpeznek a (0,*), a (4,*), a (6,*) alak llapotok is, ltalnosan fogalmazva azok az (n,*) alak kezdllapotok, ahol az n sszetett szm. Ezt lthatjuk 2. bra fels rszn. Nem kerl viszont bele egyetlen ilyen halmazba sem pldul az (1,1) vagy a (3,5) llapot, hiszen ezek nem kezdllapotai a feladatnak. (Knny megmutatni, hogy ez a csoportosts matematikai rtelemben egy osztlyozs: minden kezdllapot pontosan egy halmazhoz (csoporthoz) tartozik.) Amikor a feladathoz megold programot keresnk, azt kell beltnunk, hogy minden ilyen halmaz egyik (tetszleges) elembl (ez teht a feladat egy kezdllapota) indulva a program a feladat ltal kijellt valamelyik clllapotban ll meg. Ha gyesek vagyunk, akkor elg ezt a vizsglatot egyetlen jl megvlasztott halmazra elvgezni, mondjuk az ltalnos (n,*) alak kezdllapotok halmazra, ahol az n sszetett szm. ltalban egy feladat kezdllapotainak a fent vzolt halmazait nem knny ellltani. Ennek illusztrlsra tekintsk azt a pldt (lsd 1.1. feladat), amikor egy egyenes vonal egyenletes mozgst vgz testnek kell az tlagsebessgt kiszmolni a megtett t s az eltelt id fggvnyben. Ennek a feladatnak az llapottere (s:, t:, v:), ahol a komponensek rendre az t (s), az id (t), s a sebessg (v). (Rgztjk ezt a sorrendet a komponensek kztt.) A kezdllapotokban az els komponens nem lehet negatv, a msodik komponensnek pedig pozitvnak kell lennie. Melyek azok a kezdllapotok, amelyekhez ez a feladat a ( *,*,50) alak clllapotokat rendeli? Nem is olyan knny erre a vlasz. A (100,2,*) alak kezdllapotok ilyenek, a (200,4,*) alakak is. Ismerve a feladat megoldshoz hasznlt v=s/t kpletet (ezt a kpletet csak az ilyen egyszer feladatok esetben ltjuk ilyen vilgosan), kis gondolkods utn kitallhatjuk, hogy az (50a,a,*) alak kezdllapotokhoz (ahol a egy tetszleges pozitv vals szm), s csak azokhoz rendeli a feladat a (*,*,50) alak clllapotokat. De nem lehetne-e ennl egyszerbben, az eredmnyt kiszmol kplet alkalmazsa nlkl csoportostani a kezdllapotokat? Mirt ne tekinthetnnk kln csoportnak a (100,2,*) kezdllapotokat, s kln a (200,4,*) kezdllapotokat? Mindkett halmazra teljesl, hogy a benne lev kezdllapotokhoz ugyanazon clllapotok tartoznak. Igaz, hogy

30

2.1. Kezdllapotok osztlyozsa

ezen clllapotok mindkt csoport esetben ugyanazok, de mirt lenne ez baj? Ezek kijellshez csak azt kell tudnunk, hogy a feladat els kt adata a bemen adat, az eredmny kiszmolsnak kplete nem kell. Azonos bemen adatokhoz ugyanis ugyanazon eredmny tartozik, teht azonos bemen adatokbl felptett kezdllapotokhoz a feladat ugyanazokat a clllapotokat rendeli. Az azonos bemen adatokbl felptett kezdllapotok halmazai is osztlyozzk a kezdllapotokat, hiszen minden kezdllapot pontosan egy ilyen halmazhoz tartozik. Ezrt ha a feladat kezdllapotainak minden ilyen halmazrl belthat, hogy belle indulva a program megfelel clllapotban ll-e meg, akkor igazoltuk, hogy a vizsglt program megoldja a feladatot. Termszetesen ilyenkor sem kell az sszes halmazt megvizsglni. Elg egy ltalnos halmazzal foglalkozni. Rgztsk a pldnk bemen adatainak rtkeit az s, t tetszlegesen kivlasztott nem negatv paramterekkel, ahol t nem lehet nulla. Egy vizsglt program akkor oldja meg a feladatot, ha az {(s,t,*)} llapot-halmazbl kiindulva a program az {(*,*, s/t)} llapot-halmaz valamelyik llapotban ll meg. Nha tallkozhatunk olyan feladattal is, amelynek nincsenek bemeneti adatai. Ilyen pldul az, amikor egy prmszmot keresnk. Ennek a feladatnak az llapottere a lehetsges vlaszoknak az N halmaza. Itt a vlasz nem fgg semmilyen bemeneti rtktl. Az sszes llapot teht egyben kezdllapot is, amelyeket egyetlen halmazba foghatunk ssze, hiszen mindegyikhez ugyanazon clllapotok, a prmszmok tartoznak. 2.2. Feladatok specifikcija Vegyk el jra azt a feladatot, amikor az egyenes vonal egyenletes mozgst vgz testnek a megtett t s az eltelt id fggvnyben kell az tlagsebessgt kiszmolni! A feladat lnyeges adatai a megtett t, az eltelt id s az tlagsebessg. Ennek megfelelen a feladat llapottere a vltozkkal: A = (s:, t:, v:). Bemen adatai a megtett t (s) s az eltelt id (t). Rgztsnk a bemen adatok szmra egy-egy tetszlegesen kivlasztott rtket! Legyen az t esetn ez az s, az id esetn a t, ahol egyik sem lehet negatv, st a t nulla sem. A kezdllapotoknak az s, t bemen adatokkal rendelkez rszhalmaza az {(s,t,*)}, az ezekhez tartoz clllapotok pedig a {(*,*, s/t)}.

31

2. Specifikci

A kezdllapotoknak s a clllapotoknak a fent vzolt halmazait logikai lltsok (felttelek) segtsgvel is megadhatjuk. A logikai lltsok minden esetben az llapottr llapotait minstik: ha egy llapot kielgti a logikai lltst, azaz a logikai llts igaz rtket rendel hozz, akkor az benne van a logikai llts ltal jelzett halmazban. Pldul a {(100,2,*)} halmazt az s=100 s t=2 logikai lltssal, a {(200,4,*)} halmazt az s=200 s t=4 lltssal is jellhetjk. ltalban az {(s,t,*)} halmazt az s=s s t=t llts rja le, a {(*,*, s/t)} halmazt pedig a v=s/t. Ha ki szeretnnk ktni, hogy az t hossza nem negatv s az id pozitv, akkor a fenti lltsok mell oda kell rnunk azt is, hogy s0 s t>0. A kezdllapotokat ler elfelttelt Ef-fel, a clllapotokat ler utfelttelt Uf-fel fogjuk jellni. Megfigyelhet, hogy mindkett felttel a vltozkra fogalmaz meg megszortsokat. Ha egy vltozt egy felttel nem emlt, az azt jelzi, hogy arra a vltozra nzve nincs semmilyen megkts, azaz annak az rtke tetszleges lehet. Pldnk elfelttelben ilyen a v, az utfelttelben az s s a t. Tmren lerva az eddig elmondottakat a feladatnak az albbi gynevezett specifikcijhoz jutunk: A = (s:, t:, v:) Ef = (s=s s t=t s s0 s t>0) Uf = (v= s/t) A feladat specifiklsa sorn meghatrozzuk a bemen adatok tetszlegesen rgztett rtkeihez tartoz kezdllapotok halmazt, valamint az ehhez tartoz clllapotok halmazt. A feladat specifikcija tartalmazza: 1. az llapotteret, azaz a feladat lnyeges adatainak tpusrtkhalmazait az egyes adatokhoz tartoz vltoz nevekkel egytt; 2. az elfelttelt, amely a kezdllapotok azon halmazt ler logikai llts, amely rgzti a bemen vltozk egy lehetsges, de tetszleges kezdrtkt (ezeket ltalban a megfelel vltoznv vesszs alakjval jelljk); 3. az utfelttelt, amely a fenti kezdllapotokhoz rendelt clllapotok halmazt megad logikai llts. Meg lehet mutatni, hogy ha rendelkeznk egy feladatnak a specifikcijval s tallunk olyan programot, amelyrl belthat, hogy egy az elfelttelt kielgt llapotbl elindulva a program az

32

2.2. Feladatok specifikcija

utfelttelt kielgt valamelyik llapotba kerl, akkor a program megoldja a feladatot. Ezt mondja ki a specifikci ttele. Egy feladat llapotterben megjelen vltozk minsthetek abbl a szempontbl, hogy bemen illetve kimen vltozk-e vagy sem. Ugyanaz a vltoz lehet egyszerre bemen is s kimen is. A bemen vltozk azok, amelyeknek a feladat elfelttele kezdrtket rendel, amelyek explicit mdon megjelennek az elfelttelben. Az utfelttelben explicit mdon megjelen vltozk kzl azok a kimen vltozk, amelyekre nincs kiktve, hogy rtkk megegyezik az elfelttelben rgztett kezdrtkkkel. *** Specifikljuk most azt a feladatot, amikor egy sszetett szm legnagyobb valdi osztjt keressk. A feladatnak kt lnyeges adata van: az adott termszetes sszetett szm s a keresett valdi oszt. Mindkt adat termszetes szm tpus. Ezt a tnyt rgzti az llapottr. A = (n:, d:) A kt adat kzl az els a bemeneti, a msodik a kimeneti adat. Legyen n a tetszlegesen kivlasztott bemen rtk. Mivel a feladat nem rtelmes a 0-ra, az 1-re s a prmszmokra; ezrt az n csak sszetett szm lehet. Az elfelttel: Ef = ( n = n s n sszetett szm ) Kikthetjk, hogy a clllapot els komponensnek, azaz a bemeneti adatnak rtke ne vltozzon meg, maradjon tovbbra is n; a msodik adat pedig legyen az n legnagyobb valdi osztja: Uf = ( Ef s d valdi osztja n-nek s brmelyik olyan k szm esetn, amelyik nagyobb mint d, a k nem valdi osztja n-nek ) Ha elemi matematikai jellssel akarjuk az lltsainkat megfogalmazni, azt is megtehetjk. Az utfelttelben egy oszt "valdi" voltt egyszeren kifejezhetjk a d [2..n1] lltssal, hiszen az n szm valdi oszti csak itt helyezkedhetnek el. (Vlaszthatnnk a [2..n div 2] intervallumot is, ahol az n div 2 az n felnek egszrtke.) Ha az intervallum egy eleme osztja az n-nek, akkor valdi osztja is. Alkalmazzuk a d n jellst arra, hogy a d osztja az n-nek. Ennek megfelelen pldul azt az lltst, hogy a "d valdi osztja n-nek" gy is rhatjuk, hogy "d [2..n1] s d n". Aki otthonosan mozog az elsrend logika nyelvben, tmrebben is felrhatja a specifikci

33

2. Specifikci

lltsait, ha hasznlja a logikai mveleti jeleket. Ez termszetesen nem vltoztat a specifikci jelentsn. (Az elfelttelnl kihasznljuk azt, hogy egy szm sszetettsge azt jelenti, hogy ltezik a szmnak valdi osztja.) Ennek megfelelen az el- s az utfelttelt az albbi formban is felrhatjuk: Ef = ( n = n k [2..n1]: k n ) Uf = ( Ef d [2..n1] d n k [d+1..n1] : k n ) Az el- s utfelttelben megjelen k a specifikci egy olyan eszkze (formula vltozja), amelyet lltsaink precz megfogalmazshoz hasznlunk. A k [a..b]:tulajdonsg(k) (van olyan, ltezik olyan k egsz szm az a s b kztt, amelyre igaz a tulajdonsg(k)) formula azt az lltst rja le, hogy a s b egsz szmok kz es egsz szmok egyike kielgti az adott tulajdonsgot. A k [a..b]:tulajdonsg(k) (brmelyik", "minden olyan" k egsz szm az a s b kztt, amelyre igaz a tulajdonsg(k)) formula azt jelenti, hogy a s b egsz szmok kz es mindegyik egsz szm kielgti az adott tulajdonsgot. A formulk helyes rtelmezshez rgzteni kell a kifejezsekben hasznlt mveleti jelek kztti precedencia sorrendet. Az ltalunk alkalmazott sorrend kiss eltr a matematikai logikban szoksostl, amennyiben az implikcit szorosabban kt mveletnek tekintjk, mint a konjunkcit (logikai s-t). Ennek az oka az, hogy viszonylag sokszor fogunk olyan lltsokat rni, ahol implikcis formulk lesznek sszeselve, s zavar lenne, ha kifejezseinkben tl sok zrjelet kellene hasznlni. Pldul a d n l d [2..n1] kifejezst a matematikai logikban a d n (l d [2..n1]) formban kellene rni.. A logikai mveleti jelek precedencia sorrendje teht: , , , , , . A knyvben hasznlt jellseknl a kettspont a kvantorok ( , ) hatsnak lershoz tartoz jel. Ezrt alkot egyetlen sszetartoz kifejezst a k [2..n1] : k n . A kifejezsek tartalmazhatnak a logikai mveleteken kvl egyb mveleteket is. Ezek prioritsa megelzi a kt-argumentum logikai mveleti jelekt. Ilyen pldul a nem logikai rtk kifejezsek egyenlsgt vizsgl (=) opertor is, ezrt rhatjuk az x = y z = y kifejezst az (x = y) (z = y) kifejezs helyett. Az egyb, nem logikai mveletek kztt ez az egyenlsg opertor az utols a precedencia sorban, ezrt senki ne olvassa pldul az x+y = z kifejezst x + (y = z) kifejezsnek. Nem fogjuk megklnbztetni a nem logikai rtkek

34

2.2. Feladatok specifikcija

egyenlsg opertort a logikai rtkek egyenlsg opertortl Erre a matematikai logikban az ekvivalencia ( ) mveleti jelet szoktk hasznlni. A szvegkrnyezetbl mindig kiderl, hogy melyik egyenlsg opertorrl van sz, legfeljebb zrjelezssel tesszk majd a formulinkat egyrtelmv. Ez egyben azt is jelenti az egyenlsg opertor precedencija jobb, mint az implikcij. Sokszor segt, ha a specifikci felrshoz bevezetnk nhny sajt jellst is. Br ezeket kln definilni kell, de hasznlatukkal olvashatbb, tmrebb vlik a formlis lers. Ha pldul az sszetett(n) azt jelenti, hogy az n termszetes szm egy sszetett szm (az sszetett(n) pontosan akkor igaz, ha k [2..n1]: k n), az LVO(n) pedig megadja egy sszetett n termszetes szm legnagyobb valdi osztjt, akkor az elz specifikci az albbi formban is lerhat. Ef = ( n = n sszetett(n) ) Uf = ( Ef d = LVO(n) ) Mdostsuk az elz feladatot az albbira: Keressk egy termszetes szm legnagyobb valdi osztjt. (Teht nem biztos, hogy van az adott szmnak egyltaln valdi osztja.) Itt az llapottrbe az elz feladathoz kpest egy logikai komponenst is fel kell vennnk, ami azt jelzi majd a clllapotban, hogy van-e egyltaln legnagyobb valdi osztja a megadott termszetes szmnak. Az elfelttel most nem tartalmaz semmilyen klnleges megszortst. Az utfelttel egyrszt bvl az l vltoz rtknek meghatrozsval (l akkor igaz, ha n sszetett), msrszt a d vltoz rtkt csak abban az esetben kell specifiklnunk, ha az l rtke igaz. Ha sszevetjk a specifikcit az elz feladat specifikcijval, akkor azt vehetjk szre, hogy az n sszetettsgt vizsgl llts ott az elfelttelben, itt az utfelttelben jelenik meg. A = (n:, l: , d:) Ef = ( n = n ) Uf = ( n = n l = k [2..n1]: k n l ( d [2..n1] d n k [d+1..n1]: k n) ) A fenti specifikci olvashatbb vlik, ha az elz feladatnl bevezetett sszetett s LVO jellseket hasznljuk:

35

2. Specifikci

A = (n:, l: , d:) Ef = ( n=n ) Uf = ( n=n l=sszetett(n) l d=LVO(n) ) Ugyanazt a feladatot tbbflekppen is lehet specifiklni. Minl sszetettebb egy problma, annl vltozatosabb lehet a lersa. A kvetkez igen egyszer pldt hromflekppen specifikljuk: nveljnk meg egy egsz szmot eggyel. Az els kt vltozatban kln komponens kpviseli a bemen (a vltoz) s kln a kimen adatot (b vltoz). Az els vltozat nem tartalmaz semmi klnset a korbbi specifikcikhoz kpest. A bemeneti adat megrzi a kezd rtkt a clllapotban is, ezrt a kimeneti vltoz rtknek meghatrozsnl mindegy, hogy a bemeneti vltoz vagy a paramter vltoz rtkre hivatkozunk. A msodik specifikcinl nem kveteljk meg, hogy az a vltoz ne vltozzon meg, ezrt a b vltoz rtknek meghatrozsnl az a vltoz kezd rtkt jelz a' paramtert kell hasznlnunk. Egszen ms felfogson alapul a harmadik specifikci. Ez gy rtelmezi a feladatot, hogy van egy adat, amelynek rtkt helyben kell megnvelni eggyel. Ilyenkor az llapottr egykomponens s az utfelttel megfogalmazsnl elengedhetetlenl fontos, hogy a kezdrtket rgzt paramter hasznlata. Ez a specifikci rvilgt arra is, hogy egy feladatban nem felttlenl klnlnek el a bemeneti s a kimeneti adatok. A = (a:, b:) A = (a:, b:) A = (a:) Ef = ( a=a ) Ef = ( a=a ) Ef = ( a=a ) Uf = ( a=a b=a+1 ) Uf = ( b=a+1 ) Uf = ( a=a+1 ) Vgl egy bemeneti adat nlkli feladat: Adjunk meg egy prmszmot! A = (p:) Ef =( igaz ) Uf =( p egy prmszm ) = ( k [2..p-1] : (k p) ) Ez a specifikci az sszes llapotot kezdllapotnak tekinti, amelyek mindegyikhez az sszes prmszmot rendeli. Az elfelttel egy azonosan igaz llts, hiszen semmilyen korltozst nem kell bevezetni a p vltozra, az kezdetben tetszleges rtket vehet fel, amelytl nem fgg az eredmny. ( Az utfelttelben a [ 2..p-1] intervallum helyett rhatnnk a [2.. n ] intervallumot is.)

36

2.3. Feladatok

2.3. Feladatok 2.1. Mit rendel az albb specifiklt feladat a (10,1) s a (9,5) llapotokhoz? Fogalmazza meg szavakban a feladatot! (prm(x) = x prmszm.) A = (k:, p:) Ef = ( k=k k>0 ) Uf = ( k=k prm(p)

i>1: prm(i)

k-i

k-p )

2.2. rja le szvegesen az albbi feladatot! (A perm(x') az x' permutciinak halmaza.) A = (x:n) Ef = ( x=x' ) Uf = ( x perm(x')

i,j [1..n]: i<j

x[i]

x[j])

2.3. Specifiklja: Adott egy hmrskleti rtk Celsius fokban. Szmtsuk ki Fahrenheit fokban! 2.4. Specifiklja: Adott hrom egsz szm. Vlasszuk ki kzlk a legnagyobb rtket! 2.5. Specifiklja: Adottak egy ax+b=0 alak elsfok egyenlet a s b vals egytthati. Oldjuk meg az egyenletet! 2.6. Specifiklja: Adjuk meg egy termszetes szm termszetes osztit! 2.7. Specifiklja a feladatot: Adjuk meg egy termszetes szm valdi termszetes osztjt! 2.8. Specifiklja: Dntsk el, hogy prmszm-e egy adott termszetes szm? 2.9. Specifiklja: Adott egy sakktbln egy kirlyn (vezr). Helyezznk el egy msik kirlynt gy, hogy a kt kirlyn ne sse egymst! 2.10. Specifiklja: Adott egy sakktbln kt bstya. Helyezznk el egy harmadik bstyt gy, hogy ez mindkettnek az tsben lljon!

37

3. Strukturlt programok
Ebben a fejezetben azt vizsgljuk meg, hogy ha egy programot meglev programokbl ptnk fel meghatrozott szablyok alapjn, akkor hogyan lehet eldnteni rluk, hogy megoldanak egy kitztt feladatot. Ennek rdekben elszr meghatrozzuk az elemi program fogalmt, definilunk nhny nevezetes elemi programot, majd hromfle ptsi szablyt, gynevezett programszerkezetet (szekvencia, elgazs, ciklus) mutatunk az sszetett programok ksztsre. Ezekkel a szablyokkal fokozatosan pthetnk fel egy programot: elemi programokbl sszetettet, az sszetettekbl mg sszetettebbeket. Az ilyen programokat sajtos, egymsba gyazd, ms nven strukturlt szerkezetk miatt strukturlt programoknak hvjk. Strukturlt programokat tbbflekppen is le lehet rni. Mi egy sajtos, a program szerkezett, struktrjt a kzppontba llt, a fent emltett hrom szerkezeten kvl ms szerkezetet meg nem enged absztrakt lerst, a struktogrammokat fogjuk erre a clra hasznlni. Ez a programlers egyszer, knnyen elsajtthat, s termszetes mdon fordthat le ismert programozsi nyelvekre, azaz brmelyik konkrt programozsi krnyezetben jl hasznlhat; egyszerre illeszkedik az emberi gondolkodshoz s a magas szint programozsi nyelvekhez.3 A struktogramm egy program lersra szolgl eszkz, de felfoghat a megoldand feladat egyfajta lersnak is. Egy program ksztsekor ugyanis a feladatot prbljuk meg rszfeladatokra bontani s meghatrozni, hogy a rszfeladatok megoldsait, hogyan, melyik
3

A modellnkben bevezetett program fogalma annyira ltalnos, hogy nem minden ilyen program rhat le struktogramm segtsgvel. Ez nem a struktogramm-lers hibja, ugyanis ezen programok ms eszkzkkel (folyamatbra, C++ nyelv vagy Turing gp) sem rhatk le. A Church-Turing tzis szerint csak a parcilis rekurzv fggvnyeket kiszmt (megold) programok algoritmizlhatk. Ezek mind lerhatk folyamatbrkkal; a Bhm-Jaccopini ttele szerint pedig, brmelyik folyamatbrval megadott program struktogrammal is lerhat. A struktogramm teht azon tl, hogy a programokat egy jl ttekinthet szerkezetet segtsgvel adja meg, egy kellen ltalnos eszkz is: brmely algoritmizlhat program lerhat vele.

38

programszerkezet segtsgvel kell egy programm pteni. A programtervezs kzbls szakaszban teht egy struktogramm nem elemi programokbl, hanem megoldand rszfeladatokbl pti fel a programot. Ez azrt nem ellentmonds, mert elmletben minden feladat megoldhat egy elemi programmal (lsd 3.3. alfejezet), s ezrt csak nzpont krdse, hogy egy rszfeladatot feladatnak vagy programnak tekintnk-e. A programkszts sorn lpsrl lpsre jelennek meg az egyre mlyebben begyazott programszerkezetek, ami a feladat egyre finomabb rszletezsnek eredmnye. Ezltal a program kvlrl befel haladva, gynevezett fellrl-lefele (top-down) elemzssel szletik. A feladat finomtsnak vgn a struktogrammban legbell lev, szerkezet nlkli egysgeknek mr magtl rtetden megoldhat rszfeladatokat kell kpviselnik.

39

3. Strukturlt programok

3.1. Elemi programok Elemi programoknak azokat a programokat nevezzk, amelyek vgrehajtsai nagyon egyszerek; mkdsket egy vagy kett hossz azonos llapotter llapotsorozatok vagy a kiindul llapotot vgtelen sokszor ismtl (abnormlisan) vgtelen sorozatok jellemzik. 3.1.1. res program Az res program a legegyszerbb elemi program. Ez az gynevezett semmit sem csinl program brmelyik llapotbl indul is el, abban az llapotban marad; vgrehajtsai a kiindul llapotbl ll egyelem sorozatok. Az res programot a tovbbiakban SKIP-pel jelljk. Nyilvnval, ahhoz, hogy semmit sem csinlva eljussunk egy llapotba, mr eleve abban az llapotban kell lennnk. A gyakorlatban kitztt feladatok azonban jval bonyolultabbak annl, hogy azokat res programmal megoldhassuk. Gyakori viszont az, hogy egy feladat rszekre bontsnl olyan rszfeladatokhoz jutunk, amelyet mr az res programmal meg lehet oldani. Az res program teht gyakran jelenik meg valamilyen programszerkezetbe gyazva. (Szerepe a programban ahhoz hasonlthat, amikor a kmves egy res teret rak krbe tglval azrt, hogy ablakot, ajtt ksztsen az pl hzon. A semmi ezltal vlik az plet fontos rszv.) Nzznk most egy erltetett pldt arra, amikor egy feladatot az res program old meg. Legyen a feladat specifikcija az albbi: A = (a:, b:, c:) Ef = ( a=2 b=5 c=7 ) Uf = ( Ef (c=a+b c=10) ) Itt az Ef lltsbl kvetkezik az Uf llts (Ef Uf). Ez azt jelenti, hogy ha egy Ef-beli llapotbl (teht amire teljesl az Ef llts) elindulunk, akkor erre rgtn teljesl az Uf llts is: ezrt nem kell semmit sem tenni ahhoz, hogy Uf-ben tudjunk megllni, hiszen mr ott vagyunk. Ezt a feladatot teht megoldja a SKIP. ltalnostva az itt ltottakat azt mondhatjuk, ha egy feladat elfelttelbl kvetkezik az utfelttele, akkor a SKIP program biztosan megoldja azt.

40

3.1. Elemi programok

3.1.2. Rossz program Rossz program a mindig abnormlisan mkd program. Brmelyik llapotbl indul is el, abnormlis vgrehajtst vgez: a kiindul llapotot vgtelen sokszor ismtl vgtelen vgrehajtst fut be. A rossz programot a tovbbiakban ABORT-tal jelljk. A rossz program nem tl hasznos, hiszen semmikppen nem terminl, gy sosem tud megllni egy kvnt clllapotban. A rossz programmal csak az res feladatot, azaz a sehol sem rtelmezett, teht rtelmetlen feladatot lehet megoldani: azt, amelyik egyik llapothoz sem rendel clllapotokat. A feladatok megoldsa szempontjbl az ABORT-nak teht nincs tl nagy jelentsge. Annak az oka, hogy mgis bevezettk az, hogy program lersunkat minl ltalnosabb tegyk, segtsgvel minl tbb programot, mg a rosszul mkd programokat is le tudjuk rni. 3.1.3. rtkads A programozsban rtkadsnak azt hvjuk, amikor a program egy vagy tbb vltozja egy lpsben j rtket kap. Mivel a program vltozi az aktulis llapot komponenseit jelentik meg, ezrt az rtkads sorn megvltozik az aktulis llapot. Vegyk pldaknt az (x:, y:) llapottren azt a kznsges rtkadst, amikor az x vltoznak rtkl adjuk az x y kifejezs rtkt. Ezt az rtkadst brmelyik llapotra vgre lehet hajtani, s minden esetben kt llapotbl (a kiindul- s a vgllapotbl) ll sorozat lesz a vgrehajtsa. Pldul < (2,-5) (-10,-5) >, < (2.3,0.0) (0.0,0.0) >, < (0.0,4.5) (0.0,4.5) > vagy <(1,1) (1,1) >. Ezt az rtkadst az x:=x y szimblummal jelljk. Az x y kifejezs htterben egy olyan lekpezs (fggvny) ll, amely kt vals szmhoz (az aktulis llapothoz) egy vals szmot (az x vltoz j rtkt) rendeli s minden vals szmprra rtelmezett. Tekintsk most az (x:, y:) llapottren az x:=x/y parcilis rtkadst. Azokban a kiindul llapotokban, amikor az y-nak az rtke 0, az rtkads jobboldalon ll kifejezsnek nincs rtelme. A jobboldali kifejezs teht nem mindenhol, csak rszben (parcilisan) rtelmezett. Ebben az esetben gy tekintnk az rtkadsra, mint egy rossz programra, azaz a nem rtelmezhet kiindul llapotokbl

41

3. Strukturlt programok

indulva abortl.4 Ezzel biztostjuk, hogy ez az rtkads is program legyen: minden kiindul llapothoz rendeljen vgrehajtsi sorozatot. A feladatok megoldsakor gyakran elfordul, hogy egy idben tbb vltoznak is j rtket akarunk adni. Ez a szimultn rtkads tovbbra is egy llapotbl egy msik llapotba vezet, de az j llapot tbb komponensben is eltrhet a kiindul llapottl.5 A httrben itt egy tbbrtk fggvny ll, amelyik az aktulis llapothoz rendeli azokat az rtkeket, amelyeket a megfelel vltozknak kell rtkl adni. Egy rtkads jobboldaln ll kifejezs rtke nem mindig egyrtelm. Ekkor a baloldali vltoz vletlenszeren veszi fel a kifejezs ltal adott rtkek egyikt. Erre plda az, amikor egy vltoznak egy halmaz valamelyik elemt adjuk rtkl. Ekkor az llapottr az (x:, h:2) (a h rtke egy termszetes szmokat tartalmaz halmaz), az rtkads sorn pedig az x a h valamelyik elemt kapja. Ezt az rtkadst rtkkivlasztsnak (vagy nemdeterminisztikus rtkadsnak) fogjuk hvni s az x: h kifejezssel jelljk.6 Ez a plda radsul parcilis rtkads is, hiszen ha a h egy res halmaz, akkor a fenti rtkkivlaszts rtelmetlen, teht abortl. Ez rvilgt arra, hogy az rtkadsnak fent bemutatott ltalnostsai (parcilis, szimultn, nem-determinisztikus) egymst kiegsztve halmozottan is elfordulhatnak. A httrben itt egy nem-egyrtelm lekpezs (teht nem fggvny), egy relci ll.
4

Ezzel a jelensggel a programoz pldul akkor tallkozik, amikor az opercis rendszer "division by zero" hibazenettel lelltja a program futst. 5 A szimultn rtkadsokat a kdolskor egyszer rtkadsokkal kell helyettesteni (lsd 6.3. alfejezet), ha a programozsi nyelv nem tmogatja ilyenek rst. 6 A nem-determinisztikus rtkadsokat a mai szmtgpeken determinisztikus rtkadsok helyettestik. Ez a helyettests azonban nem mindig a programoz feladata, hanem gyakran az a programozsi krnyezet vgzi, ahol a programot hasznljuk. Ez elrejti a programoz ell azt, hogyan vlik determinisztikuss egy rtkads, gy az kvzi nem-determinisztikus. Ez trtnik pldul a vletlenszm-genertorral trtn rtkads sorn. Habr ez a nevvel ellenttben nagyon is kiszmthat, az ellltott rtk a program szempontjbl mgis nemdeterminisztikus lesz.

42

3.1. Elemi programok

ltalnos rtkadsnak egy szimultn, parcilis, nemdeterminisztikus rtkadst tekintnk. A nem-szimultn rtkadst egyszernek, a nem parcilist teljesnek (mindenhol rtelmezettnek) nevezzk, az rtkkivlaszts ellentte a determinisztikus rtkads. A kznsges rtkadson az egyszer, teljes s determinisztikus rtkadst rtjk. Az rtkads ktsget kizran egy program, amelyik az llapottr egy llapothoz az adott llapotbl indul ktelem vagy abnormlisan vgtelen llapotsorozatot rendel. (Nem-determinisztikus esetben egy kiindul llapothoz tbb vgrehajts is tartozhat.) Jellsekor a := szimblum baloldaln feltntetjk, hogy mely vltozk kapnak j rtket, a jobboldalon felsoroljuk az j rtkeket elllt kifejezseket. Ezek a kifejezsek az llapottr vltozibl, azok tpusainak mveleteibl, esetenknt konkrt tpusrtkekbl (konstansokbl) llnak. A kifejezs rtke a vltozk rtktl, azaz az aktulis llapottl fgg, amit a kifejezs egy rtkk alakt s azt a baloldalon ll vltoznak addik rtkl. Nem-determinisztikus rtkads, azaz rtkkivlaszts esetn a := szimblum helyett a : szimblumot hasznljuk. Az rtkadst nemcsak azrt tekintjk elemi programnak, mert vgrehajtsa elemi lpst jelent az llapottren, hanem azrt is, mert knny felismerni, hogy milyen feladatot old meg. Ha pldul egy x, y, z egsz vltozkat hasznl feladat utfelttele annyival mond tbbet az elfelttelnl, hogy teljesljn a z = x+y llts is, akkor nyilvnval, hogy ezt a z:=x+y rtkads segtsgvel rhetjk el. Ha a megoldand feladat az, hogy cserljk ki kt vltoz rtkt, azaz A = (x:, y:), Ef = (x=x y=y) s Uf = (x=y y=x), akkor ezt az x,y:=y,x rtkads oldja meg. 3.2. Programszerkezetek A strukturlt programok ptsnl hrom nevezetes programszerkezetet hasznlunk: szekvencit, elgazst, ciklust. 3.2.1. Szekvencia Kt program szekvencijn azt rtjk, amikor az egyik program vgrehajtsa utn feltve, hogy az terminl a msikat hajtjuk vgre.

43

3. Strukturlt programok

Ez a meghatrozs azonban nem elegend a szekvencia pontos megadshoz. Ahhoz ugyanis, hogy egy szekvencia vgrehajtsi sorozatait ez alapjn felrhassuk, meg kell elbb llapodni abban, hogy mi legyen a szekvencia alap-llapottere. A tagprogramok alapllapotterei ugyanis klnbzhetnek egymstl, s ilyenkor nyilvnvalan meg kell llapodni egy kzs alap-llapottrben, amely majd a szekvencia llapottere lesz. A tagprogramokat majd erre a kzs llapottrre kell tfogalmazni, azaz vltozik alap- illetve segdvltozi sttuszt ennek megfelelen kell megvltoztatni, esetleg bizonyos vltozkat t kell nevezni. (Emltettk, hogy az ilyen talakts nem vltozat egy program lnyegn.) A kzs alap-llapottr kialaktsa sorn elfordulhat az is, hogy az eredetileg kizrlag csak az egyik tagprogram alap- vagy segdvltozja a szekvencia kzs alapvltozjv vlik, vagy a szekvencia alap-llapotterbe olyan komponensek kerlnek be, amely az egyik tagprogramnak alap- vagy segdvltozi, a msik tagprogramban pedig segdvltozk voltak. (A segdvltozra vonatkoz ltrehoz s megszntet utastsok ilyenkor rvnyket vesztik.) A kzs alap-llapottr kialaktsa mg akkor sem egyrtelm, ha a kt tagprogram alap-llapottere ltszlag megegyezik. Elkpzelhet ugyanis pldul az, hogy egy mindkt alap-llapotrben szerepl ugyanolyan nev s tpus vltozt nem akarunk a szekvenciban kzs vltoznak tekinteni. Vgl szgezzk le, hogy a kzs alap-llapottr komponensei kizrlag a szekvenciba fztt tagprogramok vltozi kzl kerlhetnek ki. Egy azoknl nem szerepl vltozt nem vesznk fel a kzs alap-llapottrbe (ennek ugyanis nem lenne semmi rtelme). A szekvencia vgrehajtsi sorozatai, miutn mindkt tagprogramot a kzs alap-llapottren jrartelmeztk, gy kpzdnek, hogy az els tagprogram egy vgrehajtshoz amennyiben a vgrehajts vges hossz hozzfzdik a vgrehajts vgpontjbl a msodik tagprogram ltal indtott vgrehajts. A szekvencia is program, hiszen egyrszt a kzs alap-llapottr minden llapotbl indt vgrehajtst (hiszen az els tagprogram is gy tesz), msrszt ezeknek a vgrehajtsoknak az els llapota a kiindul llapot (ugyancsak amiatt, hogy az els tagprogram egy program). Harmadrszt minden vges vgrehajtsi sorozat a kzs alapllapottrben ll meg, hiszen ezek utols szakaszt a msodik tagprogram generlja, amelynek vges vgrehajtsi sorozatai a kzs

44

3.2. Programszerkezetek

alap-llapottrre val talaktsa utn ebben az llapottrben terminlnak (lvn a msodik tagprogram is program). Termszetesen ezen az elven nemcsak kett, hanem tetszleges szm programot is szekvenciba fzhetnk. Az S1 s S2 programokbl kpzett szekvencit az (S1;S2) szimblummal jellhetjk vagy az albbi rajzzal fejezhetjk ki. Ezek a jellsek rtelemszeren hasznlhatk a kettnl tbb tag szekvencikra is. S1 S2 Milyen feladat megoldsra hasznlhatunk szekvencit? Ha egy feladatot fel lehet bontani rszfeladatokra gy, hogy azokat egyms utn megoldva az eredeti feladat megoldst is megkapjuk, akkor a megold programot a rszfeladatot megold programok szekvencijaknt llthatjuk el. Formlisan: ha adott egy feladat (A,Ef,Uf) specifikcija, amelybl el tudunk lltani egy (A,Ef,Kf) specifikcij rszfeladatot, valamint egy (A,Kf,Uf) specifikcij rszfeladatot, ahol Kf az gynevezett kzbees felttel, akkor a rszfeladatokat megold programok szekvencija megoldja az eredeti feladatot. Ugyanis ekkor az els rszfeladatot megold program elvezet Ef-bl (egy Ef ltal kielgtett kezdllapotbl) Kf-be, a msodik a Kfbl Uf-be, azaz sszessgben a szekvencijuk eljut Ef-bl Uf-be. Tekintsk pldul azt a feladatot, amikor kt egsz rtk adat rtkt kell kicserlni. (Korbban mr megoldottuk ezt a feladatot egy szimultn rtkadssal. Ha azonban az adott programozsi krnyezetben nem alkalmazhat szimultn rtkads, akkor mssal kell prblkozni.) Emlkeztetl a feladat specifikcija: A = (x:, y:) Ef = ( x=x y=y ) Uf = ( x=y y=x ) Bontsuk fel a feladatot hrom rszre az albbi, kicsit trkks Kf1 s Kf2 kzbees lltsok segtsgvel. Ezltal hrom, ugyanazon az llapottren felrt rszfeladat specifikcijhoz jutottunk. A rszfeladatok llapottere azonos az eredeti llapottrrel, az els feladat

45

3. Strukturlt programok

elfelttele az Ef, utfelttele a Kf1, a msodik elfelttele a Kf1, utfelttele a Kf2, a harmadik elfelttele a Kf2, utfelttele az Uf. Kf1 = ( x=x y y=y ) Kf2 = ( x= x y y=x ) Elszr prbljunk meg az els rszfeladatot megoldani, azaz eljutni a Ef-bl a Kf1-be. Nyilvnval, hogy ezt a rszfeladatot az x:=x y megoldja, hiszen kezdetben (Ef) x az x, y az y rtket tartalmazza. A msodik rszfeladatban az y-nak kell az x eredeti rtkt, az x-t megkapni, ami (xy)+y alakban is felrhat. Mivel a Kf1 (ez a msodik feladat elfelttele) szerint kezdetben x=xy s y=y, az ami (xy)+y-t az x+y alakban is rhatjuk. A msodik feladat megoldshoz teht megfelel az y:=x+y rtkads. Hasonlan okoskodva jn ki, hogy a harmadik lpshez az x:=yx rtkads szksges. A teljes feladat megoldsa teht az albbi szekvencia lesz, amelyben mindhrom tagprogram s a szekvencia kzs alapllapottere is a feladat llapottere: x:=xy y:=x+y x:=yx Oldjuk meg most ugyanezt a feladatot mskppen: segdvltozval. Bontsuk fel a feladatot hrom rszre gy, hogy elszr tegyk flre egy z: vltozba az x vltoz rtkt, (ezt a kvnsgot rgzti a Kf1), ezt kveten az x rtke az y vltoz rtkt vegye fel, mikzben a z vltoz rzi az rtkt (ezt mutatja a Kf2), vgl kerljn t a z vltozba flretett rtk az y vltozba. Mindhrom rszfeladat llapottere az eredeti llapottrnl bvebb: A = (x:, y:, z:). Kf1 = ( x=x y=y z=x ) Kf2 = ( x=y y=y z=x ) Az els rszfeladatot knny megoldani: a Kf1 a z=x lltssal mond tbbet az Ef-nl, s az x ppen az x vltoz rtke, ezrt a z:=x rtkads vezet el az Ef-bl a Kf1-be. Ennek a programnak a z egy eredmny (nem pedig segd) vltozja, az y pedig akr el is hagyhat az llapotterbl. Mivel a z vltoz a programban ennek az

46

3.2. Programszerkezetek

rtkadsnak a baloldaln jelenik meg elszr, ezrt r a struktogramm els rtkadsa mellett kln felhvjuk a figyelmet a tpusnak megadsval. A msodik rszfeladatnl Kf1-bl a Kf2-be az x:=y rtkads visz t, hiszen itt az egyetlen klnbsg a kt llts kztt az, hogy az x vltoz rtkt az y-ban trolt y rtkre kell tlltani. A ksbbiek miatt fontos viszont, hogy ennek a programnak llapottere tartalmazza a z (bemen s eredmny) vltozt is. A harmadik rszfeladatban Kf2-bl a Uf-be kell eljutni. Itt az y-t kell megvltoztatni gy, hogy vegye fel az x eredeti rtkt, az x-t, amit a Kf2 szerint a zben tallunk. Teht: y:=z. Most a z egy bemen vltoz. Mindezek alapjn knny ltni, hogy az albbi szekvencia megoldja a kitztt feladatot. Ehhez azonban elszr a program alapllapottert kell a feladathoz igaztani, leszkteni, amely hatsra a z vltoz szekvencia egy segdvltozjv vlik: z:=x x:=y y:=z A programtervezs sorn az a legfontosabb krds, hogy mirl lehet felismerni, hogy egy feladatot szekvencival kell megoldani, milyen lpsekbl lljon a szekvencia, hogyan lehet megfogalmazni azokat a rszclokat, amelyeket a szekvencia egyes lpsei oldanak meg, s mi lesz ezen lpseknek a sorrendje. Ezekre a krdsekre a feladat specifikcijban kereshetjk a vlaszt. Pldul, ha az utfelttel egy kapcsolatokkal felrt sszetett llts, akkor gyakran az llts egyes tnyezi szolglnak rszclknt egy szekvencihoz. (De vigyzat! Nem trvnyszer, hogy az utfelttel kapcsolata mindenkppen szekvencit eredmnyez.) A rszclok kztti sorrend azon mlik, hogy az egyes rszek utalnak-e egymsra, s melyik hasznlja fel a msik eredmnyt. Kijellve az utfelttelnek azt a rszt, amelyet elszr kell teljesteni, elll az a kzbls llapotokat ler logikai llts, amely az els rszfeladat utfelttele s egyben a msodik rszfeladat elfelttele lesz. Hozzvve ehhez a feladat utfelttelnek itt mg nem rintet felt vagy annak egy rszt, megkapjuk a msodik rszfeladat utfelttelt, s gy tovbb. Az z:

47

3. Strukturlt programok

eredeti elfelttel az els rszfeladat elfelttele, az eredeti utfelttel az utols rszfeladat utfelttele lesz. 3.2.2. Elgazs Amikor egy feladatot nem egyms utn megoldand rszfeladatokra, hanem alternatv mdon megoldhat rszfeladatokra tudunk csak felbontani, akkor elgazsra van szksgnk. Elgazs az, amikor kt vagy tbb programhoz egy-egy felttelt rendelnk, s mindig azt a programot gynevezett programgat hajtjuk vgre, amelyhez tartoz felttel az aktulis llapotra teljesl. Ha egyszerre tbb felttel is igaz, akkor ezek kzl valamelyik programg fog vgrehajtdni, ha egyik sem, akkor az elgazs abortl.7 Az elgazs alap-llapottert megllapods alapjn alaktjuk ki az elgazs feltteleit alkot kifejezsekben hasznlt vltozkbl s a programgak vltozibl, tbbnyire azok unijbl. A felttelek vltozi a kzs llapottr bemen vltozi lesznek. Elfordulhat itt is, hogy kt programg ltszlag ugyanazon vltozit, elbb tnevezssel meg kell egymstl klnbztetni. Ksztsk el az albbi elgazst! Vegyk az (x:, y:, max:) llapottren a max:=x s a max:=y rtkadsokat. Rendeljk az elshz az x y, a msodikhoz az x y felttelt. Tekintsk azt a programot, amelyik az x y felttel teljeslse esetn a max:=x, az x y felttel bekvetkezsekor a max:=y rtkadst hajtja vgre. Az gy konstrult elgazs a (8,2,0) llapothoz (mivel erre az els felttel teljesl) a (8,2,0),(8,2,8) sorozatot, az (1,2,0)-hoz (erre a msodik felttel teljesl) az (1,2,0),(1,2,2) sorozatot rendeli. A (2,2,0) llapot mindkt
7

A magas szint programozsi nyelvek tbbsge ettl eltr mdon definilja az elgazst. Egyrszt rgztik az gak kzti sorrendet azzal, hogy mindig az els olyan gat hajtjk vgre, amelyiknek felttelt kielgti az aktulis llapot. Msrszt, ha egyik felttel sem teljesl, akkor az elgazs az res programmal azonos. Mi ezt azrt nem vesszk t, hogy a programjaink helyessge nem fggjn attl, hogy egyrszt az elgazs eseteit milyen sorrendben gondoltuk vgig, msrszt, ha egy esetre elfelejtettnk gondolni (egyik felttel sem teljesl), akkor a program erre figyelmeztetve hibsan mkdjn.

48

3.2. Programszerkezetek

felttelt kielgti, ezrt r tetszs szerint brmelyik rtkads vgrehajthat. A pldban ezek vgrehajtsnak eredmnye azonos; mindkt esetben a (2,2,0),(2,2,2) sorozatot kapjuk. Az elgazs gai kztt semmifle elsbbsgi sorrend nincs, ezrt ha egy kiindul llapotra egyszerre tbb felttel is teljesl, akkor az elgazs vletlenszeren vlasztja ki azt az gat, amelynek felttelt az adott llapot kielgti. Az elgazs teht annak ellenre nemdeterminisztikuss vlhat, ha az gai egybknt determinisztikus programok. Az mr a programoz felelssge, hogy ilyen esetben is biztostsa, hogy az elgazs jl mkdjn. (A pldban a feltteleknek legalbb egyike mindig teljesl.) Olyan elgazsokat is lehet szerkeszteni, ahol egy kiindul llapot egyik felttelt sem elgti ki. Ilyenkor azt kell feltteleznnk, hogy a programoz nem szmolt ezzel az esettel, az elgazsnak teht "hivatalbl" rosszul kell mkdnie. Ezrt ilyenkor az elgazs definci szerint abortl. Sokszor a feltteleket gy alaktjuk ki, hogy azok kzl az llapottr minden elemre pontosan az egyik teljesljn. Ezzel kizrjuk mind a nemdeterminisztikuss vls, mind az abortls esett. Az elgazs nyilvnvalan program, hiszen minden llapothoz rendel nmagval kezdd vgrehajtsi sorozatot: ha egy llapot valamelyik felttelt kielgti, akkor az ahhoz tartoz programg ltal ellltott sorozatot, ha egyik felttelt sem elgti ki, akkor az abortl sorozatot. Az S1, ... ,Sn A llapottr feletti programokbl s az f1, ... ,fn A llapottr feletti felttelekbl kpzett elgazst az IF(f1:S1, ... ,fn:Sn)-nel jelljk s az albbi brval rajzoljuk: f1 S1 ... ... fn Sn

Ha olyan n g elgazst kell jellnnk, ahol az n-edik g felttele akkor teljesl, ha az elz gak egyik felttele sem, azaz fn= f1 fn-1, akkor az fnt helyettesthetjk az else jellssel. A leggyakrabban elfordul elgazsok ktgak, amelyek kztt gyakran fogunk tallkozni olyanokkal, amelyekben egyik felttel a

49

3. Strukturlt programok

msik ellentte. Az albbi brk egymssal egyenrtk mdon fejezik ki az ilyen elgazsokat. f S1 f S2 S1 f S2

Milyen feladat megoldsra hasznlhatunk elgazst? Pldul, ha a feladat utfelttele esetsztvlasztssal hatrozza meg a clt. Ezt gyakran a ha-akkor szfordulatokkal (logikai implikci jelvel) fejezzk ki. Ilyenkor elszr meg kell hatroznunk az egyes eseteket ler feltteleket (fi). Ezutn meg kell bizonyosodnunk arrl, hogy az Ef-nek eleget tev brmelyik llapotra legalbb ez egyik felttel teljesl (azaz Ef f1 ... fn), mert klnben az elgazs abortl. A rszfeladatok kialaktsnl az albbiak szerint jrunk el. Az i-edik esethez (ghoz) tartoz rszfeladat kezdllapotai az eredeti feladat azon a kezdllapotai, amelyek eleget tesznek az i-edik felttelnek is. A rszfeladat clllapotai az eredeti feladat clllapotai. Az i-edik g rszfeladatnak specifikcija teht: (A, Ef fi, Uf). Mindezek alapjn belthat, hogy ha Ef f1 ... fn s minden i {1..n}-re az Si programg megoldja az (A, Ef fi, Uf) rszfeladatot, akkor az IF(f1:S1, ... ,fn:Sn) elgazs megoldja az (A, Ef, Uf) feladatot. Pldaknt oldjuk meg azt a feladatot, amelyben egy egsz szmot a szignumval kell helyettestennk. A pozitv szmok szignuma 1, a negatvok 1, a null pedig 0. A feladat specifikcija: A = (x: ) Ef = ( x=x ) Uf = ( x=sign(x) )
1 ha z 0 z 0 z 0

ahol sign(z) =

0 ha 1 ha

Az utfelttel hrom esettel specifiklja a x vltoz j rtkt: x>0, x=0 s x<0. Ez a hrom eset lefedi az sszes lehetsges esetet s egyszerre kzlk csak az egyik lehet igaz. A szignum fggvny defincijbl ltszik, hogy az els esetben az x j rtke az 1 lesz, msodik esetben a 0, harmadik esetben a 1. Vilgos teht, hogy az albbi elgazs megoldja a feladatot.

50

3.2. Programszerkezetek

x>0 x:=1

x=0 x:=0

x<0 x:= 1

3.2.3. Ciklus Ciklus mkdse sorn egy adott programot, az gynevezett ciklusmagot egyms utn mindannyiszor vgrehajtjuk, valahnyszor olyan llapotban llunk, amelyre egy adott felttel, az gynevezett ciklusfelttel teljesl. Tekintsnk egy pldt. Legyenek az llapottr llapotai a [5 .. + [ intervallumba es egsz szmok. Vlasszuk ciklusmagnak azt a programot, amely az aktulis llapotot (egsz szmot) mindig a szignumval nveli meg, azaz ha az llapot negatv, akkor cskkenti eggyel, ha pozitv, nveli eggyel, ha nulla, nem vltoztatja az rtkt. Legyen a ciklusfelttel az, hogy az aktulis llapot nem azonos a 20szal. Amikor az 5 llapotbl indtjuk a ciklust, akkor a ciklusmag els vgrehajtsa elvezet a 6 llapotba, majd msodszorra a 7-be s gy tovbb egszen addig, amg tizentdszr is vgrehajtdik a ciklusmag, s a 20 llapotba nem jutunk (ez mr nem elgti ki a ciklusfelttelt), itt a ciklus lell. A ciklus teht az 5 kiindul llapotbl az 5,6,7, ... ,19,20 llapotsorozatot futja be. Amennyiben a 20 a kiindul llapot, a ciklus rgtn lell, a 20-hoz teht a 20 egy elem vgrehajts tartozik. A 21 vagy annl nagyobb llapotokrl indulva a ciklus sohasem ll le: a ciklusmag minden lpsben nveli eggyel az aktulis llapotot, s az egyre nveked llapotok ( 21,22,23, ... ) egyike sem lesz egyenl 20szal, azaz nem elgtik ki a ciklusfelttelt. Ugyanez trtnik amikor a 0 llapotbl indulunk el, hiszen ekkor a ciklusmag sohasem vltoztatja meg az aktulis llapott, azaz a <0,0,0, > vgtelen sorozat hajtdik vgre. (Mindkt esetre azt mondjuk, hogy a program vgtelen ciklusba esett.) A 1-rl indulva viszont lpsrl lpsre cskkenti a ciklus az aktulis llapotot, de amikor a 5-hz r, a ciklus mkdse elromlik. A ciklusmag ugyanis nem kpes a 5-t cskkenteni, hiszen ez kivezetne az llapottrbl; a ciklusmag a 5-ben abortl. A teljes vgrehajtsi sorozat a 1,2,3,4,5,5,5, ... .

51

3. Strukturlt programok

Egy ciklus vgrehajtst jelkpez llapotsorozat annyi szakaszra bonthat, ahnyszor a ciklusmagot vgrehajthattuk egyms utn. Egyegy szakasz a ciklusmag egy-egy vgrehajtsa. A pldnkban ez egyetlen lps volt (teht egyetlen rtk kpviselt egy szakaszt), de ltalban a ciklusmag egy vgrehajtsa hosszabb llapotsorozatot is befuthat. Egy-egy szakasz kiindul llapota mindig kielgti a ciklusfelttelt. (A szakasz tbbi llapotra ennek nem kell fennllnia.) Amennyiben a szakasz vges hossz s a vgpontja jra kielgti a ciklusfelttelt, a ciklusmag ebbl a pontbl jabb szakaszt indt. A ciklus egy vgrehajtsa lehet vges vagy vgtelen. A vges vgrehajtsok vges sok vges hossz szakaszbl llnak, ahol a szakaszok kiindul llapotai kielgtik a ciklusfelttelt, az utols szakasz vgllapota viszont mr nem. A vges vgrehajtsok egy specilis esete az, amikor mr a ciklus kiindul llapota sem elgti ki a ciklusfelttelt, gy nem kerl sor a ciklusmag egyetlen vgrehajtsra sem. Ilyenkor a vgrehajts egyelem sorozat lesz. A vgtelen vgrehajtsok ktflk. Vannak olyanok, amelyek vgtelen sok vges hossz szakaszbl llnak. Itt minden szakasz egy ciklusfelttelt kielgt llapotban vgzdik. (vgtelen ciklus). Ms vgtelen vgrehajtsok ellenben vges sok szakaszbl llnak, de a legutols szakasz vgtelen hossz. Ilyenkor a ciklusmag egyszer csak valamilyen okbl nem terminl. Ez a hibs ciklusmag esete. A ciklus alap-llapottert a ciklusmag alap-llapottere s a ciklusfelttelt ad kifejezs vltozibl megllapods alapjn alaktjuk ki. A ciklus tnyleg program, hiszen az llapottr minden pontjhoz rendel nmagval kezdd sorozatot. A ciklust a tovbbiakban a LOOP(cf, S) szimblummal, illetve a cf S brval fogjuk jellni. Felismerni, hogy egy feladatot ciklussal lehet megoldani, majd megtallni ehhez a megfelel ciklust, nem knny. Ez csak sok gyakorls sorn megszerezhet intucis kszsg segtsgvel sikerlhet. Bizonyos klszablyok termszetesen felllthatak, de a szekvencia illetve az elgazsokhoz kpest sszehasonlthatatlanul

52

3.2. Programszerkezetek

nehezebb egy helyes ciklus konstrulsa. Ahhoz, hogy egy ciklus megold-e egy Ef s Uf-fel specifiklt feladatot, kt kritriumot kell beltni. Az egyik, az gynevezett lellsi kritrium, amely azt biztostja, hogy az Ef-bl (Ef ltal kijellt llapotbl) elindtott ciklus vges lps mlva biztosan lell, azaz olyan llapotba jut, amelyre a ciklusfelttel hamis. A msik, az gynevezett haladsi kritrium, azt biztostja, hogy ha az Ef-bl elindtott ciklus valamikor lell, akkor azt j helyen, azaz Uf-ben (Uf-beli llapotban) teszi. A lellsi kritrium igazolshoz pldul elegend az, ha a ciklus vgrehajtsa sorn a ciklusfelttel ellenrzsekor rintett llapotokban meg tudjuk mondani, hogy a ciklus magjt mg legfeljebb hnyszor fogja a ciklus vgrehajtani, s ez a szm a ciklusfelttel teljeslse esetn mindig pozitv s a ciklusmag egy vgrehajtsa utn legalbb eggyel cskken. Ekkor ugyanis csak vges sokszor fordulhat el, hogy ezen llapotokban a ciklusfelttel igazat ad, teht a ciklusnak vges lpsen bell meg kell llni. Vannak olyan feladatokat megold ciklusok is, amelyek lellsnak igazolsa ennl jval nehezebb, van, amikor nem is dnthet el. A haladsi kritrium igazolshoz a ciklus gynevezett invarins tulajdonsgt kell megtallnunk. Ez a ciklusra jellemz olyan llts (jelljk I-vel), amelyet mindazon llapotok kielgtenek, ahol a ciklus akkor tartzkodik, amikor sor kerl a ciklusfelttelnek kirtkelsre. Megfordtva, egy I lltst akkor tekintnk invarinsnak, ha teljesl r az, hogy az I-t s a ciklusfelttelt egyszerre kielgt llapotbl elindulva a ciklusmag vgrehajtsa egy I-t kielgt llapotban fog megllni, azaz I cf-bl I-be jut. Az invarins lltst kielgt llapotokbl indtott ciklus mkdse teht ebben az rtelemben jl kiszmthat, hiszen biztosak lehetnk abban, hogy amennyiben a ciklus lell, akkor I-beli llapotban fog megllni. Egy ciklusnak tbb invarins lltsa is lehet, de ezek kzl neknk arra van szksgnk, amely segtsgvel meg tudjuk mutatni, hogy a ciklus megoldja az Ef s Uf-fel specifiklt feladatot, azaz ha lell akkor eljut az Ef-bl az Uf-be. Ehhez egyrszt a I invarinsnak rvnyesnek kell lennie mr minden Ef-beli kezdllapotra (azaz Ef I), hiszen a I-nek mr a ciklus elindulsakor (a ciklusmag els vgrehajtsnak kezdllapotra) teljeslnie kell. Msrszt bizonytani kell, hogy a megllskori llapot, amely mg mindig kielgti a I-t, de mr nem elgti ki a ciklusfelttelt (hiszen ezrt llt meg a ciklus), az egyben az Uf-et is kielgti (teht I cf Uf).

53

3. Strukturlt programok

Alkalmazzuk az elmondottakat egy konkrt pldra. Legyen a megoldand feladat az, amikor keressk egy sszetett szm legnagyobb valdi osztjt. Ezt a feladatot korbban mr specifikltuk, de attl eltr mdon az elfelttelben most tegyk fel azt is, hogy a d eredmny vltoz rtke kezdetben az n1 rtkkel egyezik meg. (Ennek hinyban a ciklus eltt egy rtkadst is vgre kellene hajtani, de a pldban most nem akarjuk a szekvencikrl tanultakat is alkalmazni.) A = (n:, d:) Ef=( n=n sszetett(n) d=n1 ) Uf=( n=n sszetett(n) d=LVO(n) ) Tekintsk az A llapottren az albbi programot: d n d:=d1 Invarins lltsnak vlasszuk azt, amely azokat az llapotokat jelli ki, amelyekben a d vltoz rtke valahol 2 s n-1 kz esik, s a d-nl nagyobb egsz szmok biztosan nem oszti az n-nek. I=( n=n sszetett(n) LVO(n) d n1 ) Ez tnyleg invarins a ciklusmag mkdsre, hiszen ha egy llapotra teljesl a I s mg a ciklusfelttel is (azaz a d maga sem osztja az n-t, s emiatt d biztos nagyobb, mint az n legnagyobb valdi osztja, s persze nagyobb 2-nl is), akkor eggyel cskkentve a d rtkt (ezt teszi a ciklus magja) ismt olyan llapotba jutunk, amely kielgti az It. Nyilvnval, hogy I gyengbb, mint Ef, teht Ef I. Az is teljesl, hogy I cf Uf (ha LVO(n) d n1 s d n, akkor d=LVO(n)). sszessgben teht a ciklus egy Ef-beli llapotbl elindulva, ha megll valamikor, akkor Uf-beli llapotban fog megllni. A lellsi kritrium igazolsa rdekben minden llapotban tekintsnk a d rtkre gy, mint a htralev lpsek szmra adott fels korltra: ez, mint ltjuk a ciklusfelttel teljeslse esetn pozitv s minden lpsben eggyel cskken az rtke, teht a program biztosan meg fog llni. Tekintsk most azt a feladatot, amelynek llapottere az a: s brmelyik kiindul egsz szmhoz a nullt rendeli clllapotknt. Ezt

54

3.2. Programszerkezetek

nyilvn megoldan az a:=0 rtkads is, de mi most az albbi ciklust vizsgljuk meg. a 0 a 0 a:=a1 a 0 a:

A lellsi kritrium igazolshoz itt a htralev lpsek szmra adott fels becsls mdszere (amit az elz pldban hasznltunk) nem alkalmazhat. Egy tetszleges kiindul llapotra ugyanis csak akkor tudjuk fellrl megbecslni a htralev lpsek szmt, ha a kiindul rtk nem negatv. Ezt ugyanis a ciklusmag jra s jra eggyel cskkenti, amg az nulla nem lesz. Ha azonban az a vltoz kiindul rtke negatv, akkor ilyen becsls nem adhat. A ciklusmag els vgrehajtsa sorn a vltoz rtke egy elre meghatrozhatatlan nemnegatv egsz szm lesz, amelybl tovbb haladva a ciklus (az elzekben elmondottak szerint) mr biztosan le fog llni a nullban. A ciklus teht vges lpsben biztos a kvnt clllapotban (a nullban) fog befejezdni, de nem minden kiindul llapotra lehet megadni a htralev lpsek szmnak fels korltjt. A haladsi kritriumhoz viszont elegend a semmitmond azonosan igaz invarinst vlasztani. Nyilvnval ugyanis, hogy ha a ciklus lell, akkor azt kvn clban, a nulla rtk a-val teszi. 3.3. Helyes program, megengedett program A programtervezs clja az, hogy egy feladathoz olyan absztrakt (pldul struktogrammal lert) programot adjon, amelyik megoldja a feladatot s ugyanakkor knnyen kdolhat a konkrt programozsi nyelveken. Ez elbbi kritriumot a program helyessgnek, az utbbit a megengedhetsgnek nevezzk. Ha egy program megold egy feladatot, akkor azt a feladat szempontjbl helyes programnak hvjuk. Taln els olvassra meglepnek tnik, de helyes programot nagyon knnyen lehet kszteni, hiszen minden feladat megoldhat egyetlen alkalmas rtkads segtsgvel. Amikor ugyanis egy feladat

55

3. Strukturlt programok

specifikcijban kzvetve vagy kzvetlenl meghatrozzuk minden vltoznak a cl (clllapotbeli) rtkt, tulajdonkppen kijellnk egy rtkadst, amelynek a feladat ltal elrt rtkeket kell tadnia a megfelel vltozknak. Elmletben teht minden feladathoz megkonstrulhat az t megold rtkads, amelyet a feladat trivilis megoldsnak neveznk.8 Ilyen lehetne pldul a korbban ciklussal megoldott legnagyobb valdi osztt elllt feladat esetben a d:=LVO(n) rtkads. A programozsi gyakorlatban azonban igen ritka, hogy egy feladatot egyetlen rtkadssal oldannk meg. Ennek az oka az, hogy a trivilis megolds jobboldaln tbbnyire olyan kifejezs ll, amelyik a rendelkezsnkre ll programozsi krnyezetben nem megengedett, azaz nem ismertek a kifejezsben szerepl mveletek vagy rtkkonstansok, teht a kifejezs kzvetlenl nem kdolhat. Habr a programtervezs sorn szabad, st clszer elvonatkoztatni attl a programozsi krnyezettl, ahol majd a programunknak mkdnie kell, de a vgleges programterv nem tvolodhat el tlsgosan tle, mert akkor nehz lesz kdolni. Szmunkra azok a programtervek a kvnatosak, amelyek egyfell kellen ltalnosak (absztraktak) ahhoz, hogy ellltsuknl ne tkzznk minduntalan a programozsi krnyezet ltal szabott korltokba, msfell brmelyik programozsi nyelven knnyen kdolhatak. Szerencsre a programozsi krnyezetek fejldsk sorn egyre inkbb kzeltettek s kzeltenek egy hivatalosan ugyan nem rgztett, de a gyakorlatban nagyon is jl krvonalazott szabvnyhoz, amely kijelli a legtbb programozsi nyelv ltal biztostott nyelvi elemeket (adattpusokat, programszerkezeteket). Clszer a tervezs sorn ksztett programokat e szabvnyhoz, ezen idelis krnyezethez igaztani. Az ilyen programokat fogjuk a tovbbiakban megengedett programoknak nevezni.
8

A modellnkben bevezetett feladatok ltalnos lekpezsek, amelyekbl jval tbb van, mint az gynevezett parcilis rekurzv fggvnyekbl. Emltettk mr, hogy csak ez utbbiak megoldshoz lehet olyan programokat kszteni, amelyek algoritmizlhatak is. Modellnkben ellenben brmelyik feladathoz krelhat megold program (pldul a trivilis megolds), ezek kztt teht bven vannak olyanok, amely nem algoritmizlhatk.

56

3.3. Helyes program, megengedett program

Programozsi modellnkben megllapods alapjn jelljk ki a megengedett tpusokat. Ide tartoznak a szmok alaptpusai (termszetes-, egsz-, vals szmok) a karakterek s a logikai rtkek tpusa. Megengedett tpusokbl megfelel (azaz megengedett) eljrsokkal (gynevezett konstrukcikkal) olyan sszetett tpusokat kszthetnk (pldul ugyanazon megengedett tpus rtkeket tartalmaz egy vagy tbbdimenzis tmb, karakterekbl sszefztt lnc vagy sztring), amelyeket ugyancsak megengedettnek tekintnk. Ksbb (lsd 7. fejezet) tovbb bvtjk a megengedett tpusok krt. Egy kifejezs megengedett, ha azt megengedett tpusok rtkeibl, mveleteibl s ilyen tpus vltozkbl alaktunk ki a megadott alaki szablyoknak (szintaktiknak) megfelelen.9 Egy rtkads akkor megengedett, ha a jobboldaln szerepl kifejezs megengedett. A bevezetben emltett feladat finomts sorn olyan elemi rszfeladatokra kvnjuk bontani a megoldand feladatot, amelyek megengedett rtkadssal megoldhatk, azaz olyan programmal, amelyet nem kell mr mlyebben rszletezni. Egy megengedett tagprogramokbl felpl szekvencit megengedettnek tekintnk. Az elgazsok s ciklusok felttelei logikai rtk kifejezsek, amelyek szintn lehetnek megengedettek. Ha egy elgazst vagy ciklust megengedett felttelekbl s megengedett programokbl konstrulunk, akkor megengedettnek mondjuk. A megengedett program szekvencia, megengedett feltteleket hasznl elgazsok s megengedett ciklusfelttel ciklusok segtsgvel az res programbl s megengedett kifejezs rtkadsokbl felptett program. sszefoglalva, egy programozsi feladat megoldsn azt a programot rtjk, amelyik helyes s megengedett.

A tpusmveletek valjban lekpezsek, ezrt ltalnos esetben relciknt rhatk fel. Maga a kifejezs is egy lekpezs, amely a tpusmveleteknek, mint lekpezseknek a kompozcijaknt (sszetteleknt) ll el. A fenti meghatrozsban emltett alaki szablyok teht jl definiltak.

57

3. Strukturlt programok

3.4. Feladatok 3.1. Fejezzk ki a SKIP, illetve az ABORT programot egy tetszleges S program s valamelyik programszerkezet segtsgvel! 3.2. a) Van-e olyan program, amit felrhatunk szekvenciaknt, elgazsknt, s ciklusknt is? b) Felrhat-e minden program szekvenciaknt, elgazsknt, s ciklusknt is? 3.3. a) Adjunk meg az A = (p:, q:, r:) llapottren az r:=p+q rtkads ltal befutott vgrehajtsi sorozatokat! Adjunk meg olyan feladatot, amelyet ez az rtkads megold! b) Adjunk meg az A = (n:, m:) llapottren az n,m:=3,n-5 rtkads ltal befutott vgrehajtsi sorozatokat! Adjunk meg olyan feladatot, amelyet ez az rtkads megold! 3.4. Adjunk meg olyan vgrehajtsi sorozatokat, amelyeket a (r:=p+q; p:=r/q) szekvencia befuthat az A= (p:, q:, r:) llapottren! Adjunk meg olyan egyetlen rtkadsbl ll programot, amely ekvivalens ezzel a szekvencival! 3.5. Igaz-e, hogy az albbi hrom program ugyanazokat a feladatokat oldja meg? f1 S1 f1 S1 f2 S2 f3 S3 SKIP 3.6. rtelmezze az albbi feladatot! Adja meg nhny vgrehajtsi sorozatt a megadott elgazsnak! Mutassa meg, hogy a feladatot megoldja a program! SKIP S1 S2 S3 SKIP f2 S2 f3 S3 f1 f2 f3 SKIP

58

3.4. Feladatok

A = (x:, n:) Ef = ( x=x ) Uf = ( n=abs(x) ) x0 a:=x x 0 a:=-x

3.7. Adjunk programot a vals egytthats ax2+bx+c=0 alak egyenletet megoldsra! 3.8. rtelmezze az albbi feladatot! Adja meg nhny vgrehajtsi sorozatt a megadott ciklusnak! Mutassa meg, hogy a feladatot megoldja a program. (Segtsgl megadtuk a ciklus egy invarins lltst s a htralev lpsszmra adhat fels becslst.) A = (x:) Ef = ( igaz ) Uf = ( x = 0 ) x 0 htralev lpsek: abs(n)

x:=x sgn(x) invarins: igaz 3.9. rtelmezze az albbi feladatot! Adja meg nhny vgrehajtsi sorozatt a megadott programnak! Mutassa meg, hogy a feladatot megoldja a program. (Segtsgl megadtuk a ciklus egy invarins lltst s a htralev lpsszmra adhat fels becslst.) A = (n:, f:) Ef = ( n=n ) Uf = ( f=n! )

59

3. Strukturlt programok

f:=1 n 0 f:=f n n:=n-1 3.10. rtelmezze az albbi feladatot! Adja meg nhny vgrehajtsi sorozatt a megadott programnak! Mutassa meg, hogy a feladatot megoldja a program. (Segtsgl megadtuk a ciklus egy invarins lltst s a htralev lpsszmra adhat fels becslst.) A = (x:, n:, z:) Ef = ( n=n x=x ) Uf = ( z=(x)n ) z:=1 n 0 n pros x,n:=x x, n/2 z,n:=z x, n-1 htralev lpsek: n invarins: z (x)n=(x)n htralev lpsek: n invarins: f n!=n!

60

II. RSZ PROGRAMTERVEZS MINTK ALAPJN


A programtervezs sorn az a clunk, hogy egy feladat megoldsra helyes s megengedett programot talljunk. A helyessg azt biztostja, hogy a program megoldsa legyen a feladatnak, a megengedettsg pedig arra ad garancit, hogy a programot klnsebb nehzsg nlkl kdolni tudjuk a vlasztott konkrt programozsi nyelvre. nmagban mr az is nehz, ha adott feladat s adott program viszonyban el kell dntennk, hogy a program helyes -e, azaz megoldja-e a feladatot. Erre klnfle mdszerek vannak kezdve a tesztelstl a szigor matematikai formalizmust ignyl helyessgbizonytsig. Mindkt emltett mdszer azonban felttelezi, hogy mr van egy programunk, pedig egy feladat megoldsa kezdetn nem rendelkeznk semmilyen programmal, csak a feladat ismert. Megfelel program ellltsnl rdemes egy eleve helyes megoldsbl, a feladat trivilis megoldsbl (rtkadsbl) kiindulni. Mivel azonban ez tbbnyire nem-megengedett, fokozatosan, lpsrl lpsre (top-down) kell azt talaktunk gy, hogy a program helyessge minden lps utn megmaradjon, s e lpsenknti finomts vgre megengedett vljon. Az talakts kzbls formi, amelyeket ppgy tekinthetnk a feladat egyfajta vltozatnak, mint programnak, egyre sszetettebb programszerkezetek, amelynek nem-megengedett rtkadsait rszfeladatoknak foghatjuk fel, s amelyeket mlyebben rszletezett programmal kell kivltani. A finomtsi eljrs kzbls forminak eme ketts jelentse, miszerint a benne szerepl nemmegengedett rtkadsok feladatok is s programok is, a feladatorientlt programozsi mdszertan egyik f jellegzetessge. Egy nem-megengedett rtkadst vagy egy bonyolultabb szerkezet programmal kell helyettesteni, vagy az rtkads jobboldali kifejezsnek kiszmtsnl hasznlt tpusmveleteket kell megengedett tenni, amihez adattpusokat kell konstrulunk. Az els eljrst funkci orientlt programtervezsnek hvjuk (ehhez kapcsoldik a knyv II. rsze); a msodikat pedig tpus orientlt programtervezsnek nevezzk (ezzel a III. rszben tallkozunk). Ez a kt eljrs nem zrja ki egymst, vegyesen alkalmazhatak.

61

Ebben a rszben egy olyan lpsenknti finomtst mutatunk be, amely korbbi megoldsok analgijra pl. Ennek lnyege az, hogy egy feladat megoldst egy ahhoz hasonl, korbban mr megoldott feladat megoldsra tmaszkodva lltjuk el. Ennek az analg programozsnak egyik fajtja a visszavezets, amihez a 4. fejezetben nevezetes minta-megoldsokat (gynevezett programozsi tteleket) vezetnk majd be, s ezek gyakorlatban trtn alkalmazst az 5. fejezet pldival illusztrljuk. A 6. fejezetben olyan sszetett feladatokat vizsglunk, amelyek megoldsa visszavezetssel ellltott rszprogramokbl pl fel.

62

4. Programozsi ttelek
Az analg mdon trtn programozs a programkszts ltalnosan ismert s alkalmazott technikja. Amikor egy olyan feladatot kell megoldani, amelyhez hasonl feladatot mr korbban megoldottunk, akkor a megold programot a korbbi feladat megold programja alapjn lltjuk el. Ez az tlet, nem j kelet, nem kizrlag a programozsnl alkalmazott gondolat, hanem olyan ltalnos problmamegold mdszer, amellyel az let minden terletn tallkozhatunk. Amikor egy tevkenysggel kapcsolatban gyakorlati tapasztalatrl, megtanult ismeretekrl beszlnk, akkor olyan korbban megoldott problmkra s azok megoldsaira gondolunk, amelyek az adott tevkenysggel kapcsolatosak. Minl nagyobb egy emberben ez a fajta ismeret, minl biztosabban tudja ezt alkalmazni egy j feladat megoldsnl, annl inkbb tekintjk t a szakmja mesternek. Nem meglep ht, hogy a programozsban az itt trgyalt gynevezett analg programozs szinte kivtel nlkl minden gyakorl programoz eszkztrban jelen van. Az analg programozst lehet alkalmazni sztnsen vagy tudatosan, elnagyoltan vagy preczen, laza ajnlsknt vagy pontos technolgiai szabvnyknt. Az ebben a knyvben alkalmazott visszavezetses mdszernl mind a kitztt feladatnak, mind a korbban megoldott mintafeladatnak ismerjk a precz lerst, a specifikcijt, amely alkalmas arra, hogy a kt feladat kztti analgit pontosan felfedjk: knnyen felismerhetjk a hasonlsgot, ugyanakkor vilgosan felderthetjk az eltrseket. A visszavezets sorn a mintafeladat megold programjt (a mintaprogramot) sablonknt hasznlva lltjuk el a kitztt feladat megold programjt gy, hogy figyelembe vesszk a kitztt- s a mintafeladat specifikcikban felfedett eltrseket. Ebben a fejezetben elszr sszevetjk a visszavezetst ms analg programozsi technikkkal, majd megvizsglunk nhny olyan nevezetes mintafeladatot s annak megold algoritmust, (programozsi ttelt), amelyeket a visszavezetsek sorn hasznlhatunk.

63

4. Programozsi ttelek

4.1. Analg programozs Az analg programozsi technikk alapgondolata kzs, de azok gyakorlatban jelents klnbsgek fedezhetek fel. Ha az analg programozsban rvnyesl eltr szemlletmdokat gondolatban egy egyenes mentn kpzeljk el, akkor ennek egyik vgn az a gondolkodsmd ll, amelyiknl az j feladat megoldsakor a mintafeladat megoldsnak ellltsi folyamatt msoljuk le; a msik vglet viszont csak az eredmnyt, a megold programot veszi t, s azt igaztja hozz az j feladathoz. Az els esetre plda az, amikor a mintafeladatot megold programot algoritmikus gondolkods tjn (milyen programszerkezetet hasznljunk, mi utn mi kvetkezzen, mi legyen a ciklus vagy elgazs felttele, stb.) lltottuk el, s az ehhez hasonl feladatokat a mintafeladatnl alkalmazott gondolatsorral, annak tleteit klcsnzve, lemsolva, analg algoritmikus gondolkodssal oldjuk meg. Ettl lnyeges klnbzik az, amikor nem a mintaprogram ellltsi folyamatt, az ellltsnak lpseit msoljuk le, ismteljk meg, hanem csak magt a mintaprogramot adaptljuk a kitztt feladatra. Az analg programozsnak ezt a technikjt hvjuk visszavezetsnek. Ennek hatkony alkalmazshoz elengedhetetlen a feladatok pontos lersa, hiszen csak gy lehet felfedni azokat a rszleteket, amelyekben egyik feladat a msiktl eltr (az rdg a rszletekben bjik meg), s csak ezek utn tudjuk megmondani azt is, hogy a mr megoldott mintafeladat programjban mely rszleteket mire kell kicserlni ahhoz, hogy a kitztt feladat megoldst megkapjuk. Ebben segt a feladat specifikcija. Ha a feladatokat (mind a kitztt, mind a mintkat) specifikljuk, akkor nemcsak a kzttk lev hasonlsgot tudjuk knnyen felismerni, hanem pontosan felderthetek az eltrsek is. Amg teht az elbbi esetben a programtervezs hangslya az algoritmikus gondolkodson van, addig az utbbiban mr nem gy tekintnk a megold programra, mint egy mkd folyamatra, annak tervezse a feladat elemzsn, teht egyfajta statikus szemlleten alapul. Knyvnkben bemutatott mdszertannak taln a legnagyobb vvmnya ez a precz specifikcira pl visszavezetsi technika, amely az analg programozst lnyegesen gyorsabb s biztonsgosabb teszi. Most algoritmikus gondolkods segtsgvel megoldunk egy olyan feladatot, amely mintafeladatknt fog szolglni a ksbbi

64

4.1. Analg programozs

feladatok megoldshoz, amelyek kzl egyet analg algoritmikus gondolkodssal, a tbbit visszavezetssel oldunk majd meg. 4.1. Plda. Adjuk ssze egy n elem egsz rtk tmb elemeinek ngyzeteit. Specifikljuk elszr a feladatot. A = (v: n, s:) Ef = ( v=v )
n

Uf = ( Ef

s
i 1

v[i]2 )

A megolds sorn a kvnt sszeget fokozatosan lltjuk. Ehhez vgig kell vezetnnk egy i egsz tpus vltozt a tmb indexein, s minden lpsben hozz kell adni a kezdetben nullra belltott s vltozhoz a v[i]2 rtket. A megold program teht a kezdeti rtkadsok utn (ahol az s vltoz rtkt nullra, az i vltozt egyre lltjuk) egy ciklus, amely az i vltozt egyesvel nveli egszen n-ig. A ciklus mkdse alatt az s vltoz mindig a v tmb els i-1 elemnek ngyzetsszegt tartalmazza, Kezdetben, amikor az i rtke 1, ez az rtk mg nulla, befejezskor, amikor az i elri az n+1 rtket, mr a vgleges eredmny. s,i := 0,1 i n
s : s v[i]2

i : Az n nem j vltoz, hanem a tmb hossza

i:=i+1 4.2. Plda. Szmtsuk ki az n pozitv egsz szm faktorilist, azaz az 1*2**n szorzatot! rjuk fel elszr a feladat specifikcijt. Az utfelttelben hasznljuk azt a produktum-kifejezst, amelynek segtsgvel egy
n

m (m 1) ... (n 1) n szorzat a
i m

i zrt alakban felrhat. A

jellsrl tudni kell, hogy ha m>n, akkor a produktum rtke 1. (Az 1

65

4. Programozsi ttelek

ugyanolyan szerepet tlt be az egsz szmok szorzsnl, mint a 0 az sszeadsnl. Egy 0-hoz adott szm vagy egy 1-gyel megszorzott szm maga a szm lesz. Azt mondjuk, hogy a 0 az sszeadsra vett nulla elem, mg az 1 a szorzs nulla eleme. Egy nulla elemmel trtn mveletvgzs nem vltoztat azon az rtken, amelyre a mvelet irnyul.) A = (n:, f:) Ef = ( n=n )
n

Uf = ( Ef

f
i 2

i )

A kitztt feladat s az 4.1. plda feladata hasonlt egymsra, ami a specifikcik sszevetsbl kivlan ltszik. Ott a v[i]2 kifejezsek (i=1..n) rtkeit kellett sszeadni s ezt az s vltozban elhelyezni, itt a i szmokat (i=2..n) sszeszorozni s az f vltozban trolni. Ksztsnk megoldst analg algoritmikus gondolkodssal! Figyeljk meg, hogy csak az alhzott szavak vltoztak meg 4.1. plda megoldsnak gondolatmenethez kpest. A megolds sorn a kvnt szorzatot fokozatosan lltjuk el egy ciklussal. Ehhez vgig kell vezetnnk egy i egsz tpus vltozt a 2..n tartomny indexein, s minden lpsben hozz kell szorozni a kezdetben egyre belltott f vltozhoz az i rtket. A megold program teht a kezdeti rtkadsok utn (ahol az f vltoz rtkt egyre, az i vltozt kettre lltjuk) egy ciklus, amely az i vltozt egyesvel nveli egszen n-ig. A ciklus mkdse alatt az f vltoz mindig az i-1 faktorilist tartalmazza, Kezdetben, amikor az i rtke 2, ez az rtk mg egy, befejezskor, amikor az i elri az n+1 rtket, mr a vgleges eredmny. f,i := 1,2 i n f := f * i i := i+1 4.3. Plda. Adott kt azonos dimenzij vektor, amelyek vals szmokat tartalmaznak. Szmtsuk ki ezek skalris szorzatt! i :

66

4.1. Analg programozs

A feladat bemen adatait kt 1-tl n-ig indexelt tmbben troljuk, eredmnye a skalris szorzat; ezt tkrzi az llapottr. Az utfelttelben a skalris szorzat defincija jelenik meg. A = (a:n, b:n, s:) Ef = ( a=a b=b )
n

Uf = ( Ef

s
i 1

a[i] * b[i] )

Ez a feladat nagyon hasonlt az els sszegzsi feladathoz (4.1. plda). Ksztsnk megoldst visszavezetssel! Vegyk szmba kt feladat kztti eltrseket. A klnbsg az, hogy itt nem egy egsz elem tmb elemeinek nmagval vett szorzatait, a ngyzeteit (v[i]2), hanem a kt vals elem tmb megfelel elem prjainak szorzatait (a[i]*b[i]) kell sszegezni gy, hogy az i az 1..n tartomnyt futja be. Fogjuk meg a mintaknt szolgl 4.1. plda programjt, s cserljk le benne a v[i]2 kifejezst az a[i]*b[i] kifejezsre. Ezzel kszen is vagyunk: s,i := 0,1 i n s := s+a[i]*b[i] i := i+1 4.4. Plda. Igaz-e, hogy egy adott g: fggvny az egsz szmok egy [m..n] nem res intervallumn mindig pros szmot vesz fel rtkl, azaz g(m) is pros, g(m+1) is pros, s gy tovbb, g(n) is pros? Az ( g (m) pros ) ( g (m 1) pros ) ... ( g (n) pros ) sszetett felttelt a feladat specifikcijnak utfelttelben az
n i m

i :

( g (i) pros )

zrt alakban rjuk fel. A jellsrl tudni kell, hogy ha m>n, akkor a kifejezs rtke igaz.

67

4. Programozsi ttelek

A = (m:, n:, l: ) Ef = ( m=m n=n )


n

Uf = ( Ef

i m

( g (i) pros ) )

A kitztt feladat visszavezethet 4.1. pldra. A specifikcik abban klnbznek, hogy itt egsz szmok (v[i]2) sszeadsa helyett logikai lltsok (g(i) pros) sszeselsrl van sz. A logikai lltsok sszeselsnek nulla eleme a logikai igaz rtk ez az, amelyhez brmit selnk is hozz a brmit kapjuk meg. Eltr mg ezen kvl az intervallum is: a korbbi 1..n helyett most az ltalnosabb m..n. Az eredmnyvltoz most s helyett az l. Tekintsk az 4.1. plda programjt, s cserljk le benne a v[i]2 kifejezst az g(i) pros logikai kifejezsre, a +-t az -re, a kezdeti rtkadsban az l vltoznak a 0 helyett a logikai igaz rtket, az i vltoz kezdrtknek pedig az m-et adjuk. Tblzatos formban: [1..n] +, 0 s:=s+v[i]2 ~ ~ ~ [m..n] , igaz l:= l (az g(i) pros) i :

l,i := igaz, m i n l:=l (g(i) pros) i := i+1

4.5. Plda. Gyjtsk ki egy n elem (az n pozitv) egsz szmokat tartalmaz tmb pros rtkeit egy halmazba! A = (x:n, h:2) Ef = ( x=x )
n

Uf = ( h

x[i ] pros

{x[i ]} ) U i 1

A halmazok unija is rokon mvelet a szmok feletti sszeadssal. Egysgeleme az res halmaz. A mveletben szerepl

68

4.1. Analg programozs

kifejezs most egy gynevezett feltteles kifejezs: ha az x[i] pros felttel teljesl, akkor az {x[i]} egy elem halmazt, klnben az res halmazt unizzuk a h-hoz. Oldjuk meg visszavezetssel a feladatot! Soroljuk fel az eltrseket a 4.1. plda mintafeladata s a most kitztt feladat kztt: +, 0 ~ , s ~ h 2 s:=s+ v[i] ~ h:= h (ha x[i] pros akkor x[i] klnben ) Ezeket az eltrseket tvezetve a mintaprogramra a kitztt feladat megoldst kapjuk. Ez azonban nem megengedett, hiszen a feltteles rtkadst nem tekintjk annak. A feltteles rtkads azonban nyilvnvalan helyettesthet egy elgazssal. Ez a helyettests termszetesen mr nem a visszavezets rsze, hanem egy azutn alkalmazott talakts. h, i := i n x[i] pros h := h {x[i]} i := i+1 4.2. Programozsi ttel fogalma Az elz alfejezetben ltott feladatoknl gy talltuk, hogy az eltrsek ellenre ezek a feladatok annyira hasonlak, hogy ugyanazon sma alapjn lehet ket megoldani. De melyek is azok a tulajdonsgok, amelyekkel felttlenl rendelkeznie kell egy feladatnak, hogy az eddig ltott feladatok kz sorolhassuk? Hogyan lehetne ltalnosan megfogalmazni egy ilyen feladatokat? A fenti feladatok egyik kzs tulajdonsga az volt, hogy mindegyikben fontos szerepet tlttt be az egsz szmok egy zrt intervalluma. Vagy egy 1-tl n-ig indexelt tmbrl volt sz, vagy egy adott g: fggvnynek az egsz szmok egy [m..n] intervallumn felvett rtkeirl, vagy egyszeren csak az egsz szmokat kellett 1-tl SKIP ,1 i :

69

4. Programozsi ttelek

n-ig sszeszorozni. Ezek az intervallumok hatroztk meg, hogy a feladatok megoldsban oroszlnrszt vllal ciklus gynevezett ciklusvltozja mettl meddig fusson, azaz hnyszor hajtdjon vgre a ciklus magja. A msik fontos tulajdonsg, hogy az intervallum elemeihez tartozik egy-egy rtk, amit a szmtsban kell felhasznlni. Az els feladatban az intervallum i elemhez rendelt rtk a v[i]2 szm, a msodikban maga az i, a harmadikban az a[i]*b[i], a negyedikben a g(i) pros logikai kifejezs, az tdikben az {x[i]} egy elem halmaz. Mindegyik esetben megadhat teht egy lekpezs, egy fggvny, amely az egsz szmok egy intervallumn rtelmezett, s az intervallum elemeihez rendel valamilyen rtket: szmot, logikai rtket, esetleg halmazt. A harmadik lnyeges tulajdonsg az a szmtsi mvelet, amely segtsgvel az intervallum elemeihez rendelt rtkeket sszesteni lehetett: sszeadni, sszeszorozni, sszeselni, unizni. Ez a mvelet ppen azon rtkekre rtelmezett, amelyeket az intervallum elemeihez rendelnk. Mindig ltezett egy olyan rtk, amelyhez brmelyik msik rtket adjuk-szorozzuk-seljk-unizzuk hozz, az eredmny ez a msik rtk lett: 0+s=s, 1*s=s, igaz l=l, h=h. gy mondjuk, hogy mindegyik mveletnek van (baloldali) nulla eleme. A vizsglt mveletek egyms utni alkalmazsnak eredmnye nem fggtt a vgrehajtsi sorrendtl, az tetszlegesen csoportosthat, zrjelezhet (pldul az a+b+c rtelmezhet a+(b+c)-knt s (a+b)+c-knt is, s mi ez utbbit hasznltuk), azaz a vizsglt mveletek asszociatvak voltak. Foglaljuk ssze ezeket a kzs tulajdonsgokat, s fogalmazzuk meg azt az ltalnos feladatot, amely az elz alfejezetben kzlt sszes feladatot magba foglalja. Legyen adott az egsz szmok egy [m..n] intervallumn rtelmezett f:[m..n] H fggvny (errl ltalnos esetben nem kell tudni tbbet), amelynek H rtkkszletn definilunk egy mveletet. Az egyszersg kedvrt hvjuk ezt sszeadsnak, de ez nem felttlenl a szmok megszokott sszeadsi mvelete, minthogy a H sem felttlenl egy szmhalmaz. A mvelet lehet a szmok feletti szorzs, logikai lltsok feletti sels, halmazok feletti unizs, stb. Ami a lnyeg: a mvelet legyen asszociatv s rendelkezzen (baloldali) nulla elemmel. A feladat az, hogy hatrozzuk meg az f fggvny [m..n]-en felvett rtkeinek az sszegt (szorzatt, seltjt, unijt stb.) azaz a

70

4.2. Programozsi ttel fogalma

f (k )
k m

f (m)

f (m 1) ...

f (n) kifejezs rtkt! (m>n esetn

ennek az rtke definci szerint a nulla elem). Az elz alfejezet pldi mind rillenek erre a feladatra. Ezt az ltalnosan megfogalmazott feladatot specifiklhatjuk is. Az llapottrbe a fggvny rtelmezsi tartomnynak vgpontjait s az eredmnyt vesszk fel, elfelttele rgzti a bemen adatokat, utfelttele pedig az sszegzsi feladatot rja le. A = (m:, n:, s:H) Ef = ( m=m n=n )
n

Uf = ( Ef

s
i m

f (i) )

A kvnt sszeget fokozatosan lltjuk el. Ehhez vgig kell vezetnnk egy i egsz tpus vltozt a tmb indexein, s minden lpsben hozz kell adni a kezdetben nullra belltott s vltozhoz az f(i) rtket. A megold program teht a kezdeti rtkadsok utn (ahol az s vltoz rtkt nullra, az i vltozt m-re lltjuk) egy ciklus, amely az i vltozt egyesvel nveli egszen n-ig. A ciklus mkdse alatt az s vltoz mindig az f fggvny [m..i1] intervallumon felvett rtkeinek sszegt tartalmazza, Kezdetben, amikor az i rtke 1, ez az rtk mg nulla, befejezskor, amikor elri az n+1 rtket, mr a vgleges eredmny. s, i := 0, m i n s := s + f(i) i := i + 1 Az most bemutatott feladat-program pr egy nevezetes minta: az gynevezett sszegzs. Ez, mint azt az elz alfejezetben lthattuk, szmos feladat megoldshoz szolglhat alapul. A visszavezets sorn mintaknt hasznlt feladat-program prt (ahol a program megoldja a feladatot) programozsi ttelnek hvjuk. Az elnevezs onnan szrmazik, hogy egy mintafeladat-program prt i :

71

4. Programozsi ttelek

egy matematikai ttelhez hasonlan alkalmazunk: ha egy kitztt feladat hasonlt a minta feladatra, akkor a minta programja lnyegben megoldja a kitztt feladatot is. A "hasonlt" s a "lnyegben" szavak rtelmt az elz pldk alapjn mr rezzk, de majd az 5.1. alfejezetben rszletesen is kitrnk rtelmezskre. A visszavezets sikere azon mlik, hogy rendelkeznk-e kell szm, vltozatos s elgg ltalnos mintafeladattal ahhoz, hogy egy j feladat ezek valamelyikre hasonltson. Ezrt a mintafeladatokat s megoldsaikat gondosan kell megvlasztani. Termszetesen minden programoz maga dnti el azt, hogy munkja sorn milyen programozsi ttelekre tmaszkodik ezek mennyisge s minsge a programozi tuds, a szakrtelem fokmrje , ugyanakkor meghatrozhat a programozsi tteleknek az a kzs rsze, amit a tbbsg ismer s hasznl, amelyek feladatai a programozsi feladatok megoldsnl gyakran elfordulnak. Alig tbb mint fl tucat ilyen programozsi ttellel a gyakorlatban elfordul problmk tbbsge, nyolcvan-kilencven szzalka lefedhet. A klnfle programozsi mdszertant tant iskolk lnyegben ugyanazokat a programozsi tteleket vezetik be, legfeljebb azok megfogalmazsban, csoportostsban s felhasznlsi mdjukban van az iskolk kztt eltrs. Ott, ahol a programozsi tteleket nem visszavezetsre hasznljk, mert az analg programozs msik irnyzatt, az algoritmikus gondolkods folyamatnak lemsolst kvetik, egy ttel megfogalmazsa kevsb precz: annak tbb vltozata is lehetsges. A visszavezetsnl viszont a tteleket sokkal pontosabban, s lehetleg minl ltalnosabban kell megadni. Egy ttel ugyanis valjban nem egy konkrt feladatot, hanem egy feladatosztlyt r le, s minl ltalnosabb, annl tbb feladat illeszkedik ehhez a feladatosztlyhoz. Vigyzni kell azonban arra, hogy ha a mintafeladat tl elvont, akkor nehz lehet annak alkalmazsa. 4.3. Nevezetes mintk Most nyolc, a szakirodalomban jl ismert programozsi ttelt mutatunk be. Mindegyikknl az egsz szmok egy intervallumn rtelmezett fggvny (vagy fggvnyek) rtkeinek feldolgozsa a cl. Ezrt ezeket a tteleket intervallumos programozsi tteleknek is szoktuk nevezni.

72

4.3. Nevezetes mintk

A nyolc ttel kzl egyedl a lineris kivlasztshoz nem kapcsolhat nyilvnval mdon az egsz szmok egy intervalluma. Ez egy olyan keress, amelyik az egsz szmok szmegyenesen folyik, de elg megadni a keress kezdpontjt, a keress addig tart, amg a keressi felttel (egy egsz szmokon rtelmezett logikai fggvny) igaz nem lesz. Errl azonban tudjuk, hogy elbb-utbb bekvetkezik. Itt teht a keress sorn egy olyan intervallumot jrunk be, amelynek a vgpontja csak implicit mdon van megadva. Az intervallumokra az egyes programozsi ttelek klnfle elfeltteleket fogalmaznak meg. Nem lehet res az intervallum a rekurzv fggvny helyettestsi rtknek meghatrozsakor, illetve a kznsges maximum kivlasztsnl. A maximum kivlasztsnak van egy ltalnosabb vltozata is (feltteles maximumkeress), amely csak egy logikai felttelnek megfelel egsz szmokon felvett fggvnyrtkek kztt keresi a legnagyobbat, s itt az is megengedett, ha az intervallum egyetlen egy egsz szma sem elgti ki ezt a felttelt, vagy az intervallum res. Egy logikai vltoz jelzi majd, hogy egyltaln volt-e a felttelt kielgt vizsglt fggvnyrtk. Az albbi programozsi ttelek f(i), (i), h(i, y, y1, ... , yk1) kifejezsei az f, , h fggvnyek adott argumentum helyettestsi rtkeit jellik. Feltesszk, hogy ezek a helyettestsi rtkek kiszmthatak.

73

4. Programozsi ttelek

1. sszegzs Az sszegzs programozsi ttelt az elz alfejezetekben alaposan elemeztk. Most csak a teljessg ignye miatt ismteljk meg. Feladat: Adott az egsz szmok egy [m..n] intervalluma s egy f:[m..n] H fggvny. A H halmaz elemein rtelmezett egy asszociatv, baloldali nulla elemmel rendelkez mvelet (nevezzk sszeadsnak s jellje ezt a +). Hatrozzuk meg az f fggvny [m..n]-en felvett rtkeinek az sszegt, azaz a
n k m

f(k) kifejezs rtkt! (m>n esetn

ennek az rtke definci szerint a nulla elem). Specifikci: A = (m:, n:, s:H) Ef = ( m=m n=n )
n

Uf = ( Ef Algoritmus:

s
i m

f(i) )

s, i := 0, m i n s := s + f(i) i := i + 1

i:

74

4.3. Nevezetes mintk

2. Szmlls Gondoljunk arra a feladatra, amikor egy 20 fs osztlyban azon dikok szmt kell megadnunk, akik tst kaptak trtnelembl. A dikokat 1-tl 20-ig megsorszmozzuk, s a trtnelem jegyeiket egy 1-tl 20-ig indexelt t tmbben troljuk: az i-edik dik osztlyzata a t[i]. Definilunk egy :[1..20] logikai fggvnyt, amely azokhoz a dikokhoz rendel igaz rtket, akik tst kaptak, ms szval (i) = (t[i]=5). Azt kell meghatroznunk, hogy a ltal felvett rtkek kztt hny igaz rtk szerepel. Ilyenkor valjban 0 illetve 1 rtkeket sszegznk attl fggen, hogy a logikai kifejezs hamis vagy igaz. A szmlls teht az sszegzs specilis eseteknt foghat fel, amelyben az s:=s+1 rtkadst csak a (i) felttel teljeslse esetn kell vgrehajtani. Feladat: Adott az egsz szmok egy [m..n] intervalluma s egy :[m..n] felttel. Hatrozzuk meg, hogy az [m..n] intervallumon a felttel hnyszor veszi fel az igaz rtket! (Ha m>n, akkor egyszer sem.) Specifikci: A = (m:, n:, c:) Ef = ( m=m n=n )
n

Uf = ( Ef

c
i m (i)

1)

Algoritmus: c, i := 0, m i n (i) c := c+1 i := i + 1 SKIP i:

75

4. Programozsi ttelek

3. Maximum kivlaszts Ha arra vagyunk kvncsiak, hogy egy 20 fs osztlyban kinek van a legjobb jegye trtnelembl, akkor ehhez a dikokat 1-tl 20-ig megsorszmozzuk, s a trtnelem jegyeiket egy 1-tl 20-ig indexelt t tmbben troljuk: az i-edik dik osztlyzata a t[i]. Ez a tmb tekinthet egy f:[1..20] fggvnynek (f(i)=t[i]), amely rtkei kztt keressk a legnagyobbat. Feladat: Adott az egsz szmok egy [m..n] intervalluma s egy f:[m..n] H fggvny. A H halmaz elemein rtelmezett egy teljes rendezsi relci. Hatrozzuk meg, hogy az f fggvny hol veszi fel az [m..n] nem res intervallumon a legnagyobb rtket, s mondjuk meg, mekkora ez a maximlis rtk! Specifikci: A = (m:, n:, ind:, max:H) Ef = ( m=m n=n n m ) Uf = ( Ef ind [m..n] max=f(ind) i [m..n]: max f(i) ) = mskppen jellve, illetve rvidtett jellst hasznlva: = ( Ef = ( Ef ind [m..n]
n

max = f(ind) = max f(i) )


i m

max,ind= max f(i) )


i m

Algoritmus: max, ind, i := f(m), m, m+1 i n max<f(i) max, ind := f(i), i i := i + 1 Az ind vltoz rtkadsai trlhetk az algoritmusbl, ha nincs szksg az ind-re. SKIP i:

76

4.3. Nevezetes mintk

4. Feltteles maximumkeress A maximum kivlasztst sokszor gy kell elvgezni, hogy a vizsglt elemek kzl csak azokat vesszk figyelembe, amelyek eleget tesznek egy adott felttelnek. Pldul, egyms utni napi tlaghmrskletek kztt azt a legmelegebb hmrskletet keressk, amelyik fagypont alatti. Feladat: Adott az egsz szmok egy [m..n] intervalluma, egy f:[m..n] H fggvny s egy :[m..n] felttel. A H halmaz elemein rtelmezett egy teljes rendezsi relci. Hatrozzuk meg, hogy az [m..n] intervallum felttelt kielgt elemei kzl az f fggvny hol veszi fel a legnagyobb rtket, s mondjuk meg, mekkora ez az rtk! (Lehet, hogy egyltaln nincs felttelt kielgt elem az [m..n] intervallumban vagy m>n.) Specifikci: A = (m:, n:, l: , ind:, max:H) Ef = ( m=m n=n ) Uf = ( Ef l = i [m..n]: (i) l ind [m..n] max=f(ind) (ind) i [m..n]: (i) max f(i) ) Itt is bevezetnk rvid jellst.
n

Uf = ( Ef Algoritmus:

l,max,ind) = max f(i) )


i m (i)

l, i := hamis, m i n (i) SKIP l (i) l (i)

i:

l, max, ind := igaz, f(i), i max, ind := f(i), i SKIP i := i + 1

max< f(i)

77

4. Programozsi ttelek

5. Kivlaszts (szekvencilis vagy lineris kivlaszts) Ennek a mintnak kapcsn azokra a feladatokra gondoljunk, ahol egyms utn sorba lltott elemek kztt keressk az els adott tulajdonsgt gy, hogy tudjuk, hogy ilyen elem biztosan van. Pldul egy osztlyban keressk az els ts trtnelem jeggyel rendelkez dikot, ha tudjuk, hogy ilyen biztosan van. A dikok trtnelem jegyeit ilyenkor egy 1-tl 20-ig indexelt t tmbben troljuk (az i-edik dik osztlyzata a t[i]), ha a dikokat 1-tl 20-ig sorszmoztuk meg. A keress szempontjbl kzmbs, hogy egy 20 fs osztllyal van dolgunk. Definilunk egy :[1..20] logikai fggvnyt, amely azokhoz a dikokhoz rendel igaz rtket, akik tst kaptak, ms szval (i) = (t[i]=5). Feladat: Adott egy m egsz szm s egy m-tl jobbra rtelmezett : felttel. Hatrozzuk meg, hogy az m-tl jobbra es els olyan szmot, amely kielgti a felttelt, ha tudjuk, hogy ilyen szm biztosan van! Specifikci: A = (m:, ind:) Ef = ( m=m i m: (i) ) Uf = ( Ef ind m (ind) i [m..ind1]: (i) ) vagy rvidtett jellst alkalmazva: Uf = ( Ef Algoritmus: ind := m (ind) ind := ind + 1 Az elz ttelekkel szemben itt nincs szksg a bejrt szok intervallumnak fels hatrra, mintahogy egy kln i vltozra sem a szmok bejrshoz.

ind

select (i) )
i m

78

4.3. Nevezetes mintk

6. Keress (szekvencilis vagy lineris keress) Ez a minta hasonlt az elzre, hiszen itt is egyms utn sorba lltott elemek kztt keressk az els adott tulajdonsgt, de lehet, hogy ilyet egyltaln nem tallunk. Feladat: Adott az egsz szmok egy [m..n] intervalluma s egy :[m..n] felttel. Hatrozzuk meg az [m..n] intervallumban balrl az els olyan szmot, amely kielgti a felttelt! Specifikci: A = (m:, n:, l: , ind:) Ef = ( m=m n=n ) Uf = ( Ef l=( i [m..n]: (i)) l (ind [m..n] (ind) i [m..ind1]: (i)) ) vagy rvidtett jellst alkalmazva Uf = ( Ef Algoritmus : l, i := hamis, m l i n i:
10

l , ind

search (i) )
i m

l, ind := (i), i i := i+1

10

A lineris keress algoritmusnak ms vltozatai is ismertek: l, ind := hamis, m l ind n (ind) l:=igaz ind := ind+1 ind := m ind n (ind)

l, ind := hamis, m1 l ind<n

ind := ind+1 l := (ind)

ind := ind+1 l := ind n

79

4. Programozsi ttelek

7. Logaritmikus keress Specilis felttelek meglte esetn a lineris keressnl jval gyorsabb keres algoritmust hasznlhatunk. Amg a lineris keress egy h elem intervallumot legrosszabb esetben h lpsben tud tvizsglni (a lpsek szma az elemszm lineris fggvnye), addig a most bemutatsra kerl keressnek legrosszabb esetben ehhez csak log2h lpsre van szksge. A logaritmikus keresssel nvekeden rendezett rtkek kztt kereshetnk egy adott rtket. Ennek sorn a keressi intervallumot felezzk el, s a felez pontnl lev rtket sszevetjk a keresettel. Ha megegyeznek, akkor megtalltuk a keresett rtket, ha a vizsglt rtk nagyobb a keresett rtknl, akkor a keresett rtk (ha egyltaln ott van az rtkek kztt) a keressi intervallum els felben tallhat, ha kisebb, akkor a msodik felben, azaz a keress intervalluma elfelezhet. Feladat: Adott az egsz szmok egy [m..n] intervalluma s egy f:Z H fggvny, amelyik az [m..n] intervallumon monoton nvekv. (A H halmaz elemei kztt rtelmezett egy rendezsi relci.) Keressnk meg a fggvny [m..n] intervallumon felvett rtkei kztt egy adott rtket! Specifikci: A = (m:, n:, h:H, l: , ind:) Ef = ( m=m n=n h=h j [m..n-1]: f(j) f(j+1) ) Uf = ( Ef l=( j [m..n]:f(j)=h) l (ind [m..n] f(ind)=h)) Algoritmus: ah,fh,l := m,n,hamis l ah fh ah, fh:

ind := (ah+fh) div 2 f(ind)>h fh := ind-1 f(ind)<h ah := ind+1 f(ind)=h l := igaz

80

4.3. Nevezetes mintk

8. Rekurzv fggvny kiszmtsa Tekintsk a Fibonacci szmokat: 1, 1, 2, 3, 5, 8, 12,. Ezeket az albbi Fib: fggvnnyel llthatjuk el. Az els kt Fibonacci szm definci szerint az 1, azaz Fib(1)=1 s Fib(2)=1. A tovbbi Fibonacci szmokat a megelz kt Fibonacci szm sszegeknt kapjuk meg: Fib(i)=Fib(i1)+Fib(i2). Ha az n-edik Fibonacci szmhoz szeretnnk eljutni (n>2), akkor elszr a harmadik, utna a negyedik s gy tovbb Fibonacci szmot kell ellltani, azaz vgig kell mennnk a 3..n intervallumon. Egy msik plda az n faktorilisnak meghatrozsa. Ezt az a Fact: fggvny adja meg, amely a 0-hoz definci szerint az 1-et rendel, az 1-nl nagyobb szmok faktorilisa pedig a megelz faktorilis segtsgvel llthat el: Fact(i)=i*Fact(i1). Az n szm faktorilisnak meghatrozshoz (n>0) sorban egyms utn meg kell hatroznunk a 1..n intervallum elemeinek faktorilist. Feladat: Legyen az f: H egy k-ad rend m bzis rekurzv fggvny (m egsz szm, k pozitv egsz szm), azaz f(i) = h(i, f(i1), ... ,f(ik) ) ahol im s a h egy Hk H fggvny. Ezen kvl f(m1) = em1, ... , f(mk) = emk, ahol em-1, ... , emk H-beli rtkek. Szmtsuk ki az f fggvny adott n (nm) helyen felvett rtkt! Specifikci: A = (n:, y:H) Ef = ( n=n n m ) Uf = ( Ef y=f(n) ) Algoritmus: segdvltozk: y1, ... , yk1 , i: y, y1, ... , yk1 , i := em1, em2, ... , emk, m i n y, y1, y2,... , yk1 := h(i, y, y1, ... , yk1), y, y1, ... , yk2 i := i + 1

81

4. Programozsi ttelek

A kivlaszts, lineris keress s a logaritmikus keress kivtelvel a fenti algoritmus mintk ciklusszervezse megegyezik: egy indexvltozt vezetnek vgig az m..n intervallumon. Az ilyen esetekben alkalmazhatunk egy rvidtett jellst az algoritmus lersra. Ezt a vltozatot szoktk szmlls ciklusnak nevezni. Az elnevezs kicsit flrevezet, hiszen, mint ltjuk, ez egy kezdeti rtkadsnak s egy ciklusnak a szekvencija. A szmlls ciklus alkalmazhatsgnak jelentsgt egyrszt az adja, hogy ilyenkor pontosan meg lehet mondani, hny iterci utn fog lellni a ciklus, msrszt a klnfle programozsi nyelvek kln nyelvi elemet (pldul for) szoktak biztostani a kdolsukhoz. i := m i n feldolgozs i := i + 1 A tovbbiakban ott, ahol lehetsg van r, mi is ezt a rvidebb vltozatot fogjuk hasznlni. A programozsi ttelek helyessgt a 3. fejezetben bemutatott eszkzkkel be lehet bizonytani. Ezen bizonytsoknak sarkalatos rsze a programok ciklusainak vizsglata. A ciklusok helyes mkdshez azok haladsi s lellsi kritriumt kell igazolni. A lellsi kritriumot knny beltni az els ngy valamint a kilencedik ttelnl, hiszen ezeknl az egsz szmok egy intervallumt futja be egy szmlls ciklus. A kivlaszts esetben az elfelttel (biztos tallunk vges lpsben keresett tulajdonsg egsz szmot) biztostja a terminlst, a lineris keressnl legrosszabb esetben az intervallum vgig tart a keress. A logaritmikus keress legfeljebb addig tart, amg az ltala kzben tartott [ah..fh] intervallum nem res, ugyanakkor ez az intervallum minden lpsben kisebb s kisebb lesz (feltve, hogy nem tallunk keresett elemet, de ebben az esetben rgtn lell a ciklus). A haladsi kritrium rszletes bizonytsval nem foglalkozunk, de jellemezzk ezen bizonyts nlklzhetetlen eszkzt, a ttelek rvidebben i = m .. n feldolgozs

82

4.3. Nevezetes mintk

ciklusainak invarins tulajdonsgt. Az els ngy programozsi ttel esetben a ciklus invarinsa az utfelttel lltsnak egy olyan gyengtse, amelyik nem a teljes [m..n] intervallumra, hanem csak az [m..i-1] intervallumra vonatkozik: az egyes tteleknl rendre azt fejezi ki, hogy a ciklus mkdse sorn ezen rszintervallum feletti sszeggel, darabszmmal vagy maximummal rendelkeznk csak. Lthat, ahogy n az i rtke, gy kerlnk egyre kzelebb az utfelttel lltshoz. A rekurzv fggvny helyettestsi rtknek kiszmolsakor is hasonl a helyzet: az invarins a fggvny i-1-dik helyen felvett rtkt tekinti ismertnek, ez az eredmny vltoz aktulis rtke. A kivlasztsnl az invarins azt mutatja, hogy eddig mg nem talltunk keresett tulajdonsg elemet. A lineris s logaritmikus keress esetben az invarins egyrszt azt tartalmazza, hogy a korbban vizsglt helyeken nem teljesl a keresett felttel, msrszt azt, hogy a keress eredmnyt jelz logikai vltoz pontosan akkor igaz, ha a legutoljra vizsglt helyen a felttel teljesl.

83

4. Programozsi ttelek

4.4. Feladatok Specifikljuk az albbi feladatokat, vessk ssze azokat a programozsi ttelek specifikciival s prbljuk meg ennek figyelembevtelvel felrni a megold programokat! 4.1. Szmoljuk ki kt termszetes szm szorzatt, ha a szorzs mvelete nincs megengedve! 4.2. Keressk meg egy termszetes szm legkisebb pros valdi osztjt! 4.3. Vlogassuk ki egy egsz szmokat tartalmaz tmbbl a pros szmokat! 4.4. Egymst kvet napokon megmrtk a dli hmrskletet. Hnyadikra mrtnk elszr 0 Celsius fokot azeltt, hogy elszr fagypont alatti hmrskletet regisztrltunk volna? 4.5. Egy tmbben a tornarn megjelent dikok magassgait troljuk. Keressk meg a legmagasabb dik magassgt! 4.6. Az f:[m..n] fggvnynek hny rtke esik az [a..b] vagy a [c..d] intervallumba? 4.7. Egy tmbben szneket trolunk a sznskla szerinti nvekv sorrendben. Keressk meg a tmbben a vilgoskk sznt! 4.8. A Fld felsznnek egy vonala mentn egyenl tvolsgonknt megmrtk a terep tengerszint feletti magassgt (mterben), s a mrt rtkeket egy tmbben troljuk. Melyik a legmagasabban fekv horpads a felsznen? 4.9. Egymst kvet napokon megmrtk a dli hmrskletet. Hnyszor mrtnk 0 Celsiust gy, hogy kzvetlenl utna fagypont alatti hmrskletet regisztrltunk? 4.10. Egy n elem tmbben trolt egsz szmoknak az sszegt egy rekurzv fggvnv n-edik helyen felvett rtkvel is megadhatjuk. Definiljuk ezt a rekurzv fggvnyt s oldjuk meg a feladatot a rekurzv fggvny helyettestsi rtkt kiszmol programozsi ttel segtsgvel!

84

5. Visszavezets
Ebben az alfejezetben pldkat ltunk a visszavezetsre, nevezetesen arra, amikor a programozsi ttelek mintjra oldjuk meg a feladatainkat, s kzben azt prbljuk megvilgtani, hogy a visszavezetssel ellltott programok mirt lesznek biztosan megoldsai a kitztt feladatoknak. Az albb bemutatott esetek egymssal kombinlva is megjelenhetnek a visszavezetsek sorn. 5.1. Termszetes visszavezets Termszetes visszavezetsrl akkor beszlnk, amikor az alkalmazott programozsi ttel feladata (a mintafeladat) tnevezsektl eltekintve teljesen megegyezik a megoldand (a kitztt) feladattal. Hromfle tnevezssel tallkozhatunk. Egyrszt a kitztt feladat vltozit nem kell ugyangy hvni, mint a mintafeladatban, de attl a feladat ugyanaz marad. Msrszt a mintafeladat ltalnos (jelents nlkli) kifejezseinek (ilyen az f(i), (i) ) helyre az adott feladat konkrt jelentssel br s az i rtktl fgg kifejezseket rhat be. Harmadrszt gyakran elfordul, hogy a mintafeladat utfelttelnek egy-egy lland rtk kifejezst (pldul az intervallum vgpontjt) egy msik lland rtk kifejezsre cserljk. Az albbi feladat megoldsnl mindhrom esettel tallkozhatunk. Mivel ezek az tnevezsek a programozsi ttel helyessgt nem rontjk el, az tnevezsek eredmnyeknt kapott program nyilvnvalan megoldja a mintafeladattl csak tnevezseiben eltr kitztt feladatot. 5.1. Plda. Hnyszor vlt eljelet (pozitvrl negatvra vagy negatvrl pozitvra) az [a..b] egsz intervallumon az f: fggvny? A = (a:, b:, db:) Ef = ( a=a b=b )
b

Uf = ( Ef

db
j a 1 f(j)* f(j 1) 0

1)

Ez a specifikci olyan, mint a szmlls programozsi ttelnek specifikcija. A klnbsg csak annyi, hogy az ott szerepl felttelt itt nem az [m..n], hanem az [a+1..b] intervallumon rtelmezzk; az

85

5. Visszavezets

intervallumon nem az i, hanem a j vltozval futunk vgig; az s vltozt a db vltoz helyettesti; s a (i) helyn az f(j)*f(j-1)<0 kifejezs ll. Alkalmazzuk ezt a megfeleltetst a szmlls programjra s megkapjuk a kitztt feladat megoldst. m..n s i (i) ~ ~ ~ ~ a+1..b db j f(j)*f(j-1)<0 db := 0 j = a+1 .. b f(j) * f(j-1) < 0 db := db+1 SKIP j:

5.2. ltalnos visszavezets ltalnos visszavezetsrl akkor beszlnk, amikor a kitztt feladat megengedbb a mintafeladatnl. Ez ktflekppen is elllhat. Egyfell akkor, ha a kitztt feladat kevesebb kezdllapotra van rtelmezve, mint a mintafeladat (azaz a kitztt feladat elfelttele szigorbb a mintafeladatnl). Ez nyilvn nem okoz problmt, hiszen senkit sem rdekel, hogy a programozsi ttel programja a szmunkra rdekes kezdllapotokon kvl ms kezdllapotokra mit csinl. Erre plda, ha a kitztt feladat a termszetes szmok egy intervallumn van megfogalmazva, de azt az egsz szmok intervallumra felrt programozsi ttelre vezetjk vissza. Msfell a kitztt feladat egy kezdllapothoz olyan clllapotot is rendelhet, amelyet a mintafeladat nem (azaz a feladat utfelttele gyengbb a mintafeladatnl). Mivel egy megold programnak elg tbb lehetsges clllapotbl az egyiket elrni, gy a programozsi ttel szigorbb mintafeladatot megold programja megoldja a megengedbb kitztt feladatot is. Ez utbbira ad pldt az albbi feladat, ahol egy adott tulajdonsg elemet kell megtallnunk (ilyen tbb is lehet), de a lineris keresssel ezek kzl a legels adott tulajdonsgt fogjuk megkeresni. Termszetesen az olyan

86

5.2. ltalnos visszavezets

eltrsek, mint amelyeket a termszetes visszavezetsnl emltettnk itt is elfordulhatnak. 5.2. Plda. Keressk egy f:[m..n] fggvnynek azt az arumentumt, amelyre teljesl, hogy f(k)=(f(k-1)+ f(k+1))/2. A = (m:, n:, l: , ki: ) Ef = ( m=m n=n ) Uf = ( Ef l=( i [m+1..n-1]: f(i)=(f(i1)+f(i+1))/2 ) l ( ki [m+1..n-1] f(ki)=(f(ki-1)+f(ki+1))/2 ) ) Szigortsunk a feladaton. Ha a szigorbb feladathoz tallunk megoldst, akkor ez az eredeti feladatot is megoldja. Uf = ( Ef l=( i [m+1..n-1]: f(i)=(f(i1)+f(i+1))/2 ) l ( ki [m+1..n-1] f(ki)=(f(ki-1)+f(ki+1))/2 i [m+1..ki-1]: f(i) (f(i1)+f(i+1))/2 ) ) = ( Ef

l , ki

search( f(i)
i m 1

n 1

( f(i 1)

f(i 1)) /2 ) )

Ez a feladat visszavezethet a lineris keress programozsi ttelre. m..n (i) ind ~ ~ ~ m+1..n-1 f(i)=(f(i1)+ f(i+1))/2 ki

l, i := hamis, m+1 l i n-1 i: l, ki := f(i)=(f(i1)+ f(i+1))/2, i i := i+1

5.3. Alteres visszavezets Alteres visszavezetsrl akkor beszlnk, amikor a kitztt feladat llapottere a mintafeladat llapotternek nem minden komponenst tartalmazza (altere a kitztt feladat llapotternek), azaz

87

5. Visszavezets

a kitztt feladat llapotternek kevesebb komponenssel br. Ennek kt figyelemre mlt alesete van. (Ezen tlmenen a termszetes visszavezetsnl megengedett eltrsek is elfordulhatnak.) Az egyik eset az, amikor a kitztt feladat kevesebb eredmny komponenst tartalmaz, mint a mintafeladat. A programozsi tteleink kztt ugyanis vannak olyanok, amelyek egyszerre tbb eredmnyt is adnak, de gyakori, hogy egy konkrt feladatban ezek kzl nincs mindre szksgnk. Ezek kzl egyiket-msikat el lehet hagyni a feladat llapotterbl, ha arra nincs szksg, hiszen egy eredmny komponens kezdrtktl nem fgg a tbbi eredmny. Termszetesen a minta feladatbl gy elhagyott komponensnek a vltozja ott marad a programozsi ttel programjban, de most mr csak, mint segdvltoz, s a program alap-llapottere a kitztt feladat llapottervel lesz azonos. A kt feladat elfelttele megegyezik (hiszen az eredmnykomponensek sohasem szerepelnek az elfelttelben), a mintafeladat utfelttele szigorbb (mert az elhagyott komponensekre is tesz megktseket), de ez az elz alfejezet szerint nem jelent akadlyt. A program teht megoldja a kitztt feladatot. Tipikus plda erre az, amikor egy maximum kivlasztsnl a maximlis rtk nem rdekel bennnket, csak az intervallumnak azon eleme, amelyhez a maximum tartozik. 5.3. Plda. Keressk egy g:[a..b] fggvnynek olyan argumentumt, ahol a fggvny a maximlis rtkt veszi fel!. A = (a:, b:, ind: ) Ef = ( a=a b=b ab ) Uf = ( Ef ind [a..b] g(ind) = max g(i) )
i a b

A kitztt feladat llapottere kiegszthet komponenssel, az utfelttele pedig szigorthat Uf = ( Ef max = max g(i)
i a b

max:

ind [a..b]

g(ind) = max )

s ez a szigorbb feladat visszavezethet a maximum kivlaszts programozsi ttelre.

88

5.3. Alteres visszavezets

m..n ~ f(i) ~

a..b g(i)

max, ind := g(a), a i = a+1 .. b g(i) > max max, ind := g(i), i SKIP

max: i:

A max vltoz nem eredmnyvltozja, hanem segdvltozja a fenti programnak. Megfelel talakts utn el is lehetne hagyni, de ez egyrszt a program hatkonysgn ronthat, msrszt egy ilyen mdosts veszlyezteti a program helyessgt. Kivtelt jelent az, amikor a fordtott feladatot kell megoldanunk: a maximlis rtket keressk s annak indexre nem vagyunk kvncsiak. Ilyenkor az index vltozt (ind), pontosabban az arra vonatkoz rtkadsokat el hagyhatjuk, hiszen ezen kvl ms talaktst nem kell a programon vgezni. Hasonl eset az, amikor el kell dntennk, hogy egy intervallum valamelyik elemre teljesl-e egy megadott felttel, de nem vagyunk kvncsiak arra, hogy melyik ez az elem. Az ilyen eldntses feladatot a lineris keressre vezethetjk vissza, eltrve azt, hogy a keress mellktermkknt a felttelnek eleget tev els elemet is megadja, ha van ilyen. 5.4. Plda. Felveszi-e a g:[a..b] fggvny a nulla rtket? A = (a:, b:, l: ) Ef = ( a=a b=b ) Uf = ( Ef l = i [a..b]: g(i)=0 ) Ez az gynevezett eldntses feladat a lineris keress programozsi ttelre vezethet vissza. Ez nyilvnval, ha kiegsztjk az llapottert a ind: komponenssel, s a feladatot szigortjuk azzal, hogy meg is kell keresni az el zrus helyet a g fggvnyben. A megold programbl most elhagyhatjuk a ind vltozt, pontosabban a

89

5. Visszavezets

ind:=i rtkadst, hiszen a ind vltoz rtkt a program nem hasznlja fel. l, i := hamis, a l i b i:

l := g(i)=0 i := i+1 Ezt a gondolatmenetet tkrzi majd az, amikor a ksbbiekben ilyen eldntses feladatok specifiklsra az albbi rvidtett jellst fogjuk hasznlni: Uf = ( Ef
l search (g(i)
i a b

0) )

Az alteres visszavezetseknek msik esete az, amikor a mintafeladat egy olyan bemen vltozjt, amely a program sorn nem vltoztatja az rtkt, a visszavezetskor egy elre rgztett rtk (konstans rtk) kifejezs helyettesti. Ez a komponens ilyenkor hinyzik a kitztt feladat llapotterbl, ezrt a feladat llapottere kevesebb komponensbl ll, mint a programozsi ttel. A specifikciban a konstansokat ltalban nem jelentetjk meg az llapottr komponenseknt, azaz nem definilunk hozz vltozt, br megtehetnnk; kiegszthetjk a kitztt feladat llapottert olyan komponenssel, amelyik kezdetben felvett rtke lland. Ettl a feladat nem fog megvltozni. Az gy mdostott specifikci elfelttele rgzti az j lland vltoz rtkt. Ha ez a mdostott specifikcij feladat visszavezethet valamelyik programozsi ttelre, akkor a visszavezetssel ellltott program az eredeti feladatot is megoldja, hiszen a bevezetett konstans rtk vltozkat a program segdvltozinak tekinthetjk. A mdostott elfelttel szigorbb, mint a programozsi ttel elfelttele, mert egy rtkt megrz vltoznak egy konkrt rtket r el tetszleges rgztett kezdrtk helyett. 5.5. Plda. Adjuk meg egy termszetes szm valdi osztinak szmt!

90

5.3. Alteres visszavezets

A = (n:, s:) Ef = ( n=n )


n div2

Uf = ( Ef

s
i 2 in

1)

talakthatjuk ezt a specifikcit az albbi formra: A = (m:, n:, s:) Ef = ( m=2 n=n )
n div2

Uf = ( Ef

s
i m in

1)

Itt mr ugyanolyan llapotter feladatrl van sz, mint a szmlls mintafeladata, csak a feladat elfelttele szigorbb, de ezt az ltalnos visszavezets megengedi. m..n (i) ~ ~ 1..n div 2 i n s := 0 i = 1 .. n div 2 i n s := s+1 SKIP i:

5.4. Paramteres visszavezets Tallkozhatunk olyan visszavezetsekkel is, ahol a megoldand feladat llapottere a visszavezetsre kivlasztott programozsi ttel mintafeladatnl nem szerepl, olyan bemeneti adatkomponenseket is tartalmaz, amelyeknek rtke lland. (Ezen tlmenen a termszetes visszavezetsnl megengedett eltrsek is elfordulhatnak.)

91

5. Visszavezets

5.6. Plda. Hatrozzuk meg a g:[a..b] legnagyobb, k-val oszthat rtkt s az [a..b] intervallumnak azt az elemt (argumentumt), ahol a g fggvny ezt az rtket felveszi! A = (a:, b:, k:, l: , ind:, max:) Ef = ( a=a b=b k=k) Uf = ( Ef l,max,ind = max g(i) )
i a k g(i) b

Ebben a feladatban a k vltoz rtke lland. (Nem konstans, hiszen ez egy bemen adat, de a kezdeti rtke mr nem vltozik.) Ha ennek egy rtkt rgztjk, akkor a feladatnak egy specilis, a rgztett rtkhez tartoz, azzal paramterezett vltozathoz jutunk. Ebben a vltozatban a paramter mr egy konstans, amelyet nem kell felvennnk az llapottr komponensei kz, gy a paramterezett feladat llapottere mr meg fog egyezni a visszavezetsre kivlasztott mintafeladatval. Pldul k=2 esetben: A = (a:, b:, l: , ind:, max:) Ef = ( a=a b=b ) Uf = ( Ef l,max,ind = max g(i) )
i a 2 g(i) b

Ez a paramterezett feladat mr minden gond nlkl visszavezethet a feltteles maximumkeress programozsi ttelre. m..n f(i) (i) ~ ~ ~ a..b g(i) 2 g(i) l: = hamis i = a .. b 2 g(i) SKIP l 2 g(i) l 2 g(i) i:

l, max, ind := max, ind := g(i), i SKIP igaz, g(i), i

max<g(i)

92

5.4. Paramteres visszavezets

Mivel a k minden lehetsges rtke mellett ez a visszavezets megtehet, ezrt az eredeti feladatot is meg tudjuk oldani gy, hogy sszes paramteres vltozatt megoldjuk. Termszetesen ezt elg ltalnosan egy tetszlegesen rgztett k rtkkel paramterezett feladatra megtenni. l:= hamis i = a .. b k g(i) SKIP l k g(i) l k g(i) i:

max<g(i) max, ind := g(i), i

l, max, ind := igaz, g(i), i SKIP

Ebben a k egy olyan vltoz, amelyik a program legelejn kap egy kezdrtket, azaz a megold program alap-llapotternek komponense lesz. A paramterezett visszavezetsre pldk mg azok a feladatok is, ahol egy tmb elemeit kell feldolgozni. Ilyenkor maga a tmb lesz a paramter. Az ilyen feladatok radsul egyben az alteres visszavezetsre is pldk, hiszen a programozsi ttel intervallumt gyakran a tmb indextartomnya hatrozza meg, teht annak vgpontjai, az intervallum nem szerepel az llapottr komponensei kzt, azokat a paramterbl lehet kinyerni. 5.7. Plda. Adott kt tmb: egy x s egy b. Fektessk a b-t folyamatosan egyms utn, s ezt helyezzk az x tmb mell. Hny esetben kerl egyms mell ugyanaz az rtk? Indexeljk nulltl a megadott tmbket, legyen az x tmb n, a b tmb m elem. Ekkor megfigyelhet, hogy az x tmb i-edik eleme mell mindig a b tmb i mod m-edik eleme kerl.

93

5. Visszavezets

n -1 n -1 A = (x: 0 , b: 0 , s:) Ef = ( x=x b=b )

n 1

Uf = ( Ef

s
i 0 x[i ] b[i mod m]

1)

Itt az x s b tmbk olyan rtkket nem vltoztat bemen vltozk, amelyeket rtkeiket lland paramtereknek vve elhagyhatunk az llapottrbl. Az gy kapott llapottr azonban mg mindig nem feleltethet meg a szmlls programozsi ttele llapotternek, hiszen abban a szmlls intervallumt kijell egsz szmok is szerepelnek. Itt lp be a kpbe az alteres visszavezets. A feladat implicit mdon tartalmazza az intervallum hatrait: az als hatr a 0 (ez konstans), a fels hatr pedig az x tmb utols elemnek az indexe, amelyik ugyancsak lland rtk bemen adat. Ennl fogva az intervallum beemelhet az llapottr bemen adatkomponensei kz. m..n (i) ~ ~ 0..n-1 x[i] = b[i mod m] s := 0 i = 0 .. n-1 x[i] = b[i mod m] s := s+1 SKIP i:

5.5. Visszavezetsi trkkk Bizonyos feladatok visszavezetssel trtn megoldsnak rdekben gy kell eljrnunk, hogy vagy a vlasztott programozsi ttelt ltalnostjuk, vagy a feladatot megfogalmazsn alaktunk. Nzznk erre pldkat. Azokat a feladatokat, amelyekben a "legtbb", "legnagyobb", "legdrgbb", "legtvolabbi" stb. szfordulatokkal tallkozunk, a maximum kivlasztssal trstjuk. A maximum kivlasztssal trsthat feladatok megtlsnl krltekinten kell eljrni. Egyfell azrt, mert

94

5.5. Visszavezetsi trkkk

hasonl szfordulatok jelezhetik a feltteles maximumkerest is, ahol nem egy intervallumhoz hozzrendelt sszes elem kztt, hanem csak bizonyos tulajdonsg elemek kztt keressk a maximumot. Msfell a maximum kivlasztsnl gyelni kell az elfelttelre, amely szerint a maximlis elem kivlasztshoz lteznie kell legalbb egy elemnek, azaz az intervallum nem lehet res. Ilyenkor vagy egy elgazsba ptjk be a maximum kivlasztst azrt, hogy csak nem-res intervallum esetn kerljn sor a maximum kivlasztsra, vagy feltteles maximumkeresst hasznlunk.11 Gondoljunk most arra a feladatra, amelynl egy adott f:[m..n] H fggvny rtkei kztt a legkisebb elemet keressk. A "legkevesebb", "legnagyobb", "legolcsbb", "legkzelebb" mellknevek minimum kivlasztsra utalnak. A krds az, hogyan lehet egy minimum kivlasztsos feladatot a maximum kivlaszts programozsi ttelre visszavezetni. Azt mindenki rzi, hogy minimum kivlaszts programja mindssze annyiban tr el a maximum kivlasztstl, hogy msik relcit hasznlunk az elgazsnak felttelben: A max<f(i) helyett a max>f(i)-t. (Clszer lesz a max vltoz nevt min-re cserlni.) De hogyan bizonythatjuk, hogy ez a program tnyleg helyes? Ktfle utat is mutatunk. min, ind := f(m), m i = m+1 .. n min>f(i) min, ind := f(i), i SKIP i:

Az egyik t az, hogy a maximum kivlaszts programozsi ttelt ltalnostjuk. A maximum kivlasztsnl hasznlt " " relci tulajdonsgai kzl ugyanis csak azt hasznltuk ki, hogy ez egy teljes
11

Itt hvjuk fel a figyelmet az olyan feladatokra is, amelyekben egy intervallum pontjai kztt keressk a legnagyobb adott tulajdonsgt. Ilyen pldul a legnagyobb kzs oszt keresse. Ezeket a feladatokat nem rdemes feltteles maximumkeressre visszavezetni, tkletesen megfelel az intervallumban egy fordtott irny kivlaszts vagy lineris keress is.

95

5. Visszavezets

rendezsi relci, de a specilis jelentse egyltaln nem volt rdekes. Ezrt ez brmilyen H halmaz feletti teljes rendezsi relcival, specilisan a " " relcival is helyettesthet. A msik t a feladat talaktsval kezddik. Az f fggvny rtkei kztti minimumot megkereshetjk fggvnyrtkek ellentettjei kztti maximum kivlasztssal. Igaz, hogy ekkor a program ltal megtallt maximum ppen a keresett minimum ellentettje lesz, ezrt a programban a max helyre mindenhol min-t kell majd rnunk. -min, ind := f(m), m i = m+1 .. n -min<f(i) -min, ind:= f(i), i SKIP i:

Ez a program azonban nem megengedett, mert olyan rtkadst tartalmaz, amelynek a baloldaln egy vltoznl ltalnosabb kifejezs ll. A min:= f(i) pszeudo-rtkads hatsa azonban azonos a min:= f(i) rtkadsval, gy ezzel lecserlhet. Ha mg az elgazs-felttelt is beszorozzuk -1-gyel, akkor megkapjuk a vgleges vltozatot. Hasonl mdszerekkel oldhat meg az a keress, amikor nem a legels, hanem a legutols adott tulajdonsg elem megtallsa a cl. Ekkor a szmegyenes [m..n] intervallumt kell tkrzni az origra, s az gy kapott [n..m] intervallumban keressk az els adott tulajdonsg elemet. A program ltal tallt i helyett a i-t kell eredmnynek tekinteni. l,i: = hamis,n l i m i:

l, ind := (-i), -i i := i+1 A vgleges vltozatot, a fordtott irny keresst ebbl gy kaphatjuk meg, ha a programban az i vltoz helyre mindenhol i

96

5.5. Visszavezetsi trkkk

pszeudo-vltozt rjuk (ez egy vltoz tnevezs, amelyre i=(i) ll fenn), majd a i:=i+1 s i:=n pszeudo-rtkadsokat talaktjuk normlis rtkadsokk, s vgl a ciklusfelttelt is egyszerstjk. l,i := hamis,n l i m i := i1 A lineris keresst az eldnts jelleg feladatok megoldsra is fel lehet hasznlni (alteres visszavezets). Ilyenkor csak azt vizsgljuk, hogy a vizsglt felttel bekvetkezik-e az intervallum valamelyik pontjn. Mivel nem vagyunk kvncsiak arra, hogy m elyik ez a pont, az algoritmusbl az ind:=i rtkadst el is hagyhatjuk. Sokszor keressk arra a krdsre a vlaszt, hogy vajon az intervallum minden eleme rendelkezik-e egy adott tulajdonsggal (l= i [m..n]: (i)). Ezt az eldntses feladatot is vissza lehet vezetni a lineris keressre. Ha ezt egy olyan lineris keresssel oldjuk meg, amely azt vizsglja, hogy van-e olyan elem, amelyik nem rendelkezik az adott tulajdonsggal (u= i [m..n]: (i)), akkor a kapott vlasz alapjn az eredeti krds is knnyen megvlaszolhat (l= u). Msik megoldshoz jutunk az albbi gondolatmenettel. Tekintsk a megoldand feladat utfelttelt, majd ezt alaktsuk t vele ekvivalens, de a lineris keressre visszavezethet formra: Uf = ( Ef l = k [m..n]: (k) ) = = ( Ef l = ( k [m..n]: (k) ) ) = = ( Ef l = k [m..n]: (k) ) = = ( Ef
l search
i m n

i:

l, ind := (i), i

(i) )

97

5. Visszavezets

l,i := hamis,m l l:= i n (i)

i:

i := i+1 A program l:=hamis s l:= (i) pszeudo-rtkadsait talaktva s a ciklusfelttelt egyszerstve megkapjuk a vgleges vltozatot, amelyet akr j programozsi ttelknt is tagadott vagy jeles vagy optimista lineris keress nven jegyezhetnk meg. Ezt legkifejezbben az l = ( k [m..n]: (k) ) ) specifikcis formula fejezi ki, de bevezethetjk r az l
search (i) jellst is.
i m n

l,i:= igaz,m l i n

i:

l := (i) i := i+1 Vgl megemltnk egy olyan gyakorta elfordul feladatot, amelyet nll programozsi ttelknt is bevezethettnk volna. Ez az gynevezett feltteles sszegzs. Errl akkor beszlnk, amikor (i) logikai felttel rtktl fgg, hogy az sszegzs sorn az f(i)-t hozz kell-e adnunk az eredmnyhez. Ilyenkor a feladat utfelttele az albbi:
n

Uf = ( Ef vagy mskpp

s
i m

g(i) ), ahol g(i)

f(i) 0

ha (i) klnben

98

5.5. Visszavezetsi trkkk

Uf = ( Ef

s
i m (i)

f(i) )

Ezt a feladatot visszavezethetjk a kznsges sszegzsre, amelyben az s:=s+g(i) rtkadst egy (i) felttel elgazssal helyettestjk, amelyben az s:=s+f(i) rtkads kap szerepet. s: = 0 i = m .. n (i) s := s + f(i) SKIP i:

A feltteles sszegzsnek specilis esete a szmlls (amikor az f(i) mindig 1) vagy a kivlogats (amikor az sszeads helyn az sszefzs mvelete ll). Ebben a knyvben a szmllst gyakorisga miatt nll programozsi ttelknt vezettk be, de az sszegzs tbbi esett nem. 5.6. Rekurzv fggvny kiszmtsa Nem mutattunk ez idig pldt a rekurzv fggvny helyettestsi rtkt kiszmt programozsi ttel alkalmazsra. Habr ennek a ttelnek az alkalmazsa sem bonyolultabb a tbbi programozsi ttelre trtn visszavezetsnl, egy feladatban azt felismerni, hogy az eredmnyt egy rekurzv fggvnnyel lehet kiszmolni, sok gyakorlatot ignyel. Az ugyanis, hogy egy feladat megoldshoz maximumkeressre vagy ppen szmllsra van szksg az sokszor explicit mdon kifejezsre jut a feladat szvegben. A rekurzv fggvny defincijt viszont minden esetben neknk kell kitallni. Az ilyen feladatok specifikcija nehz, ugyanakkor ppen ez a kulcsa egy bonyolult feladat egyszer s hatkony megoldsnak. 5.8. Plda. Adott egy egsz szmokat tartalmaz tmb. Keressk meg a tmb legnagyobb s legkisebb rtkt!

99

5. Visszavezets

Ez a feladat nyilvn megoldhat kln egy maximum- s kln egy minimum kivlaszts segtsgvel. De nem lehetne a feladat eredmnyt egy egyszerbb s gyorsabb programmal ellltani? Pldul olyan fggvny segtsgvel, amelyik egyszerre kt rtket is felvesz, amely az i-dik helyen ellltja az x tmb els i darab elemnek a maximumt is, s a minimumt is, s ennek megfelelen az n-edik helyen az x tmb sszes elemnek a maximumt s a minimumt adja. A = (x: n, max:, min:) Ef = ( x=x n1 ) Uf = ( Ef (max, min) = f(n) ) Definiljuk az f fggvnyt rekurzv mdon. Az f(i) rtkei ugyanis knnyen meghatrozhatak f(i1) (azaz az x tmb els i-1 darab elemnek maximuma s minimuma), valamint az x[i] rtk alapjn. Azt is ltni, hogy f(1)= (x[1], x[1]), hiszen a vektor els elemnek maximuma is, minimuma is a tmb els eleme. f:[1..n] f(1) = (x[1], x[1]) f1(i) = max( f1(i1), x[i] ) i [2..n] f2(i) = min( f2(i1), x[i] ) i [2..n] Ez egy 2 bzis elsrend ktrtk rekurzv fggvny. m..n y e0 h1(i, f1(i1)) h2(i, f2(i1)) ~ ~ ~ ~ ~ 2..n (max, min) (x[1], x[1]) max( f1(i1), x[i] ) min( f2(i1), x[i] ) max, min := x[1], x[1] i = 2 .. n max, min := max( max, x[i] ), min( min, x[i] ) Vagy a ciklusmagot ms alakra hozva: i:

100

5.6. Rekurzv fggvny kiszmtsa

max, min := x[1], x[1] i = 2 .. n x[i] < min min := x[i] min x[i] max SKIP x[i] > max max := x[i] i:

Ez a plda rvilgtott arra is, hogy a rekurzv fggvny kiszmtsa programozsi ttellel helyettesteni lehet ms programozsi tteleket. 5.9. Plda. Egy tmb egy b alap szmrendszerben felrt termszetes szm szmjegyeinek rtkeit tartalmazza gy, hogy a magasabb helyirtkek vannak ell. Szmoljuk ki a tmbben trolt termszetes szm rtkt! A = (x:n, b:, s:) Ef = ( x=x b=b b2 i [1..n]: x[i]<b)
n

Uf = ( Ef

s
k 1

x[k ] b n

A feladat visszavezethet az sszegzs programozsi ttelre, de ebben az esetben minden lpsben hatvnyozni kell a b-t, s ezzel egytt mint az utfelttel kpletbl ltszik sszesen n(n1)/2+1 darab szorzst kell elvgezni. Megfigyelhet, hogy ha bevezetjk az f: [0..n] N
i

f(i) =
k 1

x[k ] b i

fggvnyt, akkor a feladat tulajdonkppen az f(n) kiszmtsa. Uf = ( Ef s = f(n) ) Belthat, hogy minden 1-nl nagyobb i-re az f(i) = f(i1)*b+x[i] rekurzv sszefggs ll fenn. Definiljuk teht az f fggvnyt mskppen:

101

5. Visszavezets

f: [0..n] f(0) = 0 f(i) = f(i1)*b+x[i] i [1..n] Ekkor a feladat visszavezethet a rekurzv kiszmtsnak ttelre. m .. n y e0 h(i, f(i1)) ~ ~ ~ ~ s := 0 i = 1 .. n s := s*b+x[i] i: 1..n s 0 f(i1)*b+x[i]

fggvny

Ez az algoritmus szemben az elzvel mindssze n1 szorzst hasznl.12 5.10. Plda. Kt n hosszsg tmb egy-egy b alap szmrendszerben felrt termszetes szm szmjegyeinek rtkeit tartalmazza gy, hogy a magasabb helyirtkek vannak ell. lltsuk el ennek a kt termszetes szmnak az sszegt gy, hogy a szmjegyeit elhelyezzk egy harmadik n hosszsg tmbben s azt kln is jelezzk, hogy trtnt-e tlcsorduls, azaz elfrt-e az eredmny a harmadik tmbben (n darab helyirtken)! (Feltesszk, hogy csak szmjegyeket tudunk sszeadni, azaz nem j megolds a tmbkben brzolt szmok rtkt kiszmolni, azokat sszeadni, majd az eredmnyt elhelyezni egy harmadik tmbben.)

12

Ezt az algoritmust szoktk Horner algoritmusnak is nevezni, mert az albbi Hornerrl elnevezett sma alapjn szmolja ki egy termszetes szmnak az rtkt a szm szmjegyei alapjn:
n

x[k ] b n
k 1

(...(( x[1] b

x[2]) b

x[3])...) b

x[n]

102

5.6. Rekurzv fggvny kiszmtsa

A tlcsordulst ne egy logikai rtk, hanem egy 0 vagy 1 rtk mutassa. Kt szm sszeadsnl ugyanis akkor keletkezik tlcsorduls, ha a legnagyobb helyirtk szmjegynek kiszmolsakor 1 rtk tvitel keletkezik. ltalban tvitelrl akkor beszlnk, amikor az sszeadand kt szm adott helyirtkn lev szmjegyinek, valamint az eggyel kisebb helyirtkrl szrmaz tvitel sszege nagyobb, mint a legnagyobb szmjegy, s ezrt az eggyel magasabb helyirtkhez kell majd hozz adni mg egyet, azaz az tvitel 1. Ha viszont a legmagasabb helyirtken keletkezik az tvitel, akkor azt mr nincs hov hozzadni: ez a tlcsorduls. A = (x:n, y:n, z:n, b:, c:{0,1}) Ef = ( x=x y=y b=b b2 i [1..n]:x[i]<b y[i]<b ) Uf = ( Ef (z,c) = f(n) ) Az utfelttelben hivatkozunk egy olyan fggvnyre, amely kt rtket llt el: egy tmbt (ez tartalmazza az x s y tmbkben trolt termszetes szmok sszegnek szmjegyeit) s egy tlcsorduls bitet, amely rtke akkor 1, ha nem fr el az sszeg n helyirtken. Clunk, hogy minden i [1..n] esetn az f(i) egyrszt adjon meg egy olyan tmbt, amelynek utols i darab eleme (az [ni+1 .. n] index elemei) mr az eredmnyknt ellltott termszetes szm utols i darab szmjegyt tartalmazza, msrszt adja meg, hogy keletkezett-e tvitel a bi1-es helyirtken, azaz a tmb ni+1-dik pozcijnak kiszmolsnl. Az f1(i) teht egy tmb, az f2(i) pedig egy 0 vagy 1-es rtk. Az f1(i)-nek (az eredmny tmbnek) utols i1 darab eleme meg kell egyezzen az f1(i1) utols i1 darab elemvel (ezek az [ni+2 .. n] index elemek). A tmb ni+1-dik pozcijnak meghatrozshoz pedig az x[ni+1] s y[ni+1] elemeken kvl szksg van az elz helyirtken keletkezett tvitelre, az f2(i1)-re is. Itt teht egy elsrend rekurzirl van sz. Kezdetben az tvitel rtkt 0-ra, az eredmny tmbt tetszleges rtkre lltjuk. f: [0..n] n{0,1} f1(0) = * (ez egy tetszleges rtk), f2(0) = 0 i [1..n]: f1(i)[ni+2 .. n] = f1(i1)[ni+2 .. n], f1(i)[ni+1] = (x[ni+1]+y[ni+1]+f2(i1)) mod b f2(i) = (x[ni+1]+y[ni+1]+f2(i1)) div b A feladat egy 1 bzis elsrend ktrtk rekurzv fggvny helyettestsi rtknek kiszmolsa lesz.

103

5. Visszavezets

m .. n ~ 1..n y ~ z,c e0 ~ *,0 h1(i, f(i1))[ni+1] ~ (x[ni+1]+y[ni+1]+f2(i1)) mod b h1(i, f(i1))[ni+2..n]~ f1(i1)[ni+2..n] h2(i, f(i1)) ~ (x[ni+1]+y[ni+1]+f2(i1)) div b c := 0 i = 1 .. n z[ni+1] := (x[ni+1]+y[ni+1]+c) mod b c := (x[ni+1]+y[ni+1]+c) div b i:

104

5.7. Feladatok

5.7. Feladatok 5.1. 5.2. Adott a skon nhny pont a koordintival. Keressk meg az orighoz legkzelebb es pontot! Egy hegyoldal hegycscs fel vezet svnye mentn egyenl tvolsgonknt megmrtk a terep tengerszint feletti magassgt, s a mrt rtkeket egy vektorban troljuk. Megfigyeltk, hogy ezek az rtkek egyszer sem cskkentek az elz rtkhez kpest. Igaz-e, hogy mindig nvekedtek? Hatrozzuk meg egy egsz szmokat tartalmaz tmb azon legkisebb rtkt, amely k-val osztva 1-et ad maradkul! Adottak az x s y vektorok, ahol y elemei az x indexei kzl valk. Keressk meg az x vektornak az y-ban megjellt elemei kzl a legnagyobbat! Igaz-e, hogy egy tmbben elhelyezett szveg odafel s visszafel olvasva is ugyanaz? Egy mtrix egsz szmokat tartalmaz sorfolytonosan nveked sorrendben. Hol tallhat ebben a mtrixban egy tetszlegesen megadott rtk! Keressk meg kt termszetes szm legkisebb kzs tbbszrst! Keressk meg kt termszetes szm legnagyobb osztjt! Prm szm-e egy egynl nagyobb egsz szm? Egy n elem tmb egy b alap szmrendszerben felrt termszetes szm szmjegyeinek rtkeit tartalmazza gy, hogy a magasabb helyirtkek vannak ell. Mdostsuk a tmbt gy, hogy egy olyan termszetes szm szmjegyeit tartalmazza, amely az eredetinl eggyel nagyobb, s jelezzk, ha ez a megnvelt rtk nem brzolhat n darab helyirtken!

5.3. 5.4.

5.5. 5.6.

5.7. 5.8. 5.9. 5.10.

105

6. Tbbszrs visszavezets
A visszavezets technikjnak megrtse, elsajttsa nmagban knny feladat. Alkalmazsa akkor vlik nehzz, amikor egy sszetett problma megoldshoz egyszerre tbb programozsi ttelt is fel kell hasznlni. Mr egy kezd programoznl is kialakul az a kpessg, hogy egy sszetett feladatban szrevegye a megoldshoz szksges programozsi tteleket, de ezek egymshoz val viszonyt, az egyiknek a msikba val begyazsnak mdjt mg nem ltja tisztn. Ehhez arra van szksg, hogy a megoldand feladatot rszekre tudjuk bontani gy, hogy a rszfeladatokat a programozsi ttelek segtsgvel meg lehessen oldani, s az gy kapott rszmegoldsokat kell egy programm sszepteni. A rszfeladatok kijellst hatkonyan tmogatja, ha a feladat megfogalmazsakor az egyes fogalmak jellsre egy-egy alkalmas fggvnyt vezetnk be. Ezek a kitallt, teht absztrakt fggvnyek a megolds bizonyos fzisaiban elrejtik az ltaluk definilt rszfeladatokat. A begyazott rszfeladatok elrejtse kvetkeztben vilgosabban lthat, hogy magasabb szinten milyen programozsi ttellel oldhat meg a feladat. Csak ezt kveten kell foglalkozni a rszfeladatokkal, amelyek megoldst a feladat tbbi rsztl fggetlenl, a rszfeladatot elrejt fggvny kiszmtsval llthatjuk el. Ezt a fggvnyabsztrakcis programozsi technikt procedurlis (modularizlt) programksztsnek is nevezik, mert az gy kszlt programok kdolsakor elklntjk a rszfeladatokat megold programokat, ezltal a teljes program rszprogramokra bomlik. Mivel a klnvlasztott programrszek (procedurk, modulok) jl tlthat, ellenrztt kapcsolatban llnak, ezrt a rszprogramok vgrehajtsi sorrendje pontosan ki van jellve. Amikor egy rszprogramrl tkerl a vgrehajtsi vezrls egy msikra, akkor az els adatokat adhat t a msodiknak. Amennyiben egy rszprogram lerst fizikailag is elvlasztjuk a teljes programrl, akkor azt alprogramnak hvjuk. Egy alprogram maga is tbb alprogramra bonthat, ami ltal sszetett, hierarchikus szerkezete lesz a programunknak. Ebben a fejezetben elszr bevezetjk az absztrakt programok szintjn az alprogramok fogalmt, majd nhny pldn keresztl

106

bemutatjuk, hogyan alkalmazhat tbbszrsen a visszavezets technikja az sszetett feladatok megoldsnl, s az gy kapott programot a feladat rszfeladatai mentn hogyan trdeljk alprogramokra. A harmadik alfejezetben ttekintjk azokat a programtalakt szablyokat, amelyek alkalmazsa knyelmesebb teszi a programksztst, hatkonyabb az elksztett programot. Az utols alfejezetben egy klnleges program-talaktst mutatunk arra az esetre, amikor egy ciklusban szerepl rszfeladat eredmnye rekurzv fggvnnyel szmolhat ki.

107

6. Tbbszrs visszavezets

6.1. Alprogram Egy program lersban szerepl brmelyik rszprogram egy jl meghatrozott rszfeladatot old meg. Ha egy rszprogram fizikailag is elklnl a program lersban, akkor azt alprogramnak nevezzk. Struktogrammos jells esetn egy rszprogrambl gy kszthetnk alprogramot, hogy a rszprogramot kiemeljk az azt tartalmaz program struktogrammjbl, a kiemelt struktogrammot egyedi azonostval ltjuk el, s a rszprogram helyt a program struktogrammjban ezzel az azonostval jelljk. Ez lehetsget ad majd arra is, hogy ugyanarra az alprogramra ha kell tbb helyen is hivatkozhassunk rszprogramknt. Mivel minden feladat megoldhat egy (ltalban nem megengedett) rtkadssal, ezrt az alprogramjaink ltal megoldott rszfeladatok is, ennl fogva minden alprogram azonosthat ezzel az rtkadssal. Ezrt a tovbbiakban az alprogramot ler struktogrammot ezzel az rtkadssal azonostjuk. Ez az alprogram feje. Egy program struktogrammjban, ahol az alprogramot rszprogramknt ltni kvnjuk, ugyanezt az rtkadst rjuk. Ezt az alprogramot meghv utastsnak, rviden hvsnak nevezik. Amikor egy program vgrehajtsa sorn elrnk egy alprogram hvshoz, akkor onnan kezdve az alprogram hatrozza meg a vgrehajts menett, azaz tkerl a vezrls az alprogramhoz. Az alprogram befejezdsekor a vezrls visszatr a hv programhoz s a hv utasts utn folytatdik. Ms szavakkal, a hv programnak (amely a hvst tartalmazza) a hvs pillanatig befutott vgrehajtsa (llapotsorozata) felfggesztdik, az ekkor elrt llapotbl az alprogram egy vgrehajtsval (llapotsorozatval) folytatdik, majd az gy elrt llapotbl a hv programnak a hvs utni utastsai alapjn folytatdik vgrehajts. Az alprogram kiindul llapottere tartalmazza a hv program llapotternek a hvs pillanatban (segdvltozkkal egytt) meglev komponenseit. Ms szavakkal az alprogram hasznlhatja a hv program azon vltozit, amelyek az alprogram hvsakor lnek. Ezeket az alprogram szempontjbl globlis vltozknak nevezzk. Az alprogram mint minden program bevezethet j vltozkat is, de ezek az alprogram befejezdsekor megsznnek. Ezeket nevezzk az alprogram loklis vltozinak. Egy loklis vltoz neve megegyezhet

108

6.1. Alprogram

egy globlis vltoz nevvel, de ekkor gondoskodni kell arrl, hogy a kt ugyanolyan nev, de termszetesen egymstl fggetlen vltozt megklnbztessk valahogyan egymstl. Mi erre nem vezetnk be kln jellst, de megllapodunk abban, hogy az ilyen esetekben, amikor egy vltoz neve nem azonostja egyrtelmen a vltozt, akkor azon mindig a loklis vltozt rtjk. Termszetesen az alprogramnak nem kell minden globlis vltozt hasznlnia. Ennl fogva egy alprogram ms, eltr llapotter programokbl is meghvhat, feltve, hogy azok llapotterben a hvs pillanatban vannak olyan vltozk, amelyeket az alprogram globlis vltozknt hasznlni akar. A legrugalmasabb alprogramok ebbl a szempontbl azok, amelyek egyltaln nem hasznlnak globlis vltozkat, mert ezeket brmelyik programbl meghvhatjuk. De hogyan tud ebben az esetben az alprogram a hv program vltoziban trolt rtkekhez hozzfrni, s hogyan tud azoknak j rtkeket adni? Az alprogramot meghv utastsnak s az alprogram fejnek nem kell bet szerint megegyeznie. Az alprogram fejeknt hasznlt rtkads klnbzhet a hv utastsknt szerepeltetett rtkadstl abban, hogy egyrszt az rtkads baloldaln ll vltozk neve eltrhet (tpusaik s sorrendjk azonban nem), msrszt az rtkads jobboldaln lev rszkifejezsek helyn azokkal azonos tpus vltozk llhatnak. Ezek az alprogram paramtervltozi. A kizrlag az rtkads jobboldali kifejezsben lv paramtervltozkat szoktk a bemen-vltozknak, az rtkads jeltl balra levket eredmnyvltozknak nevezni. Egy paramtervltoz lehet egyszerre bemen s eredmny-vltoz is. Ebben az esetben a hvutastsban a vltoz helyn csak egy vltoz llhat, konstans vagy kifejezs nem. A fej paramtervltozinak balrl jobbra felsorolst (az esetleges ismtldsek megszntetse utn) formlis paramterlistnak szoktk hvni. A hv utastsban a paramtervltozknak megfeleltetett vltozk s kifejezsek (ismtlds nlkli) felsorolst aktulis paramterlistnak, elemeit paramtereknek nevezzk. A formlis s aktulis paramter lista elemszma s elemeinek tpusa azonos kell hogy legyen. A paramtervltozk az alprogramban jnnek ltre s az alprogram befejezdsekor sznnek meg, teht loklis vltozi az alprogramnak, de klnleges kapcsolatban llnak az alprogram hvsval. Az alprogram hvsakor ugyanis a bemen paramtervltozk megkapjk a hv utastsban a helykn ll

109

6. Tbbszrs visszavezets

kifejezsek (specilis esetben vltozk) rtkt kezdrtkknt. Az alprogram befejezdsekor pedig az eredmny-vltozk rtkei tmsoldnak a hv rtkads baloldaln ll megfelel vltozkba. (A bemen vltozk kivtelvel az alprogram tbbi loklis vltozjnak kiindul rtke nem-definilt.) Egy alprogram hvsra gy is sor kerlhet, hogy a hv utastsnak csak a jobboldalt tntetjk fel, de ez olyan krnyezetben jelenik meg, amely kpes elkapni, feldolgozni az alprogram eredmnyvltozi ltal visszaadott rtkeket. Hogy egy egyszer pldval megvilgtsuk ezt, kpzeljnk el egy olyan alprogramot, amelyet az l:=felt(i) rtkads azonost, ahol l egy logikai, az i pedig egy egsz rtk vltoz. Ez az alprogram meghvhat pldul egy u:=felt(5) rtkadssal (ahol u egy logikai vltoz), vagy egy olyan elgazssal, ahol az elgazs felttele felt(5), azaz a felttel logikai rtkt az alprogram eredmnye adja, a felt(i). Az els esetben a hvs a teljes rtkads megadsval trtnt, a msodik esetben csak egy kifejezssel. Valjban csak formai szempontbl van klnbsg a ktfle hvs kztt: az els esetben hv utastssal trtn eljrsszer hvsrl, a msodikban hv kifejezssel kivltott fggvnyszer hvsrl beszlnk.13 A hv kifejezs lehet a hv programnak nll kifejezse (pldul egy elgazs vagy ciklus felttele, vagy akr egy rtkads jobboldala) vagy egy kifejezs rsze. A hv kifejezs rtke tbb eredmny-vltoz esetn tbb komponens. Eljrsszer hvs esetn az aktulis (a hvsban szerepl) eredmny-vltozk kapjk meg a formlis eredmny-vltozk rtkt. Fggvnyszer hvskor az alprogram eredmny-vltozinak rtke a hv kifejezs rtkeknt jelenik meg a hv programban.

13

A fggvnyszer hvssal elindtott alprogramot a konkrt programozsi nyelvek fggvnynek, az nll utastssal (rtkadssal) meghvott alprogramot eljrsnak nevezik.

110

6.2. Begyazott visszavezets

6.2. Begyazott visszavezets Ebben az alfejezetben a tbbszrs visszavezetssel megoldhat feladatokkal foglalkozunk, pontosabban olyanokkal, amelyek megoldsnl egy programozsi ttelt egy msikba kell begyazni. Ilyenkor a programnak azt a rszt, amelyet a begyazott ttelre vezettnk vissza, gyakran alprogramknt szerepeltetjk. 6.1. Plda. Egy iskola egyik n dikot szmll osztlyban m klnbz tantrgybl osztlyoztak a flv vgn. A jegyek egy tblzat formjban rendelkezsnkre llnak. (A dikokat s a tantrgyakat most sorszmukkal azonostjuk.) llaptsuk meg, van -e olyan dik, akinek csupa tse van! A feladat egy "van-e olyan az elemek kztt, hogy ..." tpus eldntsbl ll, ami alapjn sejthet, hogy a lineris keress programozsi ttelre lehet majd visszavezetni. Ebben a keressben a dikokat kell egyms utn megvizsglni, hogy csupa tsk van-e. Egy dik megvizsglsa is egy eldntses feladat, csakhogy itt arra keressk a vlaszt, hogy a diknak minden jegye ts-e. Az ilyen "minden elem olyan-e, hogy ..." tpus eldntseknl az optimista lineris keresssel adhatjuk meg a vlaszt. A feladat megoldsa teht elssorban egy lineris keress lesz, amelyik magba foglalja a "csupa ts" tulajdonsgot eldnt optimista lineris keresst. Nzzk meg ezt alaposabban! A feladat bemen adata az osztlyzatok tblzata: egy n sor s m oszlop mtrix, amelynek elemei 1 s 5 kz es egsz szmok. Kimen adata egy logikai rtk, amely igaz, ha van kitn tanul, hamis klnben. A = (t:nm , l: ) Ef = ( t=t ) Az utfelttel megfogalmazshoz bevezetnk egy fggvnyt, amelyik a t tblzat i-edik sora alapjn megmondja, hogy az i-edik diknak csupa tse van-e. Ez a sznjeles fggvny egy intervallumon rtelmezett logikai fggvny, amely akkor ad igazat az i-edik rtkre, ha a tblzat i-edik sornak minden eleme ts.

111

6. Tbbszrs visszavezets

sznjeles :[1..n] sznjeles(i) = j [1..m]: t[i,j]=5 Ennek segtsgvel knnyen felrhat a feladat utfelttele: az l pontosan akkor igaz, ha van olyan dik, azaz 1 s n kz es egsz szm, amelyre a sznjeles felttel igazat ad. Uf = ( Ef l = i [1..n]: sznjeles(i) ) Ez a feladat visszavezethet a lineris keress programozsi ttelre. A lineris keress specifikcis jellsnl most csak a logikai komponens van eredmnyknt feltntetve, hiszen csak ennek megadsa a feladat. m..n ~ 1..n (i) ~ sznjeles(i) l,i := hamis,1 l i n l := sznjeles(i) i := i+1 Ebben a programban az l:=sznjeles(i) rtkads nemmegengedett. Hangslyozzuk, hogy a sznjeles(i) nmagban csak egy kifejezs, nem tekinthet sem feladatnak, sem programnak, szemben az l:=sznjeles(i) rtkadssal. Ezt az rtkadst, mint rszfeladatot, tovbb kell finomtani, azaz egy megengedett programmal kell majd helyettesteni, azaz meg kell oldani. A megoldst egy alprogram keretben rjuk most le, amelynek hvst az l:=sznjeles(i) rtkads jelzi. (Dnthettnk volna gy is, hogy az l:=sznjeles(i) rtkadst megold rszprogramot bemsoljuk l:=sznjeles(i) rtkads helyre, de most inkbb az alprogramknt val meghvst rszestjk elnyben.) A rszfeladatnak a specifikcija az albbi lesz. A = (t: nm, i:, l: ) Ef = ( t=t i=i [1..n] ) Uf = ( Ef l = sznjeles(i) ) Figyelembe vve a sznjeles(i) defincijt ez a rszfeladat is visszavezethet a lineris keress programozsi ttelre, pontosabban i:

112

6.2. Begyazott visszavezets

az optimista lineris keressre. gyelni kell arra, hogy ciklusvltoznak nem hasznlhatjuk az i-t, hiszen az a rszfeladatnak egy bemen adata, foglalt vltoznv. Hasznljuk helyette a j-t. Ennek megfelelen a visszavezetsnl valjban nem a (i)-t, hanem a (j)-t kell helyettesteni a konkrt t[i,j]=5 felttellel, amelyben az i a vizsglt dik sorszmra utal. m..n ~ 1..m i ~ j (i) ~ t[i,j]=5 l:=sznjeles(i) l,j := igaz,1 l j m j:

l := t[i,j]=5 j := j+1 Az alprogram feje az l:=sznjeles(i) rtkads, amely most szrl szra megegyezik a hvssal. Korbbi megllapodsunk szerint a fejben szerepl l s i vltozk (a formlis paramtervltozk) az alprogram loklis vltozi, nem azonosak a hvsnl szerepl ugyanolyan nev globlis vltozkkal (az aktulis paramterekkel), de sajtos kapcsolatban llnak azokkal. (Termszetesen hasznlhattunk volna ms loklis vltoz neveket.) A loklis i (bemen-vltoz) a hvskor megkapja a globlis i rtkt, a loklis l (eredmny-vltoz) a hvs (azaz az alprogram) befejezdsekor tadja rtkt a globlis l-nek. A paramtervltozk nvegyezse miatt az alprogramban nem hivatkozhatunk a globlis l s i vltozkra. Hasznlhatja ellenben az alprogram a globlis t vltozt. Az alprogram bevezet mg egy loklis j vltozt is, amely az alprogram befejezdsekor megsznik majd. 6.2. Plda. Egy n dikot szmll osztlyban m klnbz tantrgybl adtak jegyeket a flv vgn. Ezek az osztlyzatok egy tblzat formjban rendelkezsnkre llnak. (A dikokat s a tantrgyakat most is a sorszmukkal azonostjuk.) Tudjuk, hogy az osztlyban van kitn dik, adjuk meg az egyiknek sorszmt!

113

6. Tbbszrs visszavezets

Ez a feladat nagyon hasonlt a 6.1. pldhoz. Ott nem tudtuk, hogy van-e kitn dik, ezrt a lineris keress programozsi ttelre vezettk vissza a feladatot, itt viszont tudjuk, hogy van, s egy ilyen dikot keresnk, ezrt elegend a feladatot a kivlaszts ttelre visszavezetni. (Termszetesen a 6.1. pldnl kapott program is alkalmazhat, hiszen a lineris keress nemcsak azt dnti el, hogy vane kitn dik, hanem az elst meg is keresi.) A = (t:nm, i:) Ef = ( t=t k [1..n]: sznjeles(k) ) Itt mr az elfelttel megfogalmazshoz bevezetjk a sznjeles fggvnyt. Uf = ( Ef i [1..n] sznjeles(i) ) = = ( Ef i select sznjeles (i) )
i 1

Ez a feladat visszavezethet a kivlaszts programozsi ttelre. m ~ 1 (i) ~ sznjeles(i) i := 1 sznjeles(i) i := i+1 Ebben a programban nem-megengedett felttel a sznjeles(i) kifejezs, amely rtkt az elz pldban elksztett l:=sznjeles(i) alprogram hatrozza meg. Most erre az alprogramra egy fggvnyszer hvst adunk. Amikor a ciklusfelttel kirtkelsre kerl sor, akkor meghvdik az alprogram, s a loklis eredmny-vltozjnak (l: ) rtke kzvetlenl a ciklusfelttelnek addik vissza. Ezzel teht kszen is vagyunk. Egy alprogram nem lesz ms attl, hogy fggvnyszeren vagy eljrsszeren hvjuk meg. Az alprogram mindig egy rtkads ltal kijellt feladatot old meg, van eredmny-vltozja, hiszen egy rtkadst valst meg. A 6.1. pldban ppen ezrt fggvnyszer hvsrl is s eljrsszer hvsrl is beszlhetnk egyszerre, nincs e kett kztt lthat klnbsg. Egy eljrsszer hvs ugyanis mindig felfoghat fggvnyszer hvsnak is. Fordtva ez mr nem igaz, de

114

6.2. Begyazott visszavezets

mindig talakthat a hv program gy, hogy egy fggvnyszer hvst eljrsszer hvssal helyettesthessnk. Ezt akkor tesszk meg, ha ezt valamilyen ms szempont (pldul hatkonysg) indokolja. Az aktulis pldnkban nincs ilyen rv, de a jtk kedvrt mutassuk meg ezt az talaktst. A cl az, hogy a hv programmal olyan ekvivalens programot ksztsnk, ahol a ciklusfelttel sznjeles(i) nemmegengedett kifejezse egy l:=sznjeles(i) nem-megengedett rtkadsba kerl t. Ehhez be kell vezetnnk egy j logikai vltozt, s a hv programot az albbi vltozatok valamelyikre kell alaktanunk. i, l := 1, sznjeles(1) l i := i+1 l := sznjeles(i) l: i, l := 0, hamis l i := i+1 l := sznjeles(i) l:

6.3. Plda. Egy iskola n dikot szmll osztlyban m klnbz tantrgybl osztlyoztak a flv vgn. Ezek a jegyek egy tblzat formjban rendelkezsnkre llnak. (A dikokat s a tantrgyakat sorszmukkal azonostjuk.) Igaz-e, hogy minden diknak van legalbb hrom trgybl ngyese? A feladat most egy " minden elem olyan-e, hogy ..." tpus eldnts, ami az optimista lineris keress programozsi ttelre utal. Ebben a keressben is a dikokat kell egyms utn megvizsglni, de most a vizsglat trgya az, hogy van-e legalbb hrom ngyese az illetnek. Ehhez meg kell szmolni minden diknl a ngyes osztlyzatait. Vegyk szre, hogy ezeket a szmllsokat nem kell a feladatot megold optimista lineris keress eltt egy elfeldolgozssal elvgezni, hiszen az optimista keresshez mindig csak az aktulis dik ngyeseinek szma kell, amit ott helyben kiszmolhatunk, majd utna el is felejthetnk. Az gy kapott megolds nemcsak a trigny s futsi id szempontjbl lesz hatkonyabb, hanem a program ellltsa is egyszerbb. Arra van csupn szksgnk, hogy a ngyesek szmt elllt rszfeladatot egy absztrakt fggvny mg rejtsk. Ez a fggvny a tblzat i-edik sora alapjn megadja, hogy az i-edik diknak hny ngyese van. Arra a

115

6. Tbbszrs visszavezets

krdsre, hogy mirt pont erre a fogalomra vezettnk be egy j fggvnyt mirt nem arra, hogy van-e legalbb hrom ngyese az iedik diknak az a vlasz, hogy az ltalunk vlasztott fggvny kiszmolst kzvetlenl visszavezethetjk majd a szmlls programozsi ttelre. A feladat adatai hasonltanak az elz feladatra, ami az llapottr s az elfelttel felrsban tkrzdik: A = (t:nm, l: ) Ef = ( t=t ) A feladat utfelttele a kimen adatkomponenst rja le: az l akkor igaz, ha minden diknak hrom vagy annl tbb ngyese van. Bevezetve a ngyesdb fggvnyt, amelyre a ngyesdb(i) az i-edik dik ngyeseinek szmt adja meg a t tblzat i-edik sora alapjn, az utfelttel az albbi mdon rhat fel: Uf = ( Ef l = i [1..n]: (ngyesdb(i) 3) ) = = ( Ef ahol
l search (ngyesdb(i )
i 1 n

3) )

ngyesdb :[1..m]
m

ngyesdb(i) =

1
j 1 t [i , j ] 4

Ezt a feladatot egy optimista lineris keress oldja meg: m..n ~ 1..n (i) ~ ngyesdb(i) 3

l,i := igaz,1 l i n l := ngyesdb(i) 3 i := i+1

i:

A visszavezetssel ellltott programban az l:=ngyesdb(i) 3 rtkads nem-megengedett. Ha tzetesebben megvizsgljuk az rtkads jobboldaln ll kifejezst, akkor szrevehetjk, hogy annak

116

6.2. Begyazott visszavezets

ngyesdb(i) rszkifejezse a nem-megengedett. Kszthetnk ennek kiszmolsra egy s:=ngyesdb(i) rtkadst megvalstott fggvnyszeren meghvott alprogramot, ahol az s egy darabszmot tartalmaz eredmny-vltoz. (Alternatv megolds, ha a hv programban bevezetnk egy s:N segdvltozt, s az l:=ngyesdb(i) 3 rtkadst az (s:=ngyesdb(i); l:=s 3) szekvencira bontjuk fel, s az s:=ngyesdb(i) alprogramot eljrsszeren hvjuk.) Az s:=ngyesdb(i) rtkads ltal kijellt rszfeladat specifikcija: A = (t:nm, i:, s:) Ef = ( t=t i=i [1..n] ) Uf = ( Ef s = ngyesdb(i) ) = ( Ef
m

s=
j 1 t [i , j ] 4

1)

Ez visszavezethet a szmlls programozsi ttelre. m..n ~ 1..m (i) ~ t[i,j]=4 s:=ngyesdb(i) s := 0 j = 1..m t[i,j]=4 s := s+1 SKIP j:

6.4. Plda. Egy iskola n dikot szmll egyik osztlyban m klnbz tantrgybl adtak jegyeket a flv vgn. Ezek az osztlyzatok egy tblzat formjban llnak rendelkezsnkre. (A dikokat s a tantrgyakat sorszmukkal azonostjuk.) Szmoljuk meg, hny kitn dik van az osztlyban! A szvegbl egyrtelmen kiderl, hogy egy szmllssal lehet a feladatot megoldani. A szmllst a dikok kztt, teht az [ 1..n] intervallum felett vgezzk, s azt a felttelt vizsgljuk, amely megmondja egy dikrl, hogy csupa tse van-e. Ennek a felttelnek a jellsre a korbban mr bevezetett sznjeles logikai fggvnyt hasznljuk.

117

6. Tbbszrs visszavezets

Lssuk a specifikcit! A = (t:nm, s:) Ef = ( t=t )


n

Uf = ( Ef ahol

s=
i 1 sznjeles( i )

1)

sznjeles :[1..n] sznjeles(i) = j [1..m]: t[i,j]=5 A feladatot teht egy szmllsra vezetjk vissza, ahol az intervallum az [1..n], a (i) felttel a sznjeles(i). s:=0 i = 1 .. n sznjeles(i) s := s+1 SKIP i:

A sznjeles(i) nem-megengedett felttel a korbban mr definilt alprogram fggvnyszer hvst jelli. 6.5. Plda. Egy iskola n dikot szmll egyik osztlyban m klnbz tantrgybl osztlyoztak a flv vgn. Ezek a jegyek egy tblzat formjban llnak rendelkezsnkre.(A dikokat s a tantrgyakat sorszmukkal azonostjuk.) Melyik diknak van a legtbb ngyese? Ennl a feladatnl a maximum kivlaszts programozsi ttelt kell hasznlnunk. Mivel egy iskolai osztlyhoz biztos tartoznak dikok, gy a maximum kivlaszts rtelmes. A maximlis rtket most nem kzvetlenl egy intervallum pontjai kzl, hanem az intervallum pontjaihoz (azaz a dikokhoz) rendelt rtkek (egy dik ngyeseinek szma) kzl kell kivlasztani. A feladatban jl krlvonalazdik a 6.3. pldbl mr ismert rszfeladat is, amely egy dik ngyeseinek szmt lltja el.

118

6.2. Begyazott visszavezets

A = (t:nm, ind: ) Ef = ( t=t n>0 m>0 ) Uf = ( Ef ngyesdb(ind) = max ngyesdb (i) )


i 1 n

A feladatot egy maximum kivlasztsra vezetjk vissza, ahol az intervallum az [1..n], s az f(i) kifejezst a ngyesdb(i) helyettesti. max, ind := ngyesdb(1), 1 i = 2 .. n max<ngyesdb(i) max, ind:= ngyesdb(i), i SKIP max: i:

Mivel rendelkeznk az s:=ngyesdb(i) alprogrammal, amelyet specilisan a ngyesdb(1) kiszmolsra is felhasznlhatunk, tulajdonkppen kszen vagyunk: az alprogram fggvnyszer hvsra van szksg. Hatkonysgi okbl azonban clszer a ciklusmagbeli elgazsbl a ngyesdb(i)-t egy rtkadsba kiemelni s az alprogramot eljrsszeren hvni, mert gy az i egy rgztett rtkre nem kell a ngyesdb(i) rtkt esetenknt ktszer is kiszmolni. max, ind := ngyesdb(1), 1 i = 2 .. n s := ngyesdb(i) max<s max,ind := s, i SKIP max: i: s:

6.6. Plda. Egy iskola n dikot szmll egyik osztlyban m klnbz tantrgybl osztlyoztak a flv vgn. Ezek a jegyek egy tblzat formjban llnak rendelkezsnkre.(A dikokat s a tantrgyakat sorszmukkal azonostjuk.) Ki az a dik, aki a csak 4-es illetve 5-s osztlyzat dikok kztt a legjobb tlag? Ha van ilyen, adjuk meg az tlagt is!

119

6. Tbbszrs visszavezets

Ez a feladat egy feltteles maximumkeresssel oldhat meg, hiszen csak az adott tulajdonsg dikok tlagai kztt keressk a legjobbat. Ezen bell nll rszfeladatot alkot annak eldntse, hogy egy dik csak 4-es illetve 5-s osztlyzat-e, illetve nll rszfeladat egy dik tlagnak kiszmolsa is. Az elbbi a feltteles maximum keress felttelt adja, az utbbi a maximumkeressnl hasznlt f fggvnyt. Ezeket a rszfeladatokat egy-egy absztrakt fggvnnyel jelljk ki. Bevezetjk a "csak 4-es illetve 5-s osztlyzat" tulajdonsgot eldnt j logikai fggvnyt, amely az i-edik dik esetn akkor ad igaz rtket, ha a tblzat i-edik sorban csak ngyesek vagy tsk llnak. Bevezetjk tovbb az sszeg fggvnyt, amely megadja az i-edik dik jegyeinek sszegt. Azrt az sszegt, s nem az tlagt, mert a maximum keress eredmnye mindkt esetben ugyanaz a dik. Termszetesen a vgeredmny ellltshoz kln kell majd gondoskodni a legjobb dik tlagnak kiszmolsrl. A = (t:nm, l: , ind:, tl: ) Ef = ( t=t ) Uf = ( Ef ahol j:[1..n] j(i) = j [1..m]: (t[i,j]=5 sszeg:[1..n]
m

l,max,ind = max sszeg (i ) i 1 j(i )

(l

tl=max/m) )

t[i,j]=4)

sszeg(i) =

t [i , j ]
j 1

A feladat az utfelttel alapjn kt rszre bonthat: egy [1..n] intervallum, j(i) felttel s sszeg(i) fggvny feltteles maximumkeressnek, valamint egy elgazsnak a szekvencijra. Az elgazs felttele az l, igaz ga az tl:=max/m rtkads, hamis ga a SKIP lesz.

120

6.2. Begyazott visszavezets

l := hamis i =1 .. n j(i) SKIP l j(i) l j(i) l, max, ind := SKIP igaz, sszeg(i), i max: max<sszeg(i) max, ind := sszeg(i), i l tl := max/m SKIP i:

A j(i) kiszmolshoz az u:=j(i) rtkadst megold alprogramra van szksg, ahol az u egy logikai vltoz. Az u:=j(i) nem-megengedett rtkads egy optimista lineris keresssel helyettesthet, amelyben futindexnek a j-t hasznljuk. Az sszeg(i) meghatrozshoz az ssz:=sszeg(i) rtkadst megold alprogramra van szksg, ahol az ssz egy egszszm vltoz. Az ssz:=sszeg(i) rszfeladat egy sszegzsre vezethet vissza, amelyben futindexnek ugyancsak a j-t hasznljuk, de ez nem ugyanaz a j, mint elbb. u:=j(i) u,j := igaz,1 u j m t[i,j]=4 j: ssz:=sszeg(i) ssz := 0 j = 1..m ssz := ssz +t[i,j] j:

u := t[i,j]=5 j := j+1

A fprogram fenti verzija ezen alprogramok fggvnyszer hvst mutatja, de a hatkonysg rdekben ezeket a hvsokat rdemes egy-egy rtkadsba kiemelni. Az u:=j(i) hvst a ciklusmag hrmas elgazsa eltt kell vgrehajtani, az elgazs feltteleiben pedig az u vltozt hasznlni. Az ssz:=sszeg(i) hvsra a kzps gban tallhat msik elgazs eltt van szksg, amelyben elg az ssz vltozra hivatkozni. Mind az u, mind ssz egy jonnan bevezetett segdvltozja a programnak.

121

6. Tbbszrs visszavezets

l := hamis i =1..n u := j(i) u SKIP l u l u ssz := sszeg(i) max<ssz max, ind := ssz, i l tl:=max/m SKIP SKIP i: u: l, max, ind := ssz,max: igaz, sszeg(i), i

6.7. Plda. Adott egy egsz szmokat tartalmaz vektor, s annak egy k indexe. Igaz-e, hogy van olyan elem a megadott index eltt a vektorban, amelyik nagyobb vagy egyenl az indextl kezdd elemek mindegyiknl! A feladat taln nem tnik tl rdekesnek, de a gyakorls szempontjbl nzve igen hasznos, mert sokfle mdon lehet megoldani. A feladat llapottere, elfelttele knnyen megfogalmazhat: A = (t:n, k:, l: ) Ef = ( v=v k=k 1 k n ) Az utfelttelt azonban szmos ms-ms programot eredmnyez vltozatban lehet felrni. Ezek kzl bemutatunk nhnyat. Az egyes utfelttelekhez tartoz programok megadst az olvasra bzzuk. Az els megolds a feladat szszerinti rtelmezsbl szletik: "Van olyan elem a vektor els rszben, amelyik a vektor hts rsznek mindegyik elemnl nagyobb vagy egyenl." A feladatot teht egy lineris keressbe gyazott optimista keresssel oldhatjuk meg. Ennek specifikcijt lthatjuk itt:

122

6.2. Begyazott visszavezets

Uf = ( Ef

l= i [1..k1]: j [k..n]: v[i] l, i := hamis, 1 l i k1 j: i:

v[j] )

l, j := igaz, k l j n v[j]

l := v[i] i := i + 1

j := j + 1

A megoldsban szerepl kt programozsi ttel egymshoz val viszonya megcserlhet. A feladat gy is megfogalmazhat, hogy igaz e, hogy a vektor hts rsznek minden eleme kisebb, a vektor els rsznek legalbb egy elemnl. Ilyenkor a megolds egy optimista lineris keressbe gyazott lineris keress lenne. Ez rvilgt arra, hogy a kt rszfeladat nincs al- illetve flrendelt viszonyban. Mindkt vltozatnak a futsi ideje (a v[i] s v[j] elemek sszehasonltsainak szma) legrosszabb esetet felttelezve: (k1)*(n k+1). A msodik megolds mr egy kis tletet ignyel: Ha a vektor els rsznek legnagyobb eleme nagyobb vagy egyenl a hts rsz legnagyobb elemnl, akkor van az els rszben olyan elem, amelyik a hts rsz minden elemnl nagyobb vagy egyenl. Nem kell mst tenni, mint a vektor els rszben is, s a hts rszben is kivlasztani a maximlis elemet, s a kapott maximumokat sszehasonltani. Itt teht kt maximum kivlasztsnak, s egy sszehasonltsnak a szekvencijrl van sz. Ez a megolds azonban felttelezi, hogy 2 k n, hiszen csak ekkor lesz a vektor kt szakasza, ahol a maximumot keressk, biztos nem res. Ez azonban nem kvetkezik az eredeti elfelttelbl. Kln kell teht rendelkezni a k=1 esetrl, amikor biztosan hamis a feladatra adand vlasz.

123

6. Tbbszrs visszavezets

Uf = ( Ef

l = k>1

max v[i] max v[ j ] )


i 1
j k

k 1

Az utfelttelbl kiolvashat, hogy ha k 2, akkor a k vizsglatval egytt n+1 sszehasonltst kell vgezni, k=1 esetn csak egyet. k=1 max1 := v[1] i = 2..k1 max1<v[i] max1 := v[i] max2 := v[k] j = k..n max2<v[j] max2 := v[j] l := hamis l := max1 max2 SKIP SKIP max2: j: max1: i:

A harmadik megolds is a maximum kivlasztssal kapcsolatos, de j tleten alapul. Vlasszuk ki a maximlis elemet a vektorbl gy, hogy a maximum kivlaszts tbb maximlis elem esetn a legelsnek az indext adja meg. Ha ez az index a vektor els rszbe esik, akkor igenl vlaszt adhatunk a feladat krdsre. A vektor els rszbe es maximlis elem ugyanis minden elemnl nagyobb vagy egyenl, gy a vektor hts rsznek elemeinl is. Ehhez a megoldshoz csak gy, mint az elzhz pontosan n sszehasonltst kell vgezni. Uf = ( Ef max, ind = max v[i]
i 1 n

l = ind<k )

124

6.2. Begyazott visszavezets

max, ind := v[1], 1 i = 2..n max<v[i] max, ind := v[i], i l := ind < k SKIP

max: ind: i:

A negyedik megolds az eredeti megfogalmazshoz nyl vissza: a vektor els rszben keres alkalmas tulajdonsg elemet. Az alkalmassgot azonban s itt a msodik megolds tlete jelenik meg jra a hts rsz legnagyobb elemvel val sszehasonltssal dntjk el: keresnk az els rszben a hts rsz maximlis elemnl nagyobb vagy egyenl elemet. Az Uf = ( Ef l = i [1..k1]: v[i] max v[ j ] )
j k n

utfelttel azonban gyetlen, mert a lineris keressbe gyazza be a maximum kivlasztst, holott a hts rsz maximum kivlasztsa fggetlen a keresstl az els s hts rsz feldolgozsa nincs alilletve flrendelt viszonyban , ezrt elg, ha a maximum kivlasztst a lineris keress eltt (szekvenciban) egyszer vgezzk el: Uf = ( Ef max = max v[ j ]
j k n

l = i [1..k1]: v[i] max )

max := v[k] i = k+1..n max<v[i] max := v[i] l, i := hamis, 1 l i k1 max SKIP

max: i:

l := v[i]

i := i+1

125

6. Tbbszrs visszavezets

Ebben a megoldsban az sszehasonltsok szma legrosszabb esetben is csak n1 lesz. 6.8. Plda. Adott a skon n darab pont. llaptsuk meg, melyik kt pont esik legtvolabb egymstl! Specifikljuk elszr a feladatot! A skbeli pontokat egy derkszg koordinta rendszerbeli koordinta prokkal adjuk meg; kln-kln tmbkben az x s az y koordintkat. gy az i-edik pont koordinti az x[i] s y[i] lesznek. A feladat kzponti eleme, az i-dik s j-dik pont tvolsga a
( x[i ] x[ j ]) 2 ( y[i ] y[ j ]) 2

kplet alapjn szmolhat, de mivel a pontos tvolsgot nem kri a feladat, a tnyleges tvolsgok helyet azok ngyzeteivel rdemes dolgozni, mert ezek kiszmolshoz nincs szksg gykvonsra. A tv(i,j)-vel az i-dik s j-dik pont tvolsgnak ngyzett fogjuk jellni. Ezeket az rtkeket gondolatban egy nn-es szimmetrikus mtrixba rendezhetjk, s a feladat tulajdonkppen ezen mtrix ftl nlkli alshromszg rszben trtn maximum kivlaszts. A megolds attl nehz, hogy az intervallumra megfogalmazott maximum kivlaszts csak egy dimenzis alakzatba rendezett elemeket tud vizsglni, itt pedig a vizsglt tv(i,j) elemek ktdimenzis alakzatot alkotnak. Ezrt vagy felfzzk gondolatban a vizsglt rtkeket egy egydimenzis tmbbe (vektorba), vagy az alshromszg rsz minden sorban kln-kln meghatrozzuk a maximumot, s ezen sormaximumok kztt egy kln maximum kivlasztssal keressk meg a legnagyobbat. Nzzk meg mindkt megoldst. (A 8. fejezet tmutatsa alapjn egy harmadik megoldst is adhatunk majd erre a problmra, s a 8.5. pldban egy hasonl feladattal tallkozhatunk.) Az els megolds egy maximum kivlasztsba gyazott maximum kivlaszts lesz. A begyazott maximum kivlaszts egy sor maximlis rtkt s annak az indext lltja el, azaz minden sorra egy kt-komponens rtket, a kls maximum kivlasztsnak pedig ilyen kt-komponens rtkeket kell sszehasonltani. Ezrt meg kell hatroznunk azt, hogy egy ilyen kt-komponens rtk mikor nagyobb

126

6.2. Begyazott visszavezets

egy msik kt-komponens rtknl: ha annak els komponense nagyobb a msik els komponensnl. A = (x:n, y:n, ind:, jnd:) Ef = ( x=x y=y n2 ) Uf = ( Ef g:[2..n]
i 1

(max, jnd), ind = max g(i) )


i 2

s
j 1

g(i) = max tv(i,j) s


tv(i,j) ( x[i] x[ j ]) 2 ( y[i] y[ j ]) 2

A feladat visszavezethet a maximum kivlaszts programozsi ttelre (a 2..n intervallumon a g fggvny rtkei felett), ahol a g(i) g(j) akkor teljesl, ha g(i)1 g(j)1. max, jnd, ind := g(2), 2 i = 3 .. n m, k := g(i) m > max max, jnd, ind =m, k, i SKIP max: i: m: k:

Az m, k:=g(i) rszfeladat is a maximum kivlaszts programozsi ttelre vezethet vissza az 1..i-1 intervallumon a tv(i,j) rtkeivel. Ezt a maximum kivlasztst a fprogram kt helyen is meghvja. Ezek kzl az egyik a kezdeti rtkadsban a max s a jnd rtkeit elllt g(2), amelyet fejben is kiszmolhatunk, hiszen a kpzeletbeli mtrix alshromszg rsznek msodik sorban mindssze egyetlen elem van, gy a kezdeti rtkads max, jnd, ind:=tv(2,1), 1, 2 -re mdosul.

127

6. Tbbszrs visszavezets

m, k:=g(i) m, k:=tv(i,1), 1 j = 2 .. i-1 s := tv(i,j) s>m m, k:=s, j SKIP j: s:

A msodik megoldshoz azt kell megvizsglnunk, hogyan lehet egy nn-es ngyzetes mtrix alshromszg rszt egy n(n1)/2 hossz egydimenzis tmbbe kiterteni. Pontosabban azt, hogy ha sorfolytonosan fzzk egyms utn az elemeket (a [2,1]-dik elem lesz az [1] elem, a [3,1]-dik a [2]-dik, a [3,2]-dik a [3]-dik, a [4,1]-dik a [4]dik, stb.), akkor a k-dik elem a mtrix hnyadik sornak hnyadik eleme lesz. Mivel az alshromszg rsz sorai egyre nveked elemszmak, az i-dik sor eltt (i1)(i2)/2 darab elem van, gy a mtrix [i,j]-dik eleme a sorfolytonos kitertsben az (i1)(i2)/2+j-dik elem lesz, ahol j<i. Megfordtva, a sorfolytonos kiterts k-dik eleme a mtrixos elrendezsben azon [i,j]-dik elem, amelyre egyrszt j=2k(i1)(i2), msrszt amennyiben 2k> 2k ( 2k 1) teljesl, akkor i= 2k +1, klnben i = 2k ll fenn.14 Ezutn a feladatot az itt elkpzelt vektor elemeinek maximum kivlasztsaknt specifikljuk.
14

Ez a megfordts bizonytsra szorul. A k=(i1)(i2)/2+j (j<i) miatt (i-1)(i-2)<2ki(i1), amibl (i2)< 2k <i sszefggst kapjuk. Ebbl 2k ltszik, hogy a 2k az (i1) krnyezetbe esik: a (fels egszrsz) vagy i, vagy i1. Ha 2k> 2k ( 2k 1), akkor 2k =i 1, ugyanis az ellenkezjt ( 2k =i) feltve a 2k>i(i1) sszefggst kapnnk, ami ellentmond az els megllaptsnak. Ha viszont 2k 2k ( 2k 1), akkor i= 2k , ugyanis az ellenkezjt ( 2k =i1) feltve a 2k(i1)(i2) sszefggst kapnnk, ami ugyancsak ellentmonds.

128

6.2. Begyazott visszavezets

n ( n 1) / 2

Uf = ( Ef

max, knd =

max
k 1

tv(h(k)) (ind,jnd)=h(knd) )

h:[1..n(n1)/2]
h( k ) ( 2k +1, 2k( 2k ( 2k -1 ) ) ha 2k 2k -2 ) ) ha 2k ( ( 2k -1) 2k -1) 2k 2k

2k , 2k- ( 2k -1)(

Ez a feladat visszavezethet a maximum kivlaszts programozsi ttelre, amelyet az 1..n(n1)/2 intervallumon, a tv h fggvnykompozci rtkeire kell alkalmazni. A kezdeti rtkadsban szerepl tv(h(1)) a tv(2,1)-gyel azonos. max, knd := tv(2,1), 1 k = 2 .. n(n1)/2 tv(h(k))>max max, knd := tv(h(k)), k ind, jnd :=h(knd) 6.3. Program-talaktsok Korbbi feladat-megoldsainkban gyakran alkalmaztunk program-talaktsokat. A program-talakts sorn egy programbl egy olyan msik programot lltunk el, amely megoldja mindazokat a feladatokat, amelyeket az eredeti program is megoldott. Ezt gyakran ekvivalens talaktssal rjk el, azaz gy, hogy az j program hatsa teljesen megegyezik az eredeti program hatsval. Pldaknt emlkeztetnk arra, ahogyan 6.2. pldban a kivlaszts programozsi ttelt ktflekppen is talaktottuk azrt, hogy explicit mdon egy rtkadsba emeljk ki a ciklusfelttelben szerepl nem-megengedett kifejezst. Egy-egy program-talaktsnak a helyessge a programozsi modellnk eszkzeivel belthat, de itt nem foglakozunk a SKIP k:

129

6. Tbbszrs visszavezets

bizonytssal, hanem a lustbb ltszik rajta, hogy j magyarzatot hasznljuk. Egy program-talaktsnak igen sokfle clja lehet. Esetenknt csak szebb, ttekinthetbb formlja a programot, nha az implementci, azaz a konkrt szmtgpes krnyezetbe ltets vgett van r szksg, mskor a program hatkonysgn lehet javtani. Az elbb felsorolt szempontokon kvl klnsen fontosak azok a program-talaktsok, amelyek a program ellltst segtik a programtervezs fzisban. A programtervezst tmogat talaktsok kz sorolhat pldul az, amikor egy j vltoz bevezetsnek segtsgvel emeltnk ki nem megengedett kifejezst (msik rtkads jobboldali kifejezsnek rszt, egy elgazs vagy ciklus felttelt) egy nll rtkadsba, s ezltal kijelltk a programunknak egy olyan rszfeladatt, amelyet aztn megoldottunk. Ugyancsak ilyen talaktsnak tekintjk a rekurzv fggvnyek kibontst is, amelyre a kvetkez alfejezetben mutatunk pldkat. Egy szimultn rtkads egyszer rtkadsok szekvencijra trtn felbontsa is tmogathatja a programtervezst, de tbbnyire egy implementlst tmogat talakts, amennyiben olyan programozsi nyelven kell lernunk a programunkat, amelyik nem ismeri (s tbbnyire nem ismerik) a szimultn rtkadst. Eddig fleg olyan szimultn rtkadsokkal tallkoztunk, amelyet alkot egyszer rtkadsok fggetlenek voltak egymstl, s ebben az esetben az talakts knny volt. Egy egyszer rtkads akkor fgg egy msiktl, ha a jobboldali kifejezsben szerepel egy olyan vltoz, amely a msik rtkads baloldali vltozja. Ha ilyen fggs nem ll fenn a szimultn rtkadst alkot egyszer rtkadsok kztt, akkor azokat tetszleges sorrendben vgrehajtva a szimultn rtkadssal azonos hats szekvencihoz jutunk. Ha van fgg viszony, de ezek rendszere nem alkot krt, azaz a szimultn rtkads egyszer rtkadsainak brmelyik csoportjban lehet tallni olyat, amelyik nem fgg a csoport tbbi egyszer rtkadstl, akkor az egyszer rtkadsokat olyan sorrendben kell vgrehajtani, hogy elre azt az egyszer rtkadst vesszk, amelyiktl senki ms nem fgg, majd mindig azt, amelyiktl csak az eltte vgrehajtottak fggnek. Egy teljesen ltalnos szimultn rtkads felbontshoz azonban amikor a felbontssal kapott

130

6.3. Program-talaktsok

egyszer rtkadsok klcsnsen fggnek egymstl j vltozk bevezetsre van szksg. Az x1, , xn := F1(x1, , xn), , Fn(x1, , xn) rtkads helyett az albbi kt programot hasznlhatjuk: y1:=x1 yn-1:=xn-1 x1:=F1(x1, x2, , xn-1, xn) x2:=F2(y1, x2, , xn-1, xn) xn-1:=Fn-1(y1, y2, , yn-1, xn) xn:=Fn(y1, y2, , yn-1, xn) vagy y1:=x1 yn-1:=xn-1 x1:=F1(y1, y2, , yn-1, xn) x2:=F2(y1, y2, , yn-1, xn) xn-1:=Fn-1(y1, y2, , yn-1, xn) xn:=Fn(y1, y2, , yn-1, xn)

Az implementci egyszerstst tmogatja a szekvencik sorrendjnek megvltoztatsa is. Termszetesen, ha a szekvencia msodik tagja fgg az elstl, akkor erre nincs lehetsg. Programrszek (itt a szekvencik tagjai is) fggetlensgn ugyanazt kell rteni, mint az rtkadsok esetben, ugyanis minden programrsz helyettesthet egy vele ekvivalens tbbnyire nem-megengedett rtkadssal. Program hatkonysgt tmogat talaktsok kz soroljuk a klnfle sszevonsi s kiemelsi szablyokat, a rekurzv fggvny kibontst (lsd kvetkez alfejezet), vagy alkalmas segdvltozk bevezetst tbbszr felhasznlt rtkek trolsra. sszevonsrl pldul akkor beszlhetnk, amikor egymshoz hasonl, de egyms mkdstl fggetlen ciklus szekvencijbl egyetlen ciklust ksztnk gy, hogy az j ciklus magja az eredeti ciklusmagok szekvencija lesz. Az albbi talaktsnl szekvenciacsert is vgeztnk, amikor a ciklusok eltti inicializl

131

6. Tbbszrs visszavezets

programrszeket mind elre hoztuk. Termszetesen ezek sem fgghetnek egymstl. S11 i = m .. n S1 Sk1 i = m..n Sk helyett S11 Sk1 i =m..n S1 Sk

Sok egymst kizr, de az sszes esetet lefed felttel s egyms mkdstl fggetlen ktg elgazsnak a szekvencijbl egyetlen sokg elgazst ksztnk.

felt1 S1 feltk Sk SKIP SKIP helyett

felt1 S1

feltk Sk

A baloldali algoritmusnak nem lehet olyan vgrehajtsa, amikor minden elgazsnak az else ga hajtdik vge, mert a felttelrendszer a feltevsnk szerint teljes. Ha ez nem llna fenn, akkor a jobboldali elgazst ki kell egszteni egy else ggal. Kiemelsi szably alkalmazsra mutat specilis pldt az albbi talakts:

132

6.3. Program-talaktsok

i = 0..10 i=0 S1 S2 helyett

S1 i = 1 .. 10 S2

Az sszevonsokkal illetve kiemelsekkel nemcsak hatkonysgot lehet javtani, hanem a program ttekinthetsgn, olvashatsgn is. Az albbi plda ezt is jl illusztrlja. 6.9. Plda. Soroljuk fel azokat a mkorcsolyz versenyzket, akik holtversenyben az els helyen vgeztek a ktelez gyakorlatuk bemutatsa utn. Az n versenyz programjt egy m tag zsri pontozta, s egy versenyz sszestett pontszmt gy kapjuk, hogy a legjobb s legrosszabb pontot elhagyva a tbbi pontszm tlagt kpezzk. A = (t:nm, s:*) Ef = ( t=t n>0 m>2 )
n

Uf = ( Ef pont:[1..n]

s=
i 1 pont ( i ) max

max = max pont(i) )


i 1

pont(i) = (
i 1

t[i, j ] - max t[i, j ] - min t[i, j ] )/(m2)


j 1 j 1

Az rvnyes sszestett pontszmhoz legalbb hrom pontszm kell, illetve a maximum kivlaszts miatt minimum egy versenyz; ezt tkrzi az elfelttel. Az utfelttelben szerepl szimblumot az sszefzs mveletnek jellsre hasznljuk. Ennek segtsgvel tudunk sorozatokat (itt egy elem sorozatokat) egy sorozatt sszefzni. A maximum kivlaszts szempontjbl a pont(i) kpletben szerepl m2-vel trtn osztsra nincs szksg. Az utfelttelben bevezettnk egy max:R vltozt. Vilgos, hogy elszr ennek az rtkt kell meghatrozni, s csak ezutn tudjuk a kivlogatst elvgezni. A megolds egy maximum kivlaszts, majd egy sszegzs (kivlogats) szekvencija lesz, amelyeken bell a pont(i)-t tbb helyen is hasznljuk. A pont(i) kiszmolshoz egy sszegzsre, egy maximum s egy minimum kivlasztsra van szksgnk.

133

6. Tbbszrs visszavezets

Nzzk meg elszr a megold programot program-talaktsok nlkl. Elszr a fprogramot: max := pont(1) i = 2 .. n d := pont(i) d>max max := d s:= <> i = 1 .. n max = pont(i) s := s <i> d := pont(i) o := 0 j = 1 .. m o := o+t[i,j] maxi := t[i,1] j = 2 .. m t[i,j]>maxi maxi := t[i,j] mini := t[i,1] j = 2 .. m t[i,j]<mini mini := t[i,j] d := (o-maxi-mini)/(m-2) Az gy kapott program azonban javthat. Egyrszt sszevonhatjuk a pont(i)-t kiszmol alprogram hrom programozsi SKIP SKIP mini: maxi: o: j: SKIP SKIP max: i: d:

134

6.3. Program-talaktsok

ttelt egyetlen ciklusba. Ehhez mindssze annyit kell tenni, hogy az sszegzs ciklust is (j=2..m) formjra kell alaktani, amely egy kiemelssel elvgezhet. d := pont(i) o,maxi,mini := t[i,1], t[i,1], t[i,1] j = 2 .. m o := o+t[i,j] t[i,j]>maxi maxi := t[i,j] t[i,j]<mini mini := t[i,j] SKIP o, maxi, mini,: j:

d := (o-maxi-mini)/(m-2) Az eredeti hrom ciklus kezdeti rtkadsait az sszevonssal kapott ciklus elejre emeltk ki. Az ily mdon kzs ciklusmagba kerlt kt elgazs pedig (lvn egymstl fggetlenek, a feltteleik kizrjk egymst, br nem teljesek) egy hrom g elgazsba vonhatk ssze. Msrszt bevezethetjk a versenyzk pontszmait tartalmaz p:n tmbt, amelyet a program elejn feltltnk a pont(i) rtkekkel, gy ksbb mindenhol a pont(i) helyett a p[i]-t hasznlhatjuk. A p tmb feltltse, azaz a i [1..n]:p[i]=pont(i) rszfeladat lnyegben egy p=
n i 1

pont (i)

sszegzs lesz, amelyet a program legelejn kell

elvgezni. Ennek ciklusa ha azt (i=2..n) formjra alaktjuk viszont sszevonhat a max rtkt meghatroz maximum kivlasztssal.

max, p := inicializls

135

6. Tbbszrs visszavezets

p[1] := pont(1) max := p[1] i = 2..n p[i]:=pont(i) p[i]>max max := p[i] SKIP i:

Ezek utn a fprogram az albbi lesz: max, p := inicializls s := <> i = 1 .. n max=p[i] s := s <i> SKIP i: p:n, max:

6.4. Rekurzv fggvny kibontsa A begyazott visszavezetseknl lthattuk, hogy a problmamegolds sorn egy-egy j fggvny bevezetse mennyire jl szolglja egy feladat rszfeladatokra bontst. Az ilyen fggvnyek kitallsa, absztrakcija a visszavezetses technika alkalmazsnak kataliztora. Ebben az alfejezetben olyan szellemes, trkks megoldsokat mutatunk be, amelyekhez gy jutunk, hogy a visszavezets sorn bevezetett absztrakt fggvnyek rekurzv fggvnyek lesznek. A bemutatott megoldsokban azonban ezeknek a rekurzv fggvnyeknek az rtkt nem a rjuk vonatkoz programozsi ttellel szmtjuk ki, hanem egy gyes programtalaktsi technikt alkalmazunk. 6.10. Plda. Kt tblzat (be s ki vektorok) azt mutatja, hogy az i-edik rban hny ltogat rkezett egy mzeumba (be[i]) s hny

136

6.4. Rekurzv fggvny kibontsa

ltogat tvozott (ki[i]) a mzeumbl. Melyik rban (ra vgn) volt a legtbb ltogat a mzeumban? (Feltehetjk, hogy az adatok nem hibsak s kezdetben res volt a mzeum.) Az els ra vgn be[1]-ki[1] ltogat maradt benn a mzeumban. A msodik rban ehhez hozzjtt mg be[2] ltogat, s elment ki[2]; teht a msodik ra vgn be[1]ki[1]+be[2]ki[2] ltogat volt bent. gy tovbb folytatva megkonstrulhatunk egy fggvnyt, amelyik azt mutatja meg, hogy az i-edik ra vgn hny ltogat volt a mzeumban. Ahelyett azonban, hogy ezt a fggvnyt sszegzsknt fogalmaznnk meg, egy rekurzv defincit adunk r: az i-edik ra vgn a mzeumban lev ltogatk szma az i1-edik ra vgn benn levk plusz az i-edik rban rkezk (be[i]), mnusz a tvozk szma (ki[i]). f:[1..n] f(1) = be[1]ki[1] f(i) = f(i1)+be[i]ki[i] i [2..n] A feladat ezek utn az, hogy keressk meg, hol veszi fel ez a fggvny a maximumt. Ennek megfelelen a specifikci: A = (be:n, ki:n, ind:) Ef = ( be=be ki=ki ) Uf = ( Ef f(ind)= max f(i) )
i 1 n

A feladatot visszavezetjk a maximum kivlaszts programozsi ttelre max,ind:=f(1),1 i = 2 .. n max<f(i) max,ind:= f(i), i SKIP max: i:

Ennek ciklusmagjban egy rekurzv fggvny rtkt kell kiszmolni. Ezt azonban hatkonysgi okbl nem egy olyan alprogrammal vgezzk el, amely a rekurzv fggvny helyettestsi rtkt szmoln ki, hanem egy specilis technikt a rekurzv fggvny kibontst alkalmazzuk. Ennek alaptlete az, hogy az f(i) kiszmolshoz az elz itercis lpsben kiszmolt f(i1)-et felhasznlhatjuk, ha azt egy s

137

6. Tbbszrs visszavezets

segdvltozban megjegyezzk, azaz feltesszk, hogy a ciklusfelttel ellenrzsekor lljon fenn az s= f(i1) felttel. Ezt a ciklusba lpskor amikor az s=f(1) felttelt kell belltani az s:=be[1]ki[1] rtkadssal biztosthatjuk, a ciklusmagban pedig elg az s:=f(i) rtkadssal, hiszen az ez utn vgrehajtd i:=i+1 rtkads hatsra jra be fog llni az s=f(i1). Az s:=f(i) rtkadst pedig az f(i) defincija alapjn az s:=s+be[i]ki[i] rtkadssal vltjuk ki. s := be[1]ki[1] max, ind := s, 1 i = 2 .. n s := s+be[i]ki[i] max<s max, ind := s, i SKIP s: max: i:

Ennek a program-talaktsi techniknak elengedhetetlen felttele, hogy a kibontott rekurzv fggvny rtelmezsi tartomnya s az azt tartalmaz ciklus ltal befutott egsz szmok intervalluma egybe essen. St a legjobb az, ha a ciklus indexvltozjnak els rtke (a fenti pldban ez a 2) a rekurzv fggvny bzisa is egyben, hogy a ciklus eltt a rekurzv fggvny kzvetlenl definilt rtkeit kelljen a segdvltoz(k)nak adni, a ciklusmagban pedig a rekurzv kplet alapjn mdostsuk az(oka)t. Ezt biztostand sokszor kis mrtkben mdostani is kell a rekurzv fggvny defincijn. Ha a fenti rekurzv fggvnyt mondjuk egy szmllson bell kellene hasznlnunk (pldul arra vagyunk kvncsiak, hogy hnyszor volt benn a mzeumban tszznl is tbb ltogat), akkor a ciklus az 1..n intervallumot futn be, ezrt a ciklus eltt az f(0) rtkre lenne szksg. Ehhez mdostani kellene a rekurzv fggvny defincijn: ki kellene terjeszteni az rtelmezsi tartomnyt a 0..n intervallumra az f(0) = 0 rtelmezssel, a korbban megadott rekurzv kplet pedig mr az f(1)-re is j, azaz a bzist 1-re mdostjuk. ltalnosan is lerhatjuk a rekurzv fggvny kibontsa sorn vgrehajtott lpseket. Tegyk fel, hogy rendelkeznk egy f fggvny

138

6.4. Rekurzv fggvny kibontsa

rtkeit felhasznl ltalnos algoritmussal programozsi ttelbl szrmazik). S1 i = m .. n S2(f(i))

(amely valamelyik

Az f az mk+1..n intervallumon rtelmezett k-ad rend m bzis rekurzv fggvny (lsd 4.3. alfejezet), az S1 egy tetszleges, az S2 pedig az f(i)-tl fgg program. Lthat, hogy a rekurzv fggvny bzisa a ciklushoz igazodik. Emeljk az f(i) kifejezst egy segdvltozba (ha f tbb komponens, akkor tbb segdvltozba). S1 i = m .. n s1:=f(i) S2(s1) A fenti segdvltozk mell vezessnk be mg annyi segdvltozt, hogy azok szma a rekurzi rendjvel (k) legyen egyenl. (Ha a fggvny tbb komponens, akkor a vltozk szma a komponensszm s a rend szorzata.) Mdostsuk a programot gy, hogy a ciklusfelttel ellenrzsekor az eddig rvnyesl lltsok mellett az s1=f(i1), , sk=f(ik) egyenlsgek is teljesljenek.15 s1, ,sk := f(m-1), , f(m-k)
15

Mindegyik programozsi ttel ciklushoz vlaszthatunk egy invarins lltst (lsd 3.4. alfejezet), amely segtsgvel a ttel s az abbl szrmaztatott programok helyessge is bizonythat. Itt tulajdonkppen ennek az invarinsnak a kiegsztsrl van sz. Ezt kveten gy kell mdostani a programot, hogy annak helyessgt ezzel a bvtett ciklus-invarinssal be lehessen ltni.

139

6. Tbbszrs visszavezets

S1 i = m .. n s1, ,sk := f(i), , f(ik+1) S2(s1) Helyettestsk az f(m-1), , f(m-k) kifejezseket a rekurzv fggvny defincijban rgztett e1, ,ek rtkekkel, az f(i)-t ugyancsak a defincibl szrmaz h(i)-vel, a korbban feltett egyenlsgek miatt pedig az f(i1), , f(ik+1) kifejezseket az s1, ,sk1 vltozkkal. s1, ,sk := e1, ,ek S1 i = m .. n s1, ,sk := h(i, s1, ,sk), s1, ,sk1 S2(s1) 6.11. Plda. Egy replgppel elrepltnk a Csendes cen szigetvilgnak egy rsze felett, s meghatrozott tvolsgonknt megmrtk a felszn tengerszint feletti magassgt. Az gy kapott nemnegatv vals rtkeket egy n hosszsg x vektorban troljuk. Adjuk meg a mrsek alapjn, hogy mekkora a leghosszabb sziget, s a repls hnyadik mrsnl kezddik, illetve vgzdik ezek kzl az egyik. Ennek a feladatnak tbbfle megoldsa is van, amelyek kzl most egy rekurzv fggvnyt bevezet megoldst ismertetnk. Kpzeljk el azt a fggvnyt, amelyik a repls sorn vgzett mrsi pontokon van rtelmezve; sziget felett azt mutatja meg, hogy a sziget kezdete ta hny mrsi pontot tett meg a repl, a tenger felett viszont nulla az rtke.

140

6.4. Rekurzv fggvny kibontsa

f:[0..n] f(0) = 0 f(i) =

f(i 1) 1 ha 0 ha x[i ] x[i ] 0 0

i [1..n]

A feladat megoldshoz elg ennek a fggvnynek megtallni a maximumt. Ahol ez a fggvny a maximlis rtkt felveszi, ott van a leghosszabb sziget vgpontja, amelybl a szigethossznak ismeretben a sziget kezdpontja is knnyen meghatrozhat. (Megjegyezzk, hogy ha a rekurzv fggvnyt nem a vektor elejrl htrafel haladva kpeznnk, hanem a vgrl az eleje fel, akkor egy htulrl elre halad maximum kivlasztssal kzvetlenl a leghosszabb sziget elejt tallnnk meg.) A = (x:n, hossz:, kezd:, vgz: ) Ef = ( x=x ) Uf = ( Ef hossz,vgz = max f (i )
i 1 n

kezd=vgzhossz+1 )

A feladat egy maximum kivlaszts s egy rtkads szekvencijaknt oldhat meg. A nem-megengedett f(i) kifejezseket egy segdvltoz segtsgvel kiemeltk. h := f(1) hossz, ind := h, 1 i = 2 .. n h := f(i) hossz<h hossz, ind := h, i SKIP kezd := vgzhossz+1 Most bontsuk ki a rekurzv fggvnyt. i: h:

141

6. Tbbszrs visszavezets

x[1]>0 h := 1 h := 0 h: i:

hossz, ind := h, 1 i = 2..n x[i]>0 h := h+1 hossz<h hossz, ind := h, i SKIP kezd := vgzhossz+1 Mivel a rekurzv fggvny bzisa 0 s nem 1, ezrt a h:=f(1) rtkadst is a rekurzv kplet alapjn valstottuk meg (ha x[1] pozitv, akkor az f(1) rtke 1 lesz, klnben 0). 6.12. Plda. Egy m hosszsg karakterekbl ll sorozatot (nevezzk ezt szvegnek) kdolni szeretnnk egy msik, n hosszsg karaktersorozat (nevezzk ezt tblzatnak) segtsgvel. A kd egy olyan m hosszsg szigoran nveked szmsorozat legyen, amelyiknek i-edik rtke indexknt mutat a tblzatnak arra a karakterre, amely ppen az eredeti szveg i-edik karaktere. Dntsk el, hogy egy adott szveg s tblzat esetn elkszthet-e egyltaln a szveg kdja! A feladat megoldshoz teht azt kell megvizsglni, hogy a szveg minden karaktere megfelelen kdolhat-e. A = (szveg: m, tbla: n, l: ) Ef = ( szveg=szveg tbla=tbla ) Uf = ( Ef l= i [1..n]: kdolhat(i) ) A szveg i-edik karaktert a tblzat akkor kpes kdolni, ha ez a karakter benne van a tblzatban, mgpedig azon karakter utn, amelyikkel a szveg i1-edik karaktert kdoltuk. Ha teht ismerjk, hogy a tblzat hnyadik karaktervel (jelljk ezt ind-del) kdoltuk a szveg[i1]-et, akkor a tblzatban az ind+1-edik pozcitl elindulva kell megkeresni a szveg[i]-t. Ha tallunk ilyet, akkor a szveg[i] h := 0

142

6.4. Rekurzv fggvny kibontsa

kdolhat s a tallat pozcija majd az j ind, ahonnan a kvetkez keress indul. Az itt krvonalazott lineris keress precz megfogalmazshoz egy rekurzv defincij fggvnyt kell bevezetnnk. Mivel a lineris keressnek kt eredmnye van, a rekurzv fggvny is ktrtk, ktkomponens lesz. Az f(i) els komponense (f1(i)) egy logikai rtk, amely azt mutatja majd meg, hogy sikerlt-e a szveg[i]-t kdolni; a msodik komponens (f2(i)) pedig a tblzat azon indexe, amely eltti pozcin a tblzatban a szveg[i]-t megtalljuk. Ez teht nem a keress megszokott eredmnye (ind), hanem egy eggyel nagyobb rtk. Mindkt rtket az a lineris keress lltja el, amelyik az elz sikeres lineris keress ltal tallt pozcirl (f2(i-1)) indul, s keresi a szveg[i]=tbla[j] felttelnek eleget tev j-t. A rekurzv fggvnyt a nem ltez 0-dik karakterre is definilhatjuk. f :[0..m] f(0)= (igaz, 1) i [1..m]: f(i) = (l, ind+1) ahol (l, ind) = search szveg[i] tbla[ j ]
j f 2(i 1) n

A korbban bevezetett kdolhat(i) felttel teht megegyezik a rekurzv fggvny i-edik helyen felvett logikai rtkvel. Ennek megfelelen a feladat utfelttele: Uf = ( Ef l= i [1..m]: f1(i) ) formban is rhat, amelybl lthat, hogy egy optimista lineris keressbe gyazott rekurzv fggvnnyel oldhat meg a feladat. A megolds sorn a rekurzv fggvnyt termszetesen kibontjuk egy l logikai vltoz s egy j egsz vltoz segtsgvel. A j vltozt egyben az f(i)-t kiszmol lineris keress futindexeknt is hasznlhatjuk, hiszen ennek rtke a keress lellsakor ppen az ind+1 lesz. Ennl fogva az ind vltozt s arra vonatkoz rtkadst elhagyhatjuk a programbl.

143

6. Tbbszrs visszavezets

i, l :=1, igaz l i m l := f1(i)

i:

i, l, j := 1, igaz, 1 l
n j

i,j:

i m

l, j := search szveg[i] tbla[ j ] i := i+1

i := i+1 Az els megolds teht: i, l, j := 1, igaz, 1 l i m l := hamis l j n l := szveg[i]=tbla[j] j := j+1 i := i+1

i,j:

Amennyiben a rekurzv fggvnyre azt is megkveteljk, hogy ha f1(i) valamely i-re hamis, akkor az f2(i) legyen az n+1 (a fenti lineris keress ppen gy mkdik), akkor a rekurzv fggvny els komponense az sszes i-nl nagyobb egszre is hamis lesz. Ezrt az utfelttel az albbi formban is megfogalmazhat: Uf = ( Ef l=f1(m) ) Ez egy rekurzv fggvny adott helyen felvett helyettestsi rtknek kiszmtsnak programozsi ttelre vezethet vissza, amely egy msik megoldst adja a feladatnak. Megjegyezzk, hogy ez a megolds futsi id szempontjbl rosszabb az elznl.

144

6.4. Rekurzv fggvny kibontsa

l, j:= igaz, 1 i = 1 .. m l := hamis l j n l := szveg[i]=tbla[j] j := j+1

j: i:

Keressnk most egy harmadik megoldst! Vezessnk be egy msik f fggvnyt, ahol az f(j) azt mutatja meg, hogy a tblzat els j darab elemvel a szveg legfeljebb hny karaktert lehet kdolni. Ha az f(n) felveszi a szveg hosszt rtkl, akkor ez azt jelenti, hogy a szveg kdolhat a tblzattal. Uf = ( Ef l = (f(n)=m) ) Az f fggvnyt rekurzv mdon definiljuk. A tblzat els nulla darab elemvel egyetlen szvegbeli karaktert sem lehet kdolni, az az f(0)=0. Ha feltesszk, hogy ismerjk azt a szmot (f(j1)), hogy legfeljebb hny karakter kdolhat a tblzat els j1 elemvel, akkor az f(j) rtke attl fgg, hogy a tblzat j-edik elemvel kdolhat-e a szveg soron kvetkez eleme, a szveg[f(j1)+1]. Ha igen, akkor f(j) = f(j1)+1, klnben f(j) = f(j1). f:[0..n] f(0)= 0 j [1..n]: f(j 1) 1 ha f(j 1) m

f(i) f(j 1) klnben

tbla[ j ]

szveg[ f(j 1) 1]

A feladatot az i:=f(n) kiszmolsnak s egy rtkadsnak a szekvencijval lehet megoldani. Az els rszt a rekurzv fggvny helyettestsi rtke kiszmtsnak programozsi ttelre vezetjk vissza.

145

6. Tbbszrs visszavezets

i := 0 j = 1 .. n tbla[j]=szveg[i+1] i := i+1 l := i=m SKIP

i: j:

A hatkonyabb negyedik megoldshoz gy juthatunk, ha szrevesszk azt, hogy nincs mindig szksg a rekurzv fggvny nedik helyen felvett rtknek meghatrozsra, hiszen ha a fggvny korbban felveszi az m-et, akkor az mr a sikeres kdolsnak a jele. Ennek megfelelen az utfelttel: Uf = ( Ef l = j [1..n]: f(j)=m ) Ez a feladat visszavezethet a lineris keress programozsi ttelre, amelyben kibontjuk a rekurzv fggvnyt. l, j := hamis, 1 l j n j: l, j, i := hamis, 1, 0 l j n t[j]=sz[i+1] i := i+1 j := j+1 SKIP i,j:

l := f (j)=m j := j+1

l := i=m

146

6.5. Feladatok

6.5. Feladatok 6.1. Volt-e a lversenyen olyan napunk, amikor gy nyertnk, hogy a megelz k napon mindig vesztettnk? (Oldjuk meg ktflekppen is a feladatot: lineris keressben egy lineris keresssel, illetve lineris keressben egy rekurzv fggvnnyel!) 6.2. Egymst kvet napokon dlben megmrtk a leveg hmrsklett. llaptsuk meg, hogy melyik rtk fordult el leggyakrabban! 6.3. A tornarn nvsor szerint sorba lltottuk a dikokat, s megkrdeztk a testmagassgukat. Hnyadik dikot elzi meg a legtbb nla magasabb? 6.4. llaptsuk meg, hogy egy adott sz (egy karakterlnc) elfordul-e egy adott szvegben (egy msik karakterlncban)! 6.5. Keressk meg a t ngyzetes mtrixnak azt az oszlopt, amelyben a ftlbeli s a feletti elemek sszege a legnagyobb! 6.6. Egy hatrllomson feljegyeztk az tlp utasok tlevlszmt. Melyik tlevlszm utas fordult meg leghamarabb msodszor a hatron? A feladat ktflekppen is rtelmezhet. Vagy azt az utast keressk, akirl legelszr derl ki, hogy korbban mr tlpett a hatron, vagy azt, akinek kt egymst kvet tlpse kzt a lehet legkevesebb msik utast talljuk. 6.7. Egymst kvet htvgeken feljegyeztk, hogy a lversenyen mennyit nyertnk illetve vesztettnk (ez egy eljeles egsz szm). Hnyadik hten fordult el elszr, hogy az sszestett nyeresgnk (az addig nyert illetve vesztett pnzek sszege) negatv volt? 6.8. Dntsk el, hogy egy termszetes szmokat tartalmaz mtrixban! a) van-e olyan sor, amelyben elfordul prm szm (van-e a mtrixban prm szm) b) van-e olyan sor, amelyben minden szm prm c) minden sorban van-e legalbb egy prm d) minden sorban minden szm prm (a mtrix minden eleme prm)

147

6. Modulris programtervezs

6.9. Egy kutya killtson n kategriban m kutya vesz rszt. Minden kutya minden kategriban egy 0 s 10 kztti pontszmot kap. Van-e olyan kategria, ahol a kutyk kztt holtverseny (azonos pontszm) alakult ki? 6.10. Madarak letnek kutatsval foglalkoz szakemberek n klnbz teleplsen m klnbz madrfaj elfordulst tanulmnyozzk. Egy adott idszakban megszmoltk, hogy az egyes teleplsen egy madrfajnak hny egyedvel tallkoztak. Hny teleplsen fordult el mindegyik madrfaj?

148

III. RSZ TPUSKZPONT PROGRAMTERVEZS


Az elz rsz feladataiban s az azokat megold programokban olyan adatokat hasznltunk, amelyeket a legtbb magasszint programozsi nyelvben megtallunk, gy eddig az adatok tervezsre s megvalstsra nem kellett sok energit fordtanunk. Az igazn nehz feladatok adatai azonban nem ilyenek. Ezek az adatok jval sszetettebbek, a rajtuk elvgezhet mveletek bonyolultabbak. Ezen adatok konkrt tulajdonsgaitl az egyszerbb kezels rdekben clszer elvonatkoztatni; helyettk olyan adatokkal dolgozni, amelyeket gy kapunk, hogy a lnyeges tulajdonsgokat kiemeljk a lnyegtelenek kzl, azaz ltalnostjuk azokat. Annak kvetkeztben, hogy az adatok elvonatkoztatnak a feladattl, lehetv vlik a feladatnak egy jobban tlthat, egyszerbb modelljt fellltani, amellyel a feladatot knnyebben fogalmazhatjuk s oldhatjuk meg. Ugyanakkor az gy kapott kitallt adatok tbbnyire elvonatkoztatnak azon programozsi krnyezettl is, ahol majd a megold programnak mkdnie kell. A tervezs sorn ezrt ki kell trni annak vizsglatra, hogyan lehet a kitallt adatainkat a szmtgpen megjelenteni, azaz hogyan lehet az adat rtkeit brzolni (reprezentlni); tovbb azokat a tevkenysgeket (mveleteket), amelyeket az adaton el akarunk vgezni, milyen programokkal lehet kivltani (implementlni). Amikor egy adatot gy jellemznk: azaz megadjuk az rtkeinek reprezentcijt s az adattal vgezhet mveletek implementcijt, akkor az adat tpust adjuk meg. Sokszor elfordul, hogy egy adattpus bevezetsnl elsre nem sikerl olyan reprezentcit s implementcit tallni, amely a konkrt programozsi krnyezetben is lerhat. Ennek nem az gyetlensg az oka, hanem az, hogy elssorban a megoldand feladatra koncentrlunk, s azt vizsgljuk, milyen tpusmveletek segthetik a feladat megoldst. Az ilyen nem-megengedett, gynevezett absztrakt tpust ezrt aztn egy megfelel tpussal kell majd a konkrt programozsi krnyezetben helyettestennk, megvalstanunk. Egy feladat valamely adattpusnak egy-egy tpusmvelete a feladatot megold program rsze lesz. A tpusmveletek bevezetsvel

149

7. Tpus

valjban rszfeladatokat jellnk ki a megoldand feladatban. A tpusmveletek implementlsa az ilyen rszfeladatok megoldst, sszessgben teht a feladat finomtst jelenti. A feladat megoldsa gy kt rszre vlik: egyrszt a bevezetett tpus mveleteinek segtsgvel megfogalmazott megoldsra (fprogramra), msrszt a tpusmveleteket mint rszfeladatokat megold rszprogramokra. A tpusoknak az alkalmazsa teht az eredeti feladatot rszfeladatokra felbont specilis, tpus kzpont feladatfinomtsi technika. A 7. fejezetben az ltalunk hasznlt korszer tpusfogalomnak definilsra kerl sor. Megmutatjuk, hogy mikppen lehet megvalstani egy tervezett tpust. Kitrnk a tpusok kztti kapcsolatok formira, s rszletesen elemezzk a tpus egyik fontos tulajdonsgt, a tpus szerkezett. A 8. fejezetben definiljuk a felsorol fogalmt, amely tbbek kztt az iterlt szerkezet adatok (gyjtemnyek) elemeinek bejrsra is hasznlhat. Definilunk nhny nevezetes iterlt tpust, megmutatjuk, hogyan sorolhatk fel az elemei. Ezutn a programozsi tteleinket ltalnostjuk felsorolkra, azaz felsorolval megadhat elemek sorozatra. Ennek kvetkeztben lnyegesen megn a programozsi tteleinkkel megoldhat feladatok kre, amelyet a 9. fejezetben szmos pldval illusztrlunk majd.

150

7. Tpus
Mr a fenti bevezetbl is ltszik, hogy egy adat tpust tbb nzpontbl lehet szemllni. Amikor arra vagyunk kvncsiak, hogy mire hasznlhatjuk az adatot, azaz melyek a lehetsges rtkei s ezekkel milyen mveleteket lehet vgezni, akkor a tpus fellett, kifel megmutatkoz arct nzzk; ezt szoktk a tpus interfsznek, a tpus specifikcijnak nevezni. Amikor viszont az adat tpusnak egy adott programozsi krnyezetbe val begyazsa a cl, akkor azt vizsgljuk, hogy milyen elemekkel helyettesthetek, brzolhatak a tpusrtkek, illetve melyek azok a programok, amelyek hatsa a tpusmveletekvel azonos annak ellenre, hogy nem kzvetlenl a tpus rtkeivel, hanem az azokat helyettest elemekkel dolgoznak. Ha vesszk a tpusrtkek helyettest elemeit, a helyettests mdjt, azaz a tpusrtkek reprezentcijt (brzolst), valamint a tpusmveleteket kivlt programokat, azaz a tpusmveletek implementcijt, akkor ezeket egytt a tpus megvalstsnak (realizlsnak) nevezzk.16 Egy adat tpusa magba foglalja a tpus-specifikcit s az ennek megfelel, az ezt megvalst tpus-realizcit. A tovbbiakban egy pldn keresztl vezetjk be a korszer tpus fogalmt, majd formlis meghatrozst adunk r (7.1. alfejezet). A programtervezs sorn elbb csak a tpus specifikcijt adjuk meg, s ezutn prblunk egy ehhez illeszked, azt megvalst tpust tallni. Annak feltteleit, hogy egy tpus mikor valst meg egy tpus specifikcit, a 7.2. alfejezetben adjuk meg. A tpus-specifikcit gyakran nem kzvetlenl, hanem kzvetve, egy msik, nmagban nem-megengedett, gynevezett absztrakt tpus segtsgvel rjuk le, ezrt kln kitrnk arra (7.3. alfejezet), amikor egy ilyen absztrakt tpus ltal kijellt tpus-specifikcihoz keresnk azt megvalst tpust. A 7.4. alfejezetben tbbek kztt a tpus szerkezetnek fogalmval foglalkozunk.

16

A mveletek implementcija a reprezentcira pl, ezrt sokszor az implementci fogalmba a reprezentcit is belertik, azaz tpusimplementci alatt a teljes tpus-megvalstsra gondolnak.

151

7. Tpus

7.1. A tpus fogalma Most egy olyan pldt fogunk ltni, amelyik megoldsa sorn pontostjuk a tpus korbban bevezetett fogalmt, s ezltal eljutunk a korszer tpus defincijhoz. 7.1. Plda. Kpzeljk el, hogy olyan rllomst lltanak Fld krli plyra, amelynek az a feladata, hogy adott szm szlelt ismeretlen trgy kzl megszmolja, hny tartzkodik az rlloms kzelben (mondjuk 10000 km-nl kzelebb hozz). A feladat egyik adata az rlloms; a msik az ismeretlen trgyakat tartalmaz sorozat, pontosabban egy tmb; s termszetesen az eredmny. A = (rszonda , UFOn , ) Mindenek eltt vlasszuk el a feladat adataiban a lnyegest a lnyegtelentl. Az r ismeretlen trgyait egy-egy trbeli pontknt szemllhetjk, hiszen mindssze a trben elfoglalt pozcijuk lnyeges a feladat megoldsa szempontjbl. Egy rlloms megannyi tulajdonsga kzl annak pozcija s a vdelmi krzete lnyeges: az rlloms gy helyettesthet egy trbeli gmbbel. Ennek a valsgos feladattl val elvonatkoztatsnak az eredmnye az albbi specifikci. A = (g:Gmb, v:Pontn, s:) Ef = ( g=g' v=v' ) Uf = ( Ef
n

s
i 1 v[i ] g

1)

A feladat megoldhat egy szmlls segtsgvel. A megold programnak az a felttele, hogy vajon benne van-e a v[i] pont a g gmbben, nem megengedett, mert feltesszk, hogy programozsi krnyezetnkben nem ismert sem a gmbnek, sem a pontnak a tpusa. Emeljk ki egy l logikai vltoz segtsgvel a szmlls nemmegengedett felttelt egy l:= v[i ] g rtkadsba, s tekintsk ezt a tovbbiakban egy gmb mveletnek. Egy Gmb tpus adat lehetsges rtkei gmbk, amelyeken most egyetlen mveletet akarunk vgezni: a benne van-e egy pont egy gmbben vizsglatot.

152

7.1. A tpus fogalma

Egy gmb azon pontok halmaza (mrtani helye), amelyeknek egy kitntetett ponttl (a kzpponttl) mrt tvolsga egy megadott rtknl (a sugrnl) kisebb vagy egyenl. Formlisan: Gmb={g 2Pont| van olyan c Pont kzppont s r sugr, hogy brmely p g pontra a tvolsg(c,p) r }.) A tpusmveletet, mint rszfeladatot az albbi mdon specifiklhatjuk: A = (g:Gmb, p:Pont, l: ) Ef = ( g=g' p=p' ) Uf = ( Ef l = p g ) Ezzel krvonalaztuk, ms szval specifikltuk a Gmb tpust. ltalban egy adattpus specifikcijrl (ez a tpus-specifikci) akkor beszlnk, amikor megadjuk az adat ltal felvehet lehetsges rtkek halmazt, a tpusrtk-halmazt, s az ezen rtelmezett tpusmveleteknek, mint feladatoknak a specifikciit. Ezeknek a feladatoknak kzs vonsa, hogy llapotterknek legalbb egyik komponense a megadott tpusrtk-halmaz. A benne van-e egy pont egy gmbben mvelett megoldja az l:=p g rtkads, amely nem-megengedett (vgtelen elem g halmaz esetn ez a rszfeladat nem oldhat meg vges lpsben). Ezrt egy megengedett programmal kell helyettesteni. Ehhez elszr a gmbt kell msknt, nem pontok halmazaknt brzolni, hanem pldul a kzppontjval s a sugarval. Termszetesen egy trbeli pont s egy vals szm nmagban nem egy gmb, de helyettesti, reprezentlja a gmbt. Ezt a reprezentcit Pont matematikai rtelemben egy :Pont 2 fggvny rja le, amely egy c kzpponthoz s egy r sugrhoz az annak megfelel gmbt Pont rendeli. Formlisan: (c,r) = {q Pont | tvolsg(c,q) r } 2 . Ez a fggvny negatv sugrra is rtelmes, de clszer volna a negatv sugar gmbket kizrni a vizsglatainkbl. Ezt megtehetjk gy, hogy megszortst adunk a gmbket helyettest (c,r) Pont R prokra: r 0. Ezt a megszortst a tpus invarins lltsnak hvjk. Ez formlisan egy I:Pont logikai fggvny, ahol I(c,r) = r 0. A tpus invarinsa leszkti a reprezentcis fggvny rtelmezsi tartomnyt. A gmbk itt bemutatott reprezentcija azrt elnys, mert a benne van-e egy pont egy gmbben tpusmvelet gy mr

153

7. Tpus

visszavezethet kt pont tvolsgnak kiszmolsra, hiszen az l:=p g rtkads kivlthat az l:=tvolsg(c,p) r rtkadssal. Hangslyozzuk, hogy a kt rtkads nem azonos hats, hiszen hogy mst ne mondjunk eltr az llapotterk: az els a (Gmb, Pont, ) a msodik a (Pont, , Pont, ). A msodik rtkads llapotterben nem szerepel a gmb, hiszen ott azt egy pont s egy vals szm helyettesti. Mgis a msodik rtkads abban az rtelemben megoldja az els rtkads ltal megfogalmazott feladatot, amilyen rtelemben egy gmb reprezentlhat a kzppontjval s a sugarval. Ms szavakkal gy mondjuk, hogy az l:=tvolsg(c,p) r rtkads a reprezentci rtelmben megoldja, azaz implementlja az l:=p g mveletet. Az l:=tvolsg(c,p) r rtkads kzvetlenl az albbi feladatot oldja meg A = (c:Pont, r: , p:Pont, l: ) Ef = ( c=c' r=r' p=p' ) Uf = (Ef l = tvolsg(c,p) r) de kzvetve, a reprezentci rtelmben megoldja az eredeti feladatot is: A = (g:Gmb, p:Pont, l: ) Ef = ( g=g' p=p' ) Uf = ( Ef l = p g ) Ezzel el is rkeztnk a korszer tpusfogalom defincijhoz. Egy adat tpusn azt rtjk, amikor megadjuk, hogy az adat ltal felvehet lehetsges rtkeket hogyan brzoljuk (reprezentljuk), azaz milyen elemmel (rtkkel vagy rtkcsoporttal) helyettestjk, tovbb lerjuk a tpus mveleteit implementl programokat, amelyek kzs vonsa, hogy llapotterkben komponensknt szerepel a reprezentl elemek halmaza. A tpusrtkeket helyettest (brzol) reprezentns elemeket gyakran egy bvebb halmazzal s egy azon rtelmezett logikai lltssal, a tpus invarinsval jelljk ki: ekkor az lltst kielgt elemek a reprezentns elemek. A reprezentci tbb, mint a reprezentns elemek halmaza: a reprezentns elemek s a tpus-rtkek kapcsolatt is lerja. Ez teht egy lekpezs, amely gyakran egy tpusrtkhez tbb helyettest elemet is megad, st ritkn elfordul, hogy klnbz tpusrtket ugyanazon reprezentns elemmel helyettesti. A Gmb tpuslersa sokkal rnyaltabban s rszletesebben mutatja be a gmbket, mint a Gmb korbban megadott tpus-

154

7.1. A tpus fogalma

specifikcija. Igaz, hogy a tpuslersban explicit mdon csak a gmbk brzolsrl (reprezentcijrl) s egy erre az brzolsra tmaszkod mvelet programjrl (l:=tvolsg(c,p) r) esik sz, de ez implicit mdon definilja a gmbk halmazt (a tpusrtk-halmazt) s az azokon rtelmezett (benne van-e egy pont a gmbben) tpusmveletet is. ltalban is igaz, hogy ha ismerjk a tpus-invarinst s a reprezentcis lekpezst, akkor a tpus-invarins ltal kijellt elemekhez ez a lekpezs hozzrendeli a tpusrtkeket, gy megkapjuk a tpusrtk-halmazt. A tpusmvelet programjbl pedig (mint minden programbl) kiolvashat az a feladat, amit a program megold, s ha ebben a feladatban a reprezentns elemek helyre az azok ltal kpviselt tpusrtkeket kpzeljk, akkor megkapjuk a tpusmvelet feladatt. gy elll a tpus-specifikci. Ezt a jelensget gy nevezzk, hogy a tpus kijelli nmaga specifikcijt. Sajnos a Gmb tpus mveletnek programja nem megengedett, hiszen kt trbeli pont tvolsgnak (tvolsg(c,p)) kiszmtsa sem az. Ezrt ki kell dolgoznunk a Pont tpust, amelynek mvelete a d:=tvolsg(c,p) rtkads lesz. A Pont tpus rtkei a trbeli pontok, amelyek pldul egy hromdimenzis derkszg koordinta-rendszerben (ennek az origja tetszleges rgztett pont lehet) kpzelhetek el, s ilyenkor azok a koordintikkal helyettesthetk. ( : Pont) Hangslyozzuk, hogy hrom vals szm nem azonos egy trbeli ponttal, de egy rgztett koordinta-rendszerben egyrtelmen reprezentljk azt. Mivel brmilyen koordinta-hrmas egy trbeli pontot helyettest, ezrt a tpus invarinsval (I: ) nem kell megszortst tennnk, az invarins teht az azonosan igaz llts. Ebben a reprezentciban kt pont tvolsgt az euklideszi kplet segtsgvel szmolhatjuk ki. A kplet alapjn felrt rtkads megoldja, implementlja a kt pont tvolsgt meghatroz rszfeladatot annak ellenre, hogy a mvelet llapotterben pontok, az azt megold program llapotterben pedig vals szmok szerepelnek. Mivel a kplet vals szmokkal s a vals szmok mveleteivel dolgozik, rtke mr egy megengedett programmal kiszmolhat.

155

7. Tpus

A = (p.x:, p.y:, p.z:, q.x:, q.y:, q.z:, d:)


d: ( p.x q.x) 2 ( p. y q. y ) 2 ( p.z q.z ) 2

Felhasznlva a Gmb s a Pont tpus defincijt visszatrhetnk az eredeti feladat megoldsnak elejn emltett szmllshoz, s az abban szerepl l:=v[i] g rtkadst az l:= (v[i ]. x
g.c.x) 2 (v[i]. y g.c. y ) 2 (v[i ]. z g.c.z ) 2 g.r

programmal helyettesthetjk. Ebben a v[i].x a v[i] pont x koordintjt, v[i].y az y koordintjt s v[i].z a z koordintjt jelli, tovbb a g.c a g gmb kzppontja, g.r pedig a sugara. Az eredmnyl kapott program llapottere nem egyezik meg a feladat llapottervel: az eredeti llapottr gmbje s pontjai helyett a megold program vals szmokkal dolgozik. Mgis, ez a program nyilvnvalan megoldja a feladatot, mg ha ezt nem is a megolds korbban megadott defincijnak rtelmben teszi. A feladat megoldsban tetten rhet az adatabsztrakcis programozsi szemlletmd, amely az adattpust lltja kzppontba. Els lpsknt elvonatkoztattuk a feladatot az rszondk s trgyak vilgbl a trbeli gmbk s pontok vilgba. Itt megtalltuk a feladat megoldsnak kulcst, azt a rszfeladatot, amelyik el tudja dnteni, hogy egy pont benne van-e egy gmbben. Ezt felhasznlva mr elkszthettk az eredeti feladatot megold szmllst. Egyetlen, br nem elhanyagolhat problma maradt csak htra: a megolds kulcsnak nevezett rszfeladatot, mint a Gmb tpus egy mvelett, kellett megoldani. Ehhez azonban nem az absztrakt gmbket tartalmaz eredeti llapottren kerestnk megold programot, hanem ott, ahol a gmbt a kzppontjval s sugarval helyettestettk. Ms szavakkal, a Gmb tpust meg kellett valstani: elszr reprezentltuk a gmbket, majd a reprezentns elemek segtsgvel jrafogalmaztuk a rszfeladatot. Az jrafogalmazott rszfeladat megoldshoz jabb adatabsztrakcit alkalmaztunk: bevezettk a Pont tpust, amelyhez a kt pont tvolsgnak rszfeladatt rendeltk tpusmveletknt. Vgeredmnyben egy ismert tpus, a vals szmok tpusnak segtsgvel reprezentltuk a pontokat s a gmbket, a mveleteket megold programok pedig ugyancsak a vals szmok megengedett krnyezetben mkdnek. Az adatabsztrakci alkalmazsa intucit s sok gyakorlst ignyel. Hogy mst ne emltsnk, pldul nehezen magyarzhat meg

156

7.1. A tpus fogalma

az, honnan lttuk az elz pldban mr a megolds elejn, hogy a "benne van-e a pont a gmbben" mveletet a Gmb tpushoz s nem a Pont tpushoz kell rendelni. Ez a dnts alapveten meghatrozta a megolds irnyt: elszr a Gmb tpussal s utna a Pont tpussal kellett foglalkozni; de kijellte azt is, hogy a Gmb tpus reprezentlshoz felhasznljuk a Pont tpust. 7.2. Tpus-specifikcit megvalst tpus Ha van egy tpus-specifikcink s kln egy tpusunk, akkor joggal vetdik fel az a krds, vajon a tpus megfelel-e az adott tpusspecifikcinak: megvalstja-e a tpus-specifikcit. Ezt vizsglhatnnk gy is, hogy sszehasonltjuk a vizsglt tpusspecifikcit a tpus ltal kijellt tpus-specifikcival, de kzvetlenl gy is, hogy megvizsgljuk vajon a tpus reprezentns elemei megfelelen helyettesthetik-e a tpus-specifikci tpusrtkeit, s hogy a tpus programjai rendre megoldjk-e a tpus-specifikci feladatait (termszetesen gy rtve, hogy a programok a tpusrtkek helyett azok reprezentns elemeivel szmolnak.) Annak, hogy a tpus megvalstson egy tpus-specifikcit kt kritriuma van. Egyrszt minden tpusrtk helyettesthet kell legyen reprezentns elemmel, s minden reprezentns elemhez tartoznia kell tpusrtknek. Msrszt a tpus-specifikci minden feladatt a tpus valamelyik programja a reprezentci (alapjn) rtelmben megoldja (implementlja). Egy tpus-specifikcihoz tbb azt megvalst tpus is tartozhat. Pldul a Gmb tpus-specifikcijt nemcsak az elz alfejezetben bemutatott tpus valstja meg, hanem az is, ahol a gmbket kzvetlenl ngy vals szmmal reprezentljuk; az els hrom a kzppont koordintit, az utols a sugart adn meg. Ilyenkor nincs szksg a Pont tpusra, az l:=p g feladatot pedig kzvetlenl egy vals szmokkal felrt programmal kell implementlni. A Pont tpust is lehetne msknt, pldul polr koordintkkal reprezentlni, de ekkor termszetesen ms programot ignyel kt pont tvolsgnak kiszmtsa. Nzznk most egy olyan feladatot, amelynek megoldshoz gy vezetnk be egy j tpust, hogy elszr a specifikcijt adjuk meg, majd ehhez keresnk azt megvalst tpust.

157

7. Tpus

7.2. Plda. Adott egy n hosszsg 1 s 100 kz es egsz szmokat tartalmaz tmb. Szmoljuk meg, hogy ez a tmb hny klnbz szmot tartalmaz! A feladatot szmllsra vezetjk vissza. A tmb egy elemnl akkor kell szmolni, ha az mg nem fordult el korbban. Ezt egy lineris keresssel is eldnthetnnk, de ez nem lenne tl j hatkonysg megolds, hiszen a tmbt jra s jra vgig kellene vizsglni. Radsul ilyenkor azt sem hasznlnnk ki, hogy a tmb elemei 1 s 100 kz esnek. Szmolhatnnk az 1 s 100 kz es egsz szmokra, hogy melyik szerepel a tmbben, de hatkonysg szempontjbl ez sem lenne lnyegesen jobb az elznl (hossz tmbk esetn egy kicsit jobb) hiszen a szmlls felttelnek eldntse itt is lineris keresst ignyel. Harmadik megolds az, ha elszr ellltunk egy a tmb elemeibl kpzett halmazt, s megnzzk, hogy ez a halmaz hny elem. (Ebben a megoldsban a szmlls programozsi ttele meg sem jelenik.) A = (a:n, s:) Ef = ( a=a ) Uf = ( Ef
s

{a[i]}
i 1

A specifikci szerint a megoldshoz egy halmazra, pontosabban egy halmaz tpus adatra van szksgnk. Ebbe elszr sorban egyms utn bele kell rakni a tmb elemeit, majd le kell krdezni az elemeinek szmt. A megold program ezrt egy szekvencia lesz, amelynek els fele (az unizs) az sszegzs programozsi ttelre vezethet vissza, a msodik fele pedig a halmaz tpus elemszm mveletre pl: m..n ~ 1..n s ~ h f(i) ~ {a[i]} +,0 ~ , h := i = 1 .. n h := h {a[i]} s := h

158

7.2. Tpus-specifikcit megvalst tpus

A halmaztpus egy tpusrtke egy olyan halmaz, amely elemei 1 s 100 kztti egsz szmok. Megengedett mvelet egy halmazt ress tenni, egy elemet hozz unizni, s az elemeinek a szmt lekrdezni. A halmaztpus tpus-specifikcijt formlisan az albbi (rtkhalmaz, mveletek) formban rhatjuk le: (2 ,{h:= , h:=h {e}, s:= h }). Keressnk egy olyan konkrt tpust, amely megvalstja ezt a tpus-specifikcit. Reprezentljunk pldul egy 1 s 100 kz es szmokbl ll halmazt 100 logikai rtket tartalmaz tmbbel.
{1..100}

h= 2
1

6 5
2. 3.

4.

5.

6.

7.

8.

9.

100.

v= hamis igaz hamis hamis igaz igaz hamis igaz hamis . . . hamis
db=4 7.1. bra Egy halmaz s azt reprezentl logikai tmb

A logikai tmbben az e-edik elem akkor s csak akkor legyen igaz rtk, ha a tmb ltal reprezentlt halmaz tartalmazza az e-t. Vegyk mg hozz ehhez a tmbhz kln azt az rtket, amely mindig azt mutatja, hogy hny igaz rtk van a tmbben (ez ppen a reprezentlt halmaz elemszma). Ez a kapcsolat a logikai tmb s e darabszm kztt a tpus-invarins. Itt a reprezentcis fggvny egy (logikai tmb, darabszm) prhoz rendeli azon egsz szmoknak a halmazt, amely a logikai tmb azon indexeit tartalmazza, ahol a tmbben igaz rtket trolunk. Nyilvnval, hogy minden (tmb, darabszm) pr klcsnsen egyrtelmen reprezentl egy halmazt. Trjnk most r a tpusmveletek implementlsra. Az egyes mveleteket elszr tfogalmazzuk gy, hogy azok ne kzvetlenl a halmazra, hanem a halmazt reprezentl tmb-darabszm prra legyenek megfogalmazva. Pldul a h:= feladatnak az a feladat

159

7. Tpus

feleltethet meg, hogy tltsk fel a logikai tmbt hamis rtkekkel s nullzzuk le a darabszmot. Formlisan felrva az eredeti s a reprezentcira tfogalmazott feladatot: A = (v: , db:) Ef = ( (v,db)= (v',db')) = = (v=v' db=db') Uf = ( h= ) Uf = ( (v,db)= ) = = ( i [1..100]:v[i]=hamis db=0 ) Az tfogalmazott feladat el- s utfelttelt ktflekppen is felrtuk. Az els alak mechanikusan ll el az eredeti specifikcibl: a halmazt a tmb s a darabszm helyettesti. A msodik alaknl mr figyelembe vettk a reprezentci sajtossgait. Knny beltni, hogy az talaktott feladatot az albbi program megoldja: A =(h:2 Ef = ( h=h' ) ) h := db := 0 i = 1 .. 100 v[i] := hamis Ez a program br kzvetlenl nem halmazzal dolgozik, mgis abban az rtelemben megoldja a h:= feladatot, amilyen rtelemben egy halmazt egy logikai tmb s egy darabszm reprezentl. Ezt a fenti kt specifikci kztti kapcsolat szavatolja. A msik kt mvelet esetben nem lesznk ennyire akkurtusak. (Meglep mdon ezek a mveletek jval egyszerbbek a fentinl, megvalstsuk nem ignyel ciklust.) Knny beltni, hogy a h:=h {e} rtkadst a v[e]:=igaz rtkads vltja ki, hiszen amikor egy halmazba betesszk az e szmot, akkor a halmazt reprezentl tmb e-edik elemt igaz-ra lltjuk. A tpus-invarins fenntartsa rdekben azonban azt is meg kell nzni, hogy az e elem a halmaz szempontjbl j-e, azaz v[e] hamis volt-e. Ha igen, akkor a reprezentcit kpez darabszmot is meg kell nvelni. A megolds egy elgazs.
{1..100} 100

160

7.2. Tpus-specifikcit megvalst tpus

tpusrtkek tpusspecifikci betesz 2


{1..100}

tpusmveletek h:=h {e} legyen res h := elemszma s:= h

1 s 100 kz es egsz szmokat tartalmaz halmazok

100

2
100 i 1

{1..100}

(v,db) = v[i]
100

I(v,db) =( db=

1)
i 1 v[i ]

v: 100, db:, e: , l: , s: betesz

tpus megvalsts
100

v[e]=hamis v[e]:=igaz db:=db+1 SKIP

logikai tmb s egy szm

legyen res db := 0 i [1..100]: v[i]:=hamis elemszma s:=db


7.2. bra Halmaz tpusa

161

7. Tpus

h:=h {e} v[e]=hamis v[e] := igaz db := db+1 SKIP

Ha a db-t nem vettk volna hozz a reprezentcihoz, akkor az s:= h rtkadst egy szmllssal oldhatnnk meg. gy azonban elg helyette az s:=db rtkads. s:= h s := db A 7.2 brn sszefoglaltuk a halmaz tpus specifikcijval s megvalstsval kapcsolatos megjegyzseinket. A tpusspecifikciban a mveletek feladatait rtkadsok formjban adtuk meg, a mveletek llapottere pedig kitallhat az rtkads vltozinak tpusbl. A tpus lersban rvidtett formban szerepel a legyen res mvelet programja. 7.3. Absztrakt tpus Adatabsztrakcin azt a programtervezsi technikt rjk, amikor egy feladat megoldsa sorn olyan adatot vezetnk be, amely tbb szempontbl is elvonatkoztat a valsgtl. Egyrszt elvonatkoztathat a feladattl, ha annak eredeti megfogalmazsban kzvetlenl nem szerepel; csak a megolds rdekben jelenik meg. Msrszt elvonatkoztathat a konkrt programozsi krnyezettl, ahol majd az adat tpust le kell rni. Ezt a tpust nevezzk absztrakt tpusnak. Absztrakt tpus lehet egy tpus-specifikcit, de egy olyan tpus is,amelynek a reprezentcija s implementcija nem hatkony (ezrt nem fogjuk ebben a formban alkalmazni) vagy nem-megengedett (lsd a megengedettsg 3. fejezetben bevezetett fogalmt) vagy hinyos (mert pldul nem ismert a mveleteinek programja, csak azok hatsa, vagy

162

7.3. Absztrakt tpus

mg az sem).17. Egy absztrakt tpustl mindssze azt vrjuk, hogy vilgosan megmutassa az ltala jellemzett adat lehetsges rtkeit s azokon vgezhet mveleteket, teht az egyetlen szerepe az, hogy kijelljn egy tpus-specifikcit Ha ennek definilshoz nincs szksg reprezentcira, akkor a tpus-specifikcit kzvetlen18 mdon adjuk meg, de ez a programozsi gyakorlatban viszonylag ritka. Sokszor ugyanis nem tudjuk nmagban definilni a tpusrtk-halmazt (gy mint a gmbk vagy az 1 s 100 kztti elemekbl kpzett halmazok esetben tettk), csak annak egy reprezentcijval (pldaknt gondoljunk a pont fogalmra, amelyet mindannyian jl rtnk, de definilni nem lehet, csak valamilyen koordinta rendszer segtsgvel megadni). ltalban a tpusmveletek viselkedst is szemlletesebben lehet elmagyarzni, ha azok nem elvonatkoztatott tpusrtkekkel, hanem megfoghat reprezentns elemekkel dolgoznak. A benne van-e egy pont a gmbben mvelet sokak szmra rthetbb, ha nem halmazelmleti alapon (benne van -e a pont a gmbt alkot pontok halmazban), hanem geometriai szemllettel (a pontnak a gmb kzppontjtl mrt tvolsga kisebb, mint a gmb sugara) magyarzzuk el. Ezrt gyakoribb (lsd ksbb 7.3, 7.4. pldkat) az, amikor egy tpus-specifikcit kzvetett mdon runk fel: adunk egy tpust, ami kijelli a tpus-specifikcit. Ha ez a tpus csak a tpus-specifikci kijellsre szolgl, akkor tnyleg nem fontos, hogy megengedett legyen, st az sem baj, ha hinyos. Az ilyen absztrakt tpus csak abbl a szempontbl rdekes, hogy segti-e megrtetni a kijellt tpus-specifikcit, s nem szmt, milyen gyesen tudja reprezentlni a tpusrtkeket vagy mennyire hatkonyan implementlni az azokon rtelmezett mveleteket.

17

Ez magyarzza, hogy mirt hasznljk sokszor az absztrakt tpus elnevezst magra a tpus-specifikcira. Knyvnkben azonban az absztrakt tpus tgabb fogalom, mint egy tpus-specifikci, hiszen tartalmazhat olyan elemeket is (pldul reprezentci vagy tpusmvelet hatsa, esetleg a rszletes programja), amelyek nem rszei a tpus-specifikcinak. 18 Egy tpus-specifikcit nemcsak a knyvnkben alkalmazott, gynevezett el- utfeltteles mdszerrel adhatunk meg kzvetlen mdon. Ms lersok is lteznek, ilyen pldul az gynevezett algebrai specifikci is. Ezek trgyalsval itt nem foglalkozunk.

163

7. Tpus

Ha egy feladat megoldsnl absztrakt tpust alkalmazunk, akkor ksbb ezt olyan megengedett tpussal (konkrt tpussal) kell kivltanunk, amely megvalstja az absztrakt tpus ltal kijellt specifikcit, rviden fogalmazva megvalstja az absztrakt tpust. Ha az absztrakt tpus nemcsak egy tpus-specifikcibl ll, hanem rendelkezik reprezentcival s a tpusmveleteket implementl programokkal, vagy legalbb azok hatsainak lersval, akkor az absztrakt tpust kivlt konkrt tpust gy is elkszthetjk, hogy kzvetlenl az absztrakt tpus elemeit (a reprezentcit s a programokat) valstjuk meg. Ha a reprezentci nem-megengedett vagy csak nem hatkony, akkor a reprezentns elemeket prbljuk meg helyettesteni ms konkrt elemekkel, azaz a reprezentcit reprezentljuk. Ha a tpusmveleteket megvalst programok nem megengedettek, akkor ezeket (s nem az eredeti tpusmveleteket) az j reprezentci alapjn implementljuk. Knny beltni, hogy az gy kapott konkrt tpus megvalstja az absztrakt tpus ltal lert tpusspecifikcit is. Most mutatunk nhny, az itt vzolt folyamatot illusztrl gynevezett adatabsztrakcis feladat-megoldst. A feladatok megoldsa sorn olyan absztrakt tpusokat vezetnk be, amelyek mveletei tmogatjk a feladat megoldst, annak ellenre, hogy a feladat eredeti megfogalmazsban semmi sem utal ezen adattpusok jelenltre. Ezek a feladat szempontjbl elvonatkoztatott tpusok, ugyanakkor a programozsi krnyezet szmra is absztraktak. Emiatt gondoskodni kell a megvalstsukrl is, azaz az absztrakt tpusokat az ket megvalst konkrt tpusokkal kell helyettesteni. 7.3. Plda. Adott egy n hosszsg legfeljebb 100 klnbz egsz szmot tartalmaz tmb. Melyik a tmbnek a leggyakrabban elfordul eleme! A feladat megoldhat egy maximum kivlasztsba gyazott szmllssal, ahol minden tmbelemre megszmoljuk, hogy hnyszor fordult addig el, s ezen elforduls szmok maximumt keressk. A 7.2. plda nyomn azonban itt is bevezethetnk egy halmazszer objektumot azzal a kiegsztssel, hogy amikor egy elemet ismtelten beletesznk, akkor jegyezzk fel ennek az elemnek a halmazban val elfordulsi szmt (multiplicitst). Ezt a multiplicitsos halmazt zsknak szoktk nevezni. Miutn betettk ebbe a zskba a tmb sszes

164

7.3. Absztrakt tpus

elemt, akkor mr csak arra van szksg, hogy megnevezzk a legnagyobb elforduls szm elemt. Specifikljuk a feladatot! A = (t:{1..100 n, b:Zsk, e:{1..100}) Ef = ( t = t n1 ) Uf = ( Ef
b

{t[i]}
i 1

e = MAX(b) )

A specifikciban hasznlt uni s maximum szmts a zsk specilis mveletei lesznek. A feladat egy sszegzsre vezethet vissza, amit a zsk maximlis gyakorisg elemnek kivlasztsa kvet: m..n ~ 1..n s ~ b f(i) ~ {t[i]} +,0 ~ ,

b := i = 1 .. n b := b {t[i]} e := MAX(b) A zsktpust absztrakt tpussal definiljuk. Egy szmokat tartalmaz zsk ugyanis legegyszerbben gy foghat fel, mint szmprok halmaza, ahol a szmpr els komponense a zskba betett elemet, msodik komponense ennek az elemnek az elfordulsi szmt tartalmazza. Reprezentljuk teht klcsnsen egyrtelm mdon egy {1..100} zskot a 2 hatvnyhalmaz egy (szmprokat tartalmaz) halmazval. Vlasszuk a tpus invarinsnak azt az lltst, amely csak azokra a szmprokat tartalmaz halmazokra teljesl, amelyekben brmelyik kt szmpr els komponense klnbz, azaz ugyanazon elem 1 s 100 kztti szm nem szerepelhet ktszer, akr kt klnbz elforduls szmmal a halmazban. A zsktpus mveletei: a legyen res egy zsk (b:= ), a tegynk bele egy szmot egy zskba (b:=b {e}), vlasszuk ki a zsk leggyakoribb elemt

165

7. Tpus

(e:=MAX(b)), ahol b egy zsk tpus, az e egy 1 s 100 kztti szm tpus rtket jell. A mveletek kzl az mvelet nem a szoksos halmazmvelet, ezrt ennek kln is felrjuk a specifikcijt.
A= (b:2 , e:) Ef = ( b=b' e=e ) Uf = ( e=e (e,db) b (b=b{(e,db)} {(e,db+1)}) (e,db) b (b=b {(e,1)}) ) Ezzel a zsk absztrakt tpust megadtuk, kijelltnk a zsk tpusspecifikcijt. Valstsuk most meg az absztrakt zsktpust! Egy zskot helyettest szmprok halmaza lerhat egy 100 elem termszetes szmokat tartalmaz tmbbel (v), ahol a v[e] azt mutatja, hogy az e szm hnyszor van benne a zskban. Ha v[e] nulla, akkor az e szm mg nincs benne. Vegyk szre, hogy nem kzvetlenl a zskot prbltuk meg mskpp reprezentlni, hanem a zskot az absztrakt tpus ltal megadott korbbi reprezentcijt. Ezt a ktlpcss megvalstst alkalmazzuk a mveletek {1..100} implementlsnl is. A 2 -beli halmazokra megfogalmazott mveleteket prbljuk megvalstani, s ezzel kzvetve az eredeti, a zskokon megfogalmazott mveleteket is implementljuk. A zskot reprezentl halmaz akkor res, ha minden 1 s 100 kztti szm egyszer sem (nullaszor) fordul benne el, azaz a b:= rtkadst a e [1..100]: v[e]:=0 rtkads-sorozattal helyettesthetjk. A b:=b {e} mvelet implementlsa mg egyszerbb: nem kell mst tenni, mint az e elem elforduls szmt megnvelni, azaz v[e]:=v[e]+1. A legnagyobb elforduls szm elemet a reprezentns v tmbre alkalmazott maximum kivlaszts hatrozza meg. Megjegyezzk, hogy ez mg akkor is visszaad egy elemet, ha a zsk res, mert ilyenkor minden elem nulla elforduls szmmal szerepel a tmbben. A megoldsban jl elklnl a tpus megvalsts hrom szintje (7.3. bra). Legfell van a zsk fogalma, amit az alatta lev absztrakt tpus jell ki. Ezrt nincs definilva az absztrakt tpus reprezentcis fggvnye, csak a tpus invarinsa. A tpusmveletek llapottere kitallhat a mveletet ler rtkads vltozinak tpusbl. Az absztrakt tpus alatt talljuk az azt megvalst konkrt tpust. Ennek invarins lltsa mindig igaz, ezrt ezt kln nem tntettk fel. A

{1..100}

166

7.3. Absztrakt tpus

mveleteket implementl programok programok vltozinak tpusbl. tpusrtkek tpus specifikci


legfeljebb 100 klnbz egsz szmot tartalmaz

llapottere

kitallhat

tpusmveletek legyen res betesz maximum


{1..100}

Zsk :2
{1..100}

Zsk

I(b)= e1, e2 b: e1.1 e2.1 absztrakt tpus


2 -beli szmprok halmaza

b: 2 e:{1..100}

{1..100}

b:= b:= b {e} e:=MAX(b)

: 100 2
100

{1..100}

(v)

i 1

{(i, v[i])}

v: 100, e:{1..100}

konkrt tpus

100 elforduls szmok tmbje

e [1..100]: v[e]:=0 v[e]:=v[e]+1


max, e : max v[i]
i 1 100

7.3. bra Zsk absztrakt tpusa s annak megvalstsa

7.4. Plda. Adott egy n hosszsg karaktereket tartalmaz tmbben egy olyan szveg, amelyben a szavakat vessz vlasztja el egymstl. Ksztsk el azt a msik tmbt, amelybe a szvegben szerepl szavakat az eredeti sorrendjkben, de megfordtva helyezzk

167

7. Tpus

el! gyeljnk arra is, hogy a szavakat tovbbra is vesszk vlasszk el. (Feltehetjk, hogy a szavak 30 karakternl nem hosszabbak.) Ennek a feladatnak a megoldshoz egy vermet hasznlunk. A v verem egy olyan gyjtemny, amelybl a korbban beletett elemeket a betevsk sorrendjvel ellenttes sorrendben lehet kiolvasni. Egy veremre t mveletet vezetnk be. Egy elemnek a verembe raksa (v:=push(v,e)), a legutoljra betett elem kiolvassa (top(v)), a legutoljra betett elem elhagysa (v:=pop(v)), annak lekrdezse, hogy a verem res-e (empty(v)) illetve a verem kirtse (v:= ). Tegyk be sorban egyms utn a verembe a feldolgozand szveg karaktereit, de valahnyszor a szvegben egy vesszhz rnk, akkor rtsk ki a vermet, s rjuk t a verembl kivett karaktereket az eredmny-tmb soron kvetkez helyeire, amelyek utn rjunk mg oda egy vesszt is. A feldolgozs legvgn tegyk az j szveg vgre a veremben maradt karaktereket. A fenti lersban krvonalazdik ugyan a veremtpus specifikcija, de ennek pontos megadsa kzvetett mdon szemlletesebb. (7.4.bra) brzoljuk a legfeljebb 30 karaktert tartalmaz vermeket legfeljebb 30 elem, karaktereket tartalmaz sorozatokkal. Ha s a vermet reprezentl s1 , , s s sorozat, akkor ezen a verem mveletei knnyen definilhatak. Ezt az absztrakt tpust kell ezek utn megvalstanunk. Reprezentljuk a vermet ler legfeljebb 30 hossz karaktersorozatokat egy 30 elem, karaktereket tartalmaz tmbbel, valamint egy termszetes szmmal, amely azt mutatja, hogy a tmb els hny eleme alkotja a vermet ler sorozatot. Ha ez a szm nulla, akkor a verem res. Ha ezt a szmot nullra lltjuk, akkor ezzel a vermet kirtettk. A verembe egy j elemet gy tesznk be, ho gy megnveljk ezt a szmllt, s a tmbben a szmll ltal mutatott helyre berjuk az j elemet. A verembl val kivtel a tmb-szmll ltal mutatott elemnek kiolvasst, majd a szmll cskkentst jelenti. A reprezentcis fggvny nem klcsnsen egyrtelm, hiszen a reprezentci szempontjbl kzmbs, hogy a t tmbben milyen karakterek tallhatk az m-nl nagyobb index helyeken.

168

7.3. Absztrakt tpus

tpus rtkek tpus specifikci


legfeljebb 30 karaktert tartalmaz verem

tpus mveletek betesz: v := push(v,e) kivesz: v := pop(v) olvas: e := top(v) res-e: l := empty(v) legyen res: v :=
*

I(s)= s absztrakt tpus

100

s:

, e: , l:

legfeljebb 30 hossz * -beli sorozat

s := s, e s := s1, ,s e := s
s s -1

l := s= s := :
30

* 30

(t,m) =
i 1

t[i ]
30

t:

, m: , e: , l:

konkrt tpus

tmb-szm pr

t[m+1], m :=e, m+1 m := m-1 e := t[m] l := (m=0) m := 0

7.4. bra Verem absztrakt tpusa s annak megvalstsa

Az eredeti feladatot egy rekurzv fggvny segtsgvel specifikljuk.

169

7. Tpus

A = (a: n, b: n) Ef = ( a=a ) Uf = ( Ef b=f1(n+1) ) n Az f:[0..n+1] Verem egy hrom-rtk fggvny. Tetszleges i [0..n] index esetn az f(i)-nek hrom komponense van: f1(i) az n hosszsg eredmny tmb; f2(i) ennek egy olyan indexe, amely azt mutatja, hogy az eredmny tmb els hny elemt lltottuk mr el eddig; s vgl az f3(i), amely a feldolgozshoz hasznlt verem. A rekurzv definciban sokszor kell az f(i-1) komponenseit hasznlnunk, amelyekre az tlthatsg vgett rendre b, k, s s nvvel hivatkozunk majd. (Clszer lesz ksbb ugyanezen neveket vlasztani segdvltozknak a rekurzv fggvny kiszmtsnak programozsi ttelben.) Az egyszerbb jells rdekben az <s> szimblummal hivatkozunk a veremben lev karakterek sorozatra (ennek els eleme a verem teteje, s gy tovbb), az s szimblum pedig a verembeli elemek szmra utal majd. f(0)=( b, 0, ) i [1..n]:

f(i)

(b, k , push(s , a[i] )) (b[1..k ] s ', ', k s 1,

ha a[i] ' , ' ) ha a[i] ' , '

A rekurzv kpletnek az els sora azt rja le, hogy egy karaktert, ami nem vessz, a verembe kell betenni, a tmb s az index komponensek ilyenkor nem vltoznak; a msodik sora pedig azt, hogy vessz esetn a verem tartalmt a b tmb k-adik indexe utni helyeire kell tmsolni majd utna rni mg a vesszt is. Ilyenkor j rtket kap a k index is, a verem pedig kirl. Mivel a legutols szt nem zrja le vessz, ezrt az a tmb vgre (n-hez) rve a legutols sz mg a veremben marad. Ezrt definiljuk a rekurzv fggvnyt az n+1-edik helyen, amely a verembe (f3(n), amit tovbbra s jell) lev elemeket tmsolja az eredmnytmbbe (b-vel jellt f3(n), amelynek els k, azaz f2(n) eleme utn kell az jabb karaktereket rni).

f(n 1)

b[1..k ]

s ,k

s,

A rekurzv fggvny kiszmtsnak programozsi ttelt felhasznlva kapjuk a megold programot. Hatkonysgi okbl a fggvny n+1-dik helyen trtn kiszmolst kiemeljk a ciklusbl,

170

7.3. Absztrakt tpus

s azt a ciklus utn kln hatrozzuk meg. A verem tartalmnak a b tmb k-adik indexe utni helyeire trtn tmsolsa lnyegben egy sszegzs, amelynek precz visszavezetst csak a kvetkez fejezetben bemutatott felsorolkkal lehetne elvgezni. Annyit azonban knny ltni, hogy ennek a rszfeladatnak a megoldsa egy ciklust ignyel, amely a verembl veszi ki az elemeket addig, amg a verem ki nem rl, s teszi t a b tmb soron kvetkez helyre. Nzzk meg ezek utn a programot. k, s := 0, i = 1 .. n a[i]=, empty(s) b[k+1], k:=top(s), k+1 s:=pop(s) b[k+1], k:= , , k+1 empty(s) b[k+1], k:=top(s), k+1 s:=pop(s) s:= push(s, a[i])

7.4. Tpusok kztti kapcsolatok Egy bonyolultabb feladat megoldsban sok, egymssal sszefgg tpus jelenhet meg. A tpusok kztti kapcsolatok igen sokrtek lehetnek. A 7.1. plda rszonds feladatban pldul a Pont tpus kzvetlenl rszt vett a Gmb tpus reprezentcijban, azaz megjelent annak szerkezetben, s ennek kvetkeztben a Gmb tpus mvelett megvalst program hasznlhatja a Pont tpus mvelett. Megtehetnnk azonban azt is, hogy a Gmb tpust mshogy, pldul ngy vals szmmal reprezentljuk. Ekkor a Pont tpus nem vesz rszt a Gmb tpus reprezentcijban, ugyanakkor tagadhatatlanul ilyenkor is van valamilyen kapcsolat a kt tpus kztt: egyrszt minden gmb pontok mrtani helynek tekinthet, msrszt a "benne van-e egy pont

171

7. Tpus

egy gmbben" mvelet is sszekti ezt a kt tpust. A tpusok kztti kapcsolatok, gynevezett trstsok (asszocicik) felfedse segti a programtervezst, ugyanakkor egyszerbb, tlthatbb, hatkonyabb teheti programjaink kdjt is, klnsen, ha a hasznlt programozsi nyelv tmogatja az ilyen kapcsolatok lerst. A tpusok kztti trstsi kapcsolatok lnyegben klnbz tpusok kztti relcit jelent. Ezek lehetnek tbbes vagy binris relcik. Binris trstsok esetn pldul azt lehet vizsglni, hogy a relci az egyik tpus egy rtkhez hny tpusrtket rendelhet a msik tpusbl. Ez 1-1 formj, ha relci klcsnsen egyrtelm; 1-n formj, ha a relci inverze egy fggvny; s m-n formj, ha tetszleges nem-determinisztikus relci. Az utbbi kt esetben tovbbi vizsglat lehet az n s m rtknek, vagy rtkhatrainak meghatrozsa is. Ezek a vizsglatok azt a clt szolgljk, hogy a valsgos dolgok kztti viszonyokat a feladatnak az adatabsztrakci utn kapott modelljben is megjelentsk. Emltettk mr, hogy a Gmb tpust mskppen is definilhattuk volna, amikor kzvetlenl ngy vals szmmal reprezentlunk egy gmbt. Ebben az esetben nem tartalmaz Pont tpus komponenst a Gmb, s ilyenkor annak az eldntse, hogy a "benne van -e egy pont egy gmbben" mvelet melyik tpushoz tartozzon, nem magtl rtetd. Ha a Gmb tpus mveleteknt valstjuk meg, akkor kt lehetsgnk is van. Vagy a gmb kzppontjt reprezentl vals szmokbl kell egy pontot kszteni (ez nyilvnvalan a Pont tpus egy j mvelete lesz), s ezutn a korbbi megoldshoz hasonlan hivatkozunk a pontok tvolsgt meghatroz mveletre. Vagy kzvetlenl az euklideszi tvolsg-kplettel dolgozunk, de ehhez elbb meg kell tudnunk hatrozni egy pont trbeli koordintit (ezek is a Pont tpus egy j mveletei lesznek). Bizonyos programozsi nyelvek gy kerlik ki, hogy a Pont tpushoz jabb mveleteket kelljen bevezetni s szmolni kelljen azok meghvsval jr idvesztesggel, hogy bevezetik a bartsg (friend) fogalmt, mint specilis trstsi kapcsolatot. Ez lehetv teszi, hogy egyik tpus mondjuk a Gmb tpus belelthasson a msik a Pont tpus reprezentcijba. Ilyenkor a "benne van-e egy pont egy gmbben" mvelet az euklideszi tvolsg-kplet alapjn kzvetlenl megvalsthat; noha a mvelet a Gmb tpushoz tartozik, a vizsglt pont koordintit azonban a bartsg miatt a Gmb tpusban is kzvetlenl ltni. Mg szebb az a megolds, amely ezt a "benne van-e egy pont egy gmbben" mveletet kiveszi a

172

7.4. Tpusok kztti kapcsolatok

Gmb tpusbl, azt egy fggetlen eljrsnak tekinti, de ezt az eljrst mind a Pont, mind a Gmb tpus bartjv teszi, gy azoktl kzeli, de egyenl tvolsgra helyezi el. A bartsg kapcsolat segtsgvel lehetv vlik az eljrs szmra mind egy gmb, mind egy pont reprezentcijra trtn hivatkozs. Tpusok kztti kapcsolatnak tekinthetjk azt is, amikor egy tpust (pontosabban az ltala kijellt tpus-specifikcit) egy msik tpussal megvalstunk. Ugyancsak tpusok kztti kapcsolatot fogalmaz meg egy tpus reprezentcija. Pontosabban, itt a tpus s annak egy rtket helyettest elemi rtkek tpusai kztti reprezentcis kapcsolatrl van sz. A reprezentcis kapcsolat egyik vetlete az a tartalmazsi kapcsolat, amelyik gy tekint a reprezentlt tpusrtkre, mint egy burokra, amely az t reprezentl elemi rtkeket tartalmazza. Erre lttunk pldt az rszonds feladatban, ahol a Pont s a vals szm tpusa pt eleme volt a Gmb tpusnak: egy gmb reprezentcija egy pont s egy sugr volt. A tartalmazsi kapcsolat teht arra hvja fel a figyelmet, amikor egy tpus rszt vesz egy msik tpus reprezentcijban. A reprezentcis kapcsolat msik vetlete a reprezentl tpusok egymshoz val viszonya, a tpus-reprezentci szerkezete. A reprezentci szempontjbl ugyanis lnyeges az, hogy egy tpusrtket helyettest elemi rtkeknek mi az egymshoz val viszonya: egy tpusrtket klnbz tpus elemi rtkek egyttese reprezentl-e, vagy klnbz tpus rtkek kzl mindig az egyik, vagy azonos tpus rtkek sokasga (halmaza, sorozata). Ez a reprezentl tpusok kztti szerkezeti kapcsolat fontos tulajdonsga a reprezentlt tpusnak. Azokat a tpusokat, ahol a helyettest elemek nem rendelkeznek bels szerkezettel, vagy az adott feladat megoldsa szempontjbl nem lnyeges a bels szerkezetk, elemi tpusoknak nevezzk. Ha egy tpus nem ilyen, akkor sszetett tpusnak hvjuk. Egy tpus szerkezetn a helyettest elemek gyakran igen sszetett bels szerkezett rtjk, azaz azt, hogyan adhat meg egy helyettest elem elemibb rtkek egytteseknt, s milyen kapcsolatok vannak ezen elemi rtkek kztt. Els hallsra ez nem tnik korrekt meghatrozsnak, hiszen a legegyszerbb elemek is felbonthatk tovbbi rszekre. A

173

7. Tpus

szmtgpek vilgban clszernek ltszik az elemi szintet a biteknl meghzni, hiszen egy programoz szmra az mr igazn nem rdekes, hogy hny szabad elektron formjban lt testet egy 1-es rtk bit a szmtgp memrijban. A programksztsi gyakorlatban azonban mg a bitek szintje is tlsgosan alacsony szintnek szmt. A legtbb feladat megoldsa szempontjbl kzmbs az, hogy a programozsi krnyezetben adott (teht megengedett) tpus rtkei hogyan plnek fel a bitekbl. Pldul a feladatok tlnyom tbbsgben nem kell azzal foglalkoznunk, hogy a szmtgpben egy termszetes szm binris alakban van jelen; nem fontos ismernnk az egsz szmok kdolsra hasznlt 2-es komplemens kdot; nem kell tudnunk arrl, hogy a szmtgp egy vals szmot 2 s 4 kz normlt egyenes kd mantisszj s tbbletes kd karakterisztikj binrisan normalizlt alakban trol. (Legfeljebb csak a legnagyobb s a legkisebb brzolhat szm, a fellp kerektsi hiba vonatkozsban rdekelhet ez bennnket.) Ezrt hacsak a feladat nem kvetel mst nyugodtan tekinthetjk a termszetes szmokat, az egsz szmokat, s a vals szmokat is elemi tpusoknak. Hasonl elbrls al esik a karakterek tpusa, s a logikai tpus is. Egy-egy feladat kapcsn termszetesen ms elemi tpusok is megjelenhetnek. Ha egy tpus hasznlata megengedett s nem kell hozzfrnnk a tpusrtkeket helyettest elemek egyes rszeihez, akkor a tpust elemi tpusnak tekintjk. Hangslyozzuk, hogy ez a meghatrozs relatv. Nem kell csodlkozni azon, ha egy tpus az egyik feladatban elemi tpusknt, a msikban sszetett tpusknt jelenik meg, st ugyanazon feladat megoldsnak klnbz fzisban lehet egyszer elemi, mskor sszetett. Az sszetett tpusok mveletei tbbnyire egy-egy tpusrtk helyettest elemnek sszetev rszeit krdezik le, azokat mdostjk, esetleg az sszetevs mdjt vltoztatjk meg. Nyilvnval, hogy az ilyen tpusok mveleteinek elemzsnl, definilsnl nagy segtsget jelent a helyettest elemek szerkezetnek ismerete. Erre a tpusoknak tpus-specifikcival trtn megadsa nem alkalmas, mert az reprezentci nlkl kevsb szemlletes; radsul a programoz gysem kerlheti el, hogy elbb utbb gondoskodjon a tpus reprezentlsrl, azaz dntsn a tpusrtkek bels logikai, majd fizikai szerkezetrl.19
19

Az adatszerkezeteket kzppontba llt vizsglatoknl clszer a tpus szerkezetnek definilsnl egy tpusrtket helyettest

174

7.4. Tpusok kztti kapcsolatok

Nzznk meg most pldaknt nhny jellegzetes tpusszerkezetet. Egy tpust rekord szerkezetnek neveznk, ha egy tpusrtkt megadott (tpusrtk-) halmazok egy-egy elembl ll rtk-egyttes (rekord) reprezentlja. A T = rec( m1:T1, , mn:Tn ) azt jelli, hogy a T egy rekord (direktszorzat) tpus, azaz minden tpusrtkt egy T1 Tn-beli elem (rtk-egyttes) reprezentlja. Ha t egy ilyen T tpusnak egy rtke (rekord tpus objektum vagy rviden rekord), akkor a t reprezentnsnak i-edik komponensre a t.mi kifejezssel hivatkozhatunk (lekrdezhetjk, megvltoztathatjuk). Reprezentljuk pldul a gmbket a kzppontjukkal s a sugarukkal. Ekkor a Gmb tpus rekord szerkezet. Vezessnk be jl megjegyezhet neveket a reprezentci komponenseinek azonostsra. Jellje c a kzppontot, r a sugarat. Ekkor a g.cvel a g gmb kzppontjra, g.r-rel pedig a sugarra hivatkozhatunk. Mindezen informcit a Gmb=rec(c:Pont,r:R) jellssel adhatjuk meg. A tpus alternatv szerkezet, ha egy tpusrtkt megadott (tpusrtk-) halmazok valamelyiknek egy eleme reprezentlja. A T = (reprezentl) elemet olyan irnytott grffal brzolni, amelyben a cscsokat elemi adatrtkekkel cmkzzk meg, az irnytott lek pedig az ezek kzti szomszdsgi kapcsolatokat jellik. Pldul egy sorozatszerkezet tpus egy rtkt olyan grffal rhatjuk le, ahol a cscsokat sorba, lncba fzzk, s mindegyik cscsbl (az utols kivtelvel) egyetlen irnytott l vezet ki, amelyik a rkvetkez adatelemre mutat. A helyettest (reprezentns) elemeknek irnytott grfokkal trtn megjelentse nem felttlenl jelenti azt, hogy a tpusnak konkrt programozsi krnyezetben trtn megvalstsakor az irnytott grfban rgztett szerkezetet hen kell kvetni. A tpus szerkezetnek ilyen brzolsa elssorban a tpus megadst, megrtst szolglja, ezrt tbbnyire egy absztrakt tpus definilshoz hasznljuk. Az absztrakt tpus szerkezete, ms szval a tpus absztrakt szerkezete lehetv teszi a tpus mveleteinek szemlletes bemutatst, s a mveletek hatkonysgnak elemzst. Az irnytott grfok, mint absztrakt szerkezetek lehetsget adnak a tpusok klnfle szerkezet szerinti rendszerezsre. Pldul az sszes sorozatszerkezet tpus szerkezett egy lncszer irnytott grf, gynevezett lineris adatszerkezet jellemzi. Az absztrakt adatszerkezet jellemzsre meg szoktak mg klnbztetni ortogonlis-, fa-, ltalnos grf-szerkezet tpusszerkezeteket is.

175

7. Tpus

alt( m1:T1; ; mn:Tn ) azt jelli, hogy T egy alternatv (uni) tpus, azaz minden tpusrtkt egy T1 Tn-beli elem reprezentl. Ha t egy ilyen T tpusnak egy rtke (alternatv tpus objektum), akkor a t.mi logikai rtk abban az esetben igaz, ha t-t ppen a Ti tpus egyik rtke reprezentlja. Pldaknt tekintsk azt a tpust, amely egy fogorvosi rendelben egy pciensre jellemz adatokat foglalja ssze. Mivel egy pciens lehet felntt s gyerek is, akiket fogorvosi szempontbl meg kell klnbztetnnk, hiszen pldul a gyerekeknl kln kell nyilvn tartani a tejfogakat: Pciens=alt(f:Felntt;g:Gyerek). Termszetesen egy ilyen plda akkor teljes, ha definiljuk a Felntt s a Gyerek tpusokat is. Ezek rekord tpusok lesznek: Felntt=rec(nev: * , fog:, kor:), Gyerek=rec(nev: *, fog:, tej:, kor:). Ha p egy Pciens tpus objektum, akkor a p.f lltssal dnthetjk el, hogy a p pciens felntt-e; a p.fog:=p.fog-1 rtkads pedig azt fejezi ki, hogy kihztk a p egyik fogt. Ha egy tpus tetszleges rtkt sok azonos tpus elemi rtk reprezentlja, akkor azt iterlt (felsorolhat, gyjtemny) tpusnak is szoktk nevezni. Az elnevezs onnan szrmazik, hogy a tpusrtket reprezentl elemi rtkeket azok egymshoz val viszonytl fgg mdon sorban egyms utn fel lehet sorolni. Az elemi rtkek kapcsolata a reprezentlt tpusrtk bels szerkezett hatrozza meg. Ez lehet olyan, amikor nincs kijellve az elemi rtkek kztt sorrendisg; a tpusrtket elemi rtkek kznsges halmaza reprezentlja. Ez a halmaz lehet multiplicitsos halmaz (zsk) is, amelyben megengedjk ugyanazon elem tbbszri elfordulst. Lehet a reprezentl elemsokasg egy sorozat is, amely egyrtelm rkvetkezsi kapcsolatot jell ki az elemek kztt, de lehet egy olyan irnytott grf, amelynek cscsai az elemi rtkek, az azok kztti lek pedig sajtos, egyedi rkvetkezsi relcit jellnek. A T=it(E) azt a T iterlt (szerkezet) tpust jelli, amelynek tpusrtkeit az E elemi tpus rtkeibl ptjk fel. A kvetkez fejezetben szmos nevezetes iterlt szerkezet tpust fogunk bemutatni. A tpusszerkezethez ktd tpusok kztti kapcsolat a tpusok kzti szerkezeti rokonsg. Kt tpust akkor neveznk rokonnak, ha tpusrtkeik ugyanazon tpus (esetleg tpusok) elemeibl hasonl szerkezet alapjn plnek fel. Szerkezetileg rokon pldul egy egsz szmokat tartalmaz tmb s egy egsz szmokbl ll sorozat. Rokon tpusok mveletei termszetesen klnbzhetnek. Ilyenkor megksrelhetjk az egyik tpus mveleteit a rokon tpus mveleteinek

176

7.4. Tpusok kztti kapcsolatok

segtsgvel helyettesteni. A rokonsg gyakran egyoldal, azaz a rokon tpusoknak csak az egyike helyettesthet a msikkal, fordtva nem; gyakran rszleges, azaz nem az sszes, csak nhny mvelet helyettesthet; esetenknt nvleges, mert a szerkezeti hasonlsg ellenre sem helyettesthet egyik tpus a msikkal. Tpusok kztt nemcsak szerkezeti rokonsg, hanem mveleti rokonsg is fennllhat. Errl akkor beszlhetnk, amikor kt tpusnak megegyeznek a tpusmveletei. Pldul a Gmb tpus illetve egy Kocka tpus ilyen tpusmveleti rokonsgot mutathat, ha mindkettnl olyan mveleteket definilunk, mint add meg a test slypontjt, szmtsd ki a trfogatot, benne van-e egy pont a testben. Ezen mveletek specifikcija is azonos, csak a megvalstsuk tr el egymstl. Specilis tpusmveleti rokonsg a tpus-altpus kapcsolat. Az altpus ugyanazokkal a mveletekkel rendelkezik, mint az ltalnosabb tpus, csak azok rtelmezsi tartomnya s rtkkszlete szkl. Pldul egsz szmok tpusnak egy altpusa az 1 s 10 kz es egsz szmok tpusa. Az altpus fogalmnak ltalnostsval juthatunk el az objektum orientlt programozsban legtbbet emlegetett tpusok kztti kapcsolathoz, az rkldshez. Lttuk, hogy az altpus rendelkezik az ltalnosabb tpus reprezentcijval s tpus-mveleteivel, azaz rkli azokat az ltalnosabb tpustl. Ezt az rklst rugalmasabban is lehet rvnyesteni: meglev tpusbl (esetleg tpusokbl) szrmaztatunk egy j tpust gy, hogy egyenknt megmondjuk, milyen tulajdonsgokat (szerkezetet, szerkezet sszetevit, mveleteket) vessznk t, ms nven rklnk a meglv tpus(ok)tl, s azokhoz milyen j tulajdonsgokat tesznk hozz. Az gy ltrejtt j tpust szrmaztatott tpusnak, a meglv tpusokat stpusoknak nevezik.20 Az objektum elv programtervezs pldul a Gmb s a Pont tpus megadsnl szreveszi, hogy egy gmb ltalnosabb fogalom, mint a pont, hiszen a pont felfoghat egy specilis, nulla sugar gmbnek. Ilyenkor az gynevezett megszort rkldst alkalmazva a Pont tpust szrmaztathatjuk a Gmb tpusbl, azaz azt mondjuk, hogy a Pont tpus majdnem olyan, mint a Gmb tpus, csak minden elemnek a sugara nulla. A Pont tpus teht Gmb tpus megszortsaknt ll el. Meg kell jegyezni, hogy ebben az esetben a gmb a korbban
20

Az objektum elv programtervezs a tpusok helyett az osztly elnevezst hasznlja.

177

7. Tpus

bemutatott megvalstsval ellenttben mr nem egy pont s egy vals szm segtsgvel, hanem ngy vals szmmal van reprezentlva. Ha a Gmb tpuson definilunk egy olyan mvelett, amely eldnti, hogy egy gmb tartalmaz-e egy msik gmbt, akkor ezt a mveletet specilisan gy is meg lehet majd hasznlni, ha a msik gmbt egy pont helyettesti (hiszen az is egy gmb). Ha a Gmb tpus tartalmazn kt gmb tvolsgt (pontosabban a gmbk kzppontjnak tvolsgt) kiszmol mveletet, akkor ezt a mvelet rkln a Pont tpus is, ahol azonban ez mr megszortva, kt pont tvolsgnak meghatrozsra szolglna. Egybknt ugyangy rklhet a benne van-e egy gmbben egy msik gmb mvelet is, amely a Pont tpusra nzve a benne van-e egy pontban egy msik gmb vagy akr benne van-e egy pontban egy msik pont (ami lnyegben az azonos-e kt pont mvelet) rtelmet nyerne. A megszort rkldsnl elvben azt is el lehet rni, hogy az stpusbl szrmaz bizonyos mveletek ne rkldjenek a leszrmazott tpusra. Mivel a pldban a Pont tpus s a Gmb tpus ugyanazon mveletekkel rendelkezik (hiszen a Pont rkli a Gmb egyetlen mvelett s nem vezet be mell jat), ezrt itt a Pont a Gmb altpusa is. A megszort rklds nemcsak az itt bemutatott specializci mentn jhet ltre, hanem gy, hogy az egymshoz hasonl tpusokat ltalnostjuk, s ennek sorn elksztjk azt az stpust, amelybl a vizsglt tpusok rkldssel szrmaztathatk. Ltezik az objektum elv programozs gyakorlatban egy msik, a fentiektl eltr gondolkods is, amely azrt vezet be sosztlyokat, hogy az rklds rvn a kd-jrafelhasznlst tmogassa. Ennek a gondolatnak jegyben mondhatjuk pldul azt, hogy egy gmbt ler kd tartalmazza a pontot ler kdot, ezrt rdemes elbb a Pont tpust megalkotni, s majd ebbl szrmaztathatjuk a Gmb tpust. A szrmaztats sorn kiegsztjk egy pont reprezentcijt mg egy vals szmmal (ez lesz a gmb sugara); tvesszk (rkljk) a kt pont tvolsgt kiszmol mveletet, amely most mr kt gmb kzppontjainak tvolsgt szmtja majd ki; s csak itt a gmbkre definiljuk a "benne van-e egy pont egy gmbben" j mveletet. Az rkldsnek ezt a fajtjt, amikor j tulajdonsgokat vesznk hozz az stpushoz, analitikus rkldsnek nevezik. Ebben a megkzeltsben elbb a Pont tpust kell megalkotni, s utna a Gmb tpust, teht nem a programtervezsnl eddig ltott fellrl lefel halad finomtsi

178

7.4. Tpusok kztti kapcsolatok

technikt, hanem ellenkezleg, egy alulrl felfel halad technikt alkalmazunk. Ez a szemllet persze csak akkor kifizetd, ha a programozsi nyelv, amelyen implementljuk majd a programunkat, rendelkezik az rkldst tmogat nyelvi elemekkel.

179

7. Tpus

7.5. Feladatok 7.1. Valstsuk meg a racionlis szmok tpust gy, hogy kihasznljuk azt, hogy minden racionlis szm brzolhat kt egsz szmmal, mint azok hnyadosa! Implementljuk az alapmveleteket! 7.2. Valstsuk meg a komplex szmok tpust! brzoljuk ezeket az algebrai alakkukkal (x+iy)! Implementljuk az alapmveleteket! 7.3. Valstsuk meg a skvektorok tpust! Implementljuk kt vektor sszegnek, egy vektor nyjtsnak, s forgatsnak mveleteit! 7.4. Valstsuk meg a ngyzet tpust! Ennek rtkei a sk ngyzetei, amelyeket el lehet tolni egy adott vektorral, s fel lehet nagytani! 7.5. Valstsuk meg azt a zsk tpust, amelyikrl tudjuk, hogy csak 1 s 100 kztti termszetes szm kerlhet bele, de egy szm tbbszr is! Implementljuk az j elem behelyezse, egy elem kivtele s egy elem hnyszor van benne a zskban mveleteket! 7.6. Valstsuk meg az egsz szmokat tartalmaz sor tpust! Az elemeket egy tmbben troljuk. Mveletei: a sor vgre betesz, sor elejrl kivesz, megvizsglja, hogy res-e illetve tele-e a sor. 7.7. Valstsuk meg a nagyon nagy termszetes szmok tpust! A szmokat decimlisan brzoljuk, s szmjegyeit egy kellen hossz tmbben troljuk! 7.8. Valstsuk meg a vals egytthatj polinomok tpust az sszeads, kivons, szorzs mveletekkel! 7.9. Valstsuk meg a diagonlis mtrixtpust (amelynek mtrixai csak a ftljukban tartalmazhatnak nulltl klnbz szmot)! Ilyenkor elegend csak a ftl elemit reprezentlni egy sorozatban. Implementljuk a mtrix i-edik sornak j-edik elemt visszaad mveletet, valamint kt mtrix sszegt s szorzatt! 7.10. Valstsuk meg az alshromszg mtrixtpust (a mtrixok a ftljuk felett csak nullt tartalmaznak)! Ilyenkor elegend csak a ftl s az alatti elemeket reprezentlni egy sorozatban. Implementljuk a mtrix i-edik sornak j-edik elemt visszaad mveletet, valamint kt mtrix sszegt s szorzatt!

180

8. Programozsi ttelek felsorol objektumokra


Ha egy adatot elemi rtkek csoportja reprezentl, akkor az adat feldolgozsa ezen rtkek feldolgozsbl ll. Az ilyen adat lnyeges jellemzje, hogy az t reprezentl elemi rtkeknek mi az egymshoz val viszonya, a reprezentci milyen jellegzetes bels szerkezettel rendelkezik. Szmunkra klnsen azok az adattpusok rdekesek, amelyek tpusrtkeit azonos tpus elemi rtkek sokasga reprezentl. Ilyen pldul egy tmb, egy halmaz vagy egy sorozat. Ezeknek az gynevezett gyjtemnyeknek kzs tulajdonsga, hogy a bennk trolt elemi rtkek egyms utn felsorolhatk. Egy halmazbl egyms utn kivehetjk, egy sorozatnak vagy egy tmbnek egyms utn vgignzhetjk az elemeit. ppen ezrt az ilyen tpusokat szoktk felsorolhatnak (enumerable) vagy iterltnak (iterlt szerkezetnek) is nevezni. Felsorolni azonban nemcsak gyjtemnyek elemeit lehet, hanem pldul egy egsz szm valdi osztit, vagy kt egsz szm ltal meghatrozott zrt intervallum egsz szmait. Ennl fogva a felsorolhat adat fogalma nem azonos a gyjtemnnyel, hanem annl ltalnosabb, az elbbi pldkban szerepl gynevezett virtulis gyjtemnyeket is magba foglalja. A felsorolhatsg azt jelenti, hogy kpesek vagyunk egy adatnak valamilyen rtelemben vett els elemre rllni, majd a soron kvetkezre, az azt kvetre, s gy tovbb, meg tudjuk krdezni, van-e jabb soron kvetkez elem (vagy van-e egyltaln els elem), s lekrdezhetjk a felsorols sorn rintett aktulis elemnek az rtkt. A felsorolst vgz mveletek nem annak az adatnak a sajt mveletei, amelynek elemeit felsoroljuk. Furcsa is lenne, ha egy egsz szm (amelyiknek valdi osztit kvnjuk felsorolni) alapbl rendelkezne ilyen (vedd a kvetkez valdi osztt fle) mveletekkel. De egy egsz szmokat tartalmaz intervallumnak is csak olyan mveletei vannak, amivel az intervallum hatrait tudjuk lekrdezni, az intervallum egsz szmainak felsorolshoz mr egy specilis objektumra, egy indexre van szksg. Radsul egy intervallum felsorolsa tbbfle lehet (egyesvel vagy kettesvel; nvekv, esetleg cskken sorrendben), ezeket mind nem lenne rtelme az intervallum tpusmveleteivel lerni. A felsorolst vgz mveleteket mindig egy kln objektumhoz ktjk. Ha szksg van

181

8. Programozsi ttelek felsorol objektumokra

egy adat elemi rkeinek felsorolsra, akkor az adathoz hozzrendelnk egy ilyen felsorol objektumot. Egy felsorol objektum feldolgozsa azt jelenti, hogy az ltala felsorolt elemi rtkeket valamilyen tevkenysgnek vetjk al. Ilyen tevkenysg lehet ezen rtkek sszegzse, adott tulajdonsg rtkek megszmolsa vagy a legnagyobb elemi rtk megkeresse, stb. Ezek ugyanolyan feladatok, amelyek megoldsra korbban programozsi tteleket vezettnk be, csakhogy azokat a tteleket intervallumon rtelmezett fggvnyekre fogalmaztuk meg, most viszont ennl ltalnosabb, felsorolra kimondott vltozatukra lesz szksg. Ezt az ltalnostst azonban knny megtenni, hiszen egy intervallumhoz nem nehz felsorolt rendelni, gy a korbban bevezetett intervallumos tteleket egyszeren tfogalmazhatjuk felsorol objektumra. Elszr (8.1. alfejezet) a nevezetes tpusszerkezeteket fogjuk megvizsglni, de ezek kztt is a legnagyobb hangslyt az iterlt szerkezet, teht felsorolhat tpusok bemutatsra helyezzk. A 8.2. alfejezetben a felsorol tpus mveleteit fogjuk jellemezni, majd megadjuk egy felsorol objektum ltalnos feldolgozst vgz algoritmus-smt. A 8.3. alfejezetben nevezetes felsorol tpusokat mutatunk. A 8.4. alfejezetben a programozsi tteleinket mondjuk ki felsorol tpusokra. Vgl (8.5. alfejezet) feladatokat oldunk meg.

182

8.1. Gyjtemnyek

8.1. Gyjtemnyek Gyjtemnyeknek (s itt nem foglalkozunk a virtulis gyjtemnyekkel) az sszetett szerkezet adatokat nevezzk. Ezek legfbb jellegzetessge, hogy reprezentcijuk elemi rtkekbl pl fel, azaz elemi rtkeket trol, amelyeket megfelel mveletek segtsgvel be tudunk jrni, fel tudunk sorolni. Leggyakrabban az iterlt szerkezet adatokat hasznljuk gyjtemnyknt, amelyek tpusrtkeit azonos tpus elemi rtkek sokasga reprezentlja. Vizsgljunk meg most nhny nevezetes gyjtemnyt. A halmaz (szerkezet) tpus tpusrtkeit egy-egy vges elemszm 2E-beli elem (E-beli elemekbl kpzett halmaz) reprezentlja. Egy halmaz tpus objektumnak a tpusmveletei a halmazok szoksos mveletei lesznek. rtelmezzk: halmaz ressgnek vizsglatt (h= , ahol h egy halmaz tpus rtket jell), halmaz egy elemnek kivlasztst (e: h, ahol e egy elemi rtket hordoz segdvltoz), halmazbl egy elem kivonst (h:=h{e}), j elemnek a hozzadst a halmazhoz (h:=h {e}). A tpus-megvalsts szempontjbl egyltaln nem kzmbs, hogy itt a szoksos uni illetve kivons mveletvel van-e dolgunk, vagy a megklnbztetett (diszjunkt) uni illetve megklnbztetett kivonssal. Ez utbbiak esetn felttelezzk, hogy a mvelet megvltoztatja a halmazt, azaz uni esetn bvl (mert a hozzadand elem j, mg nincs benne a halmazban), kivons esetn fogy (mert a kivonand elem benne van a halmazban). Ezeknek a mveleteknek az implementlsa egyszerbb, mert nem kell ezen feltteleket kln ellenriznik, igaz, a felttel nem teljeslse estn abortlnak. A halmaz tpust a set(E) jelli. Ltjuk, hogy egy halmaz egy elemnek kivlasztsa (e: h) a nem-determinisztikus rtkkivlasztssal trtnik, amely ugyanazon halmazra egyms utn alkalmazva nem ugyanazt az eredmnyt fogja adni. Be lehet vezetni azonban a determinisztikus elemkivlaszts mvelett (e:=mem(h)), amelyet ha ugyanarra a halmazra tbbszr egyms utn hajtjuk vgre, akkor mindig ugyanazon elemt adja vissza a halmaznak. Az igazat megvallva, a halmaz szba jhet reprezentcii sokkal inkbb tmogatjk ennek az elemkivlasztsnak a megvalstst, mint a valban vletlenszer, nem-determinisztikus rtkkivlasztst.

183

8. Programozsi ttelek felsorol objektumokra

A sorozat (szerkezet) tpus tpusrtkeit egy-egy vges hossz E*-beli elem (E-beli elemekbl kpzett sorozat) reprezentlja, tpusmveletei pedig a sorozatokon rtelmezhet mveletek. Jelljn a t egy sorozat tpus objektumot, amelyet egy sorozat reprezentl. Most a teljessg ignye nlkl felsorolunk nhny tpusmveletet, amelyeket a sorozatra be szoktak vezetni. Ilyen egy sorozat hossznak lekrdezse (|t|), a sorozat valahnyadik elemre indexelssel trtn hivatkozs (ti ahol az i indexnek 1 s a sorozat hossza kz kell esni), egy elem trlse egy sorozatbl (ha a sorozat nem res) vagy egy j elem beszrsa. Magt a sorozat tpust a seq(E) jelli. Specilis sorozattpusokhoz jutunk, ha csak bizonyos tpusmveleteket engednk meg. Ilyen pldul a verem s a sor. A verem esetn csak a sorozat elejre szabad j elemet befzni, a sornl pedig csak a sorozat vgre. Mindkett esetn megengedett mvelet annak eldntse, hogy a reprezentl sorozat res-e. Mindkettnl ki lehet olvasni a sorozat els elemt, s azt el is lehet hagyni a sorozatbl. A szekvencilis outputfjl (jellse: outfile(E)) kt mveletet enged meg: res sorozat ltrehozst (t:=<>) s a sorozat vghez j elem vagy elemekbl kpzett sorozat hozzillesztst (jellse: t:write(e) vagy t:write(<e1, ,en>)). A szekvencilis inputfjlnak (jellse: infile(E)) is egyetlen mvelete van: a sorozat els elemnek lefzse, ms szval az olvass mvelete. Matematikai rtelemben ezt egy olyan fggvnnyel rhatjuk le, amely egy sorozat tpus objektumhoz (pontosabban az t reprezentl sorozathoz) hrom rtket rendel: az olvass sttuszt, a sorozat els elemt (ha van ilyen), s az els elemtl megfosztott sorozatot. Az olvasst az st,e,t:=read(t) rtkadssal, vagy rvidtve az st,e,t:read szimblummal jelljk. Az st az olvass sttusza. Ez egy specilis ktelem halmaznak (Sttusz ={abnorm, norm}) az elemt veheti fel rtkknt. Ha a t egy res sorozat, akkor az st,e,t:read mvelet sorn az st vltoz az abnorm rtket veszi fel, a t-beli sorozat tovbbra is res marad, az e pedig definilatlan. Ha a t-beli sorozat nem res, akkor az st,e,t:read mvelet vgrehajtsa utn az st vltoz az norm-ot, az e a t sorozat els elemt, a t pedig az eggyel rvidebb sorozatot veszi fel. Sorozat szerkezetnek tekinthetjk a vektor tpust, vagy ms nven egydimenzis tmbt. Ha eltekintnk egy pillanatra attl, hogy a vektorok tetszlegesen indexelhetek, akkor a vektor felfoghat egy olyan sorozatnak, amelynek az elemeire a sorszmuk alapjn lehet kzvetlenl hivatkozni, de a sorozat hossza (trlssel vagy beszrssal)

184

8.1. Gyjtemnyek

nem vltoztathat meg. Egy vektor tpushoz azonban a fent vzolt sorozaton kvl azt az indextartomnyt is meg kell adni, amely alapjn a vektor elemeit indexeljk. A vektor tpus teht valjban egy rgztett hosszsg sorozatbl s egy egsz szmbl ll rekord, amelyben a sorozat tartalmazza a vektor elemeit, az egsz szm pedig a sorozat els elemnek indext adja meg. A vektor tpust a vec(E) jelli. A vektor als s fels indexnek lekrdezse is ppen gy tpusmveletnek tekinthet, mint a vektor adott index elemre val hivatkozs. Ha v egy vektor, i pedig egy indexe, akkor v[i] a vektor i index eleme, amit lekrdezhetnk vagy megvltoztathatunk, azaz llhat rtkads jobb vagy baloldaln. ltalnosan a v vektor indextartomnynak elejt a v.lob, vgt a v.hib kifejezsek adjk meg. Ha azonban a vektor tpusra az ltalnos vec(E) jells helyett tovbbra is a korbban bevezetett E m..n jellst alkalmazzuk, akkor az indextartomnyra egyszeren az m s n segtsgvel hivatkozhatunk. Vilgosan kell azonban ltni, hogy itt az m s az n a vektor egyedi tulajdonsgai, s nem attl fggetlen adatok. A ktdimenzis tmbtpusra, azaz a mtrix tpusra vektorok vektoraknt gondolunk. Ennek megfelelen egy t mtrix i-edik sornak j-edik elemre a t[i][j] hivatkozik (ezt rvidebben t[i,j]-vel is jellhetjk), az i-edik sorra a t[i], az els sor indexre a t.lob, az utolsra a t.hib, az i-edik sor els elemnek indexre a t[i].lob, az utols elem indexre a t[i].hib. A mtrix tpust a matrix(E) jelli. (Ezek a mveletek ltalnosthatak a kettnl tbb dimenzis tmbtpusokra is.) Specilis, de a leggyakrabban alkalmazott mtrix (tglalap-mtrix) az, amelynek sorai egyforma hosszak s ugyanazzal az indextartomnnyal indexeltek. Ezt jelli az El..nk..m, ahol a sorokat az [l..n] intervallum, egy sor elemeit pedig a [k..m] intervallum indexeli. Ha k=1 s l=1, akkor az Enm-jellst is hasznljuk, s ilyenkor n*m-es mtrixokrl (sorok szma n, oszlopok szma m) beszlnk. Knyvnkben megengedettnek tekintjk mindazokat a tpusokat, amelyeket megengedett tpusokbl az itt bemutatott tpusszerkezetek segtsgvel kszthetnk. 8.2. Felsorol tpus specifikcija A felsorolhat adatoknak (vektornak, halmaznak, szekvencilis inputfjlnak, valdi osztit felknl termszetes szmnak; teht a valdi vagy virtulis gyjtemnyeknek) az elemi rtkeit egy kln

185

8. Programozsi ttelek felsorol objektumokra

objektum segtsgvel szoktuk felsorolni. Termszetesen egy felsorol objektumnak hivatkoznia kell tudni az ltala felsorolt adatra, amelyen keresztl tmaszkodik a felsorolt adat mveleteire, de ezen kvl egyb segdadatokat is hasznlhat. Egy felsorol objektum21 (enumerator) vges sok elemi rtk felsorolst teszi lehetv azltal, hogy rendelkezik a felsorolst vgz mveletekkel: r tud llni a felsoroland rtkek kzl az elsre vagy a soron kvetkezre, meg tudja mutatni, hogy tart-e mg a felsorols s vissza tudja adni a felsorols sorn rintett aktulis rtket. Azt a tpust, amely biztostja ezeket a mveleteket, s ezltal felsorol objektumok lersra kpes, felsorol tpusnak nevezzk. Egy t felsorol objektumra teht definci szerint ngy mveletet vezetnk be. A felsorolst mindig azzal kezdjk, hogy a felsorolt a felsorols sorn elszr rintett elemi rtkre feltve, hogy van ilyen lltjuk. Ezt ltalnosan a t:=First(t) rtkads valstja meg, amit a tovbbiakban t.First()22-tel jellnk. Minden tovbbi, teht soron kvetkez elemre a t.Next() mvelet (amely a t:=Next(t) rvidtett jellse) segtsgvel tudunk rllni. Vegyk szre, hogy mindkett mvelet megvltoztatja a t felsorol llapott. A t.Current() mvelet a felsorols alatt kijellt aktulis elem rtket adja meg. A t.End() a felsorols sorn mindaddig hamis rtket ad vissza, amg van kijellt aktulis elem, a felsorols vgt viszont igaz visszaadott rtkkel jelzi. Nem szksgszer, de ajnlott e kt utbbi mveletet gy definilni, hogy ne vltoztassa meg a felsorol llapott. Mi a tovbbiakban ezt kvetkezetesen be is tartjuk. Fontos kritrium, hogy a felsorols vge vges lpsben (a t.Next() vges sok vgrehajtsa utn) bekvetkezzk. A felsorol mveletek hatst ltalban nem definiljuk minden esetre. Pldul nem-definilt az, hogy a t.First() vgrehajtsa eltt (teht a felsorols kezdete eltt) illetve a t.End() igazra vltsa utn (azaz a felsorols befejezse utn) mi a hatsa a t.Next(), a t.Current() s a t.End() mveleteknek. ltalban nem definilt az sem, hogy mi trtnjen akkor, ha a t.First() mveletet a felsorols kzben ismtelten vgrehajtjuk.
21

Amikor a felsorolhat adat egy gyjtemny (iterlt), akkor a felsorol objektumot szoktk bejrnak vagy itertornak is nevezni, mg maga a felsorolhat gyjtemny a bejrhat, azaz iterlhat adat. 22 A mveletek jellsre az objektum orientlt stlust hasznljuk: t.First() a t felsorolra vonatkoz First() mveletet jelli.

186

8.2. Felsorol tpus specifikcija

Minden olyan tpust felsorolnak neveznk, amely megfelel a felsorol tpus-specifikcinak, azaz implementlja a First(), Next(), End() s Current() mveleteket. A felsorol tpust enor(E)-vel jelljk, ahol az E a felsorolt elemi rtkek tpusa. Ezt a jells alkalmazhatjuk a tpus rtkhalmazra is. Egy felsorol objektum mg mindig elemi rtkeknek azon vges hossz sorozatt kpzeljk, amelynek elemeit sorban, egyms utn be tudjuk jrni, fel tudjuk sorolni. Ezrt specifikcis jellsknt megengedjk, hogy egy t felsorol ltal felsorolhat elemi rtkre gy hivatkozzunk, mint egy vges sorozat elemeire: a ti a felsorols sorn iedikknt felsorolt elemi rtk, ahol i az 1 s a felsorolt elemek szma (jelljk ezt t -vel) kz es egsz szm. Hangslyozzuk, hogy a felsorolhat elemek szma definci szerint vges. Ezzel tulajdonkppen egy absztrakt megvalstst is adtunk a felsorol tpusnak: a felsorolkat a felsoroland elemi rtkek sorozata reprezentlja, ahol a felsorols mveleteit ezen a sorozat bejrsval implementljuk. Egy felsorol tpus konkrt reprezentcijban termszetesen nem szerepel ez a sorozat (kivve, ha ppen sorozat bejrsra definilunk felsorolt), de mindig megjelenik valamilyen hivatkozs arra az adatra, amelyet fel akarunk sorolni. Ez az adat lehet egyetlen termszetes szm, ha annak az osztit kell ellltani, lehet egy vektor, szekvencilis inputfjl, halmaz, esetleg multiplicitsos halmaz (zsk), ha ezek elemeinek felsorolsa a cl, vagy akr egy grf, amelynek a cscsait valamilyen stratgival be kell jrni, hogy az ott trolt rtkekhez hozzjussunk. A reprezentci ezen az rtk-szolgltat adaton kvl mg tartalmazhat egyb, a felsorolst segt komponenseket is. A felsorols sorn mindig van egy aktulis elemi rtk, amelyet az adott pillanatban lekrdezhetnk. Egy vektor elemeinek felsorolsnl ehhez elg egy indexvltoz, egy szekvencilis inputfjl esetben a legutoljra kiolvasott elemet kell trolni illetve, azt, hogy sikeres volt-e a legutols olvass, az egsz szm osztinak felsorolsakor pldul a legutoljra megadott osztt. Egy felsorol ltal visszaadott rtkeket rendszerint valahogyan feldolgozzuk. Ez a feldolgozs igen vltozatos lehet; jelljk ezt most ltalnosan az F(e)-vel, amely egy e elemi rtken vgzett tetszleges tevkenysget fejez ki. Nem szorul klnsebb magyarzatra, hogy a felsorolsra pl feldolgozst az albbi algoritmus-sma vgzi el.

187

8. Programozsi ttelek felsorol objektumokra

Megjegyezzk, hogy mivel a felsorolhat elemek szma vges, ezrt ez a feldolgozs vges lpsben garantltan befejezdik. t.First() t.End() F( t.Current() ) t.Next() 8.3. Nevezetes felsorolk Az albbiakban megvizsglunk nhny fontos felsorol tpust, olyat, amelynek reprezentcija valamilyen nevezetes egy kivtelvel iterlt tpusra pl. Vizsglatainknak fontos rsze lesz, hogy megmutatjuk, hogyan specializldik a fenti ltalnos feldolgozst vgz algoritmus-sma egy-egy konkrt felsorol tpus objektum esetn. Termszetesen minden esetben ki fogunk trni arra, hogy a vizsglt tpus hogyan feleltethet meg a felsorol tpusspecifikcinak, azaz mi a felsorolst biztost First(), Next(), End() s Current() mveletek implementcija. Tekintsk elszr az egsz-intervallumot felsorol tpust. Itt egy [m..n] intervallum elemeinek klasszikus, m-tl n-ig egyesvel trtn felsorolsra gondolunk. Termszetesen ennek mintjra lehet definilni a fordtott sorrend vagy a kettesvel nveked felsorolt is. Az egsz szmok intervallumt nem tekintjk iterlt szerkezetnek, hiszen a reprezentcijhoz elg az intervallum kt vgpontjt megadni, mveletei pedig ezeket az intervallumhatrokat krdezik le. Ugyanakkor mindig fel lehet sorolni az intervallumba es szmokat. Az egsz-intervallumra pl felsorol tpus attl klnleges szmunkra, hogy a korbban bevezetett programozsi tteleinket is az egsz szmok egy intervallumra fogalmaztuk meg, amelyeket valjban ezen intervallum elemeinek felsorolst vgeztk. Ennl fogva a korbban mutatott programozsi tteleket knnyen tudjuk majd felsorolkra ltalnostani. Az egsz-intervallumot felsorol tpus egy tpusrtkt egy [m..n] intervallum kt vgpontja (m s n) s az intervallum elemeinek felsorolst segt egsz rtk indexvltoz (i) reprezentlja. Az i

188

8.3. Nevezetes felsorolk

vltoz az [m..n] intervallum aktulisan kijellt elemt tartalmazza, azaz implementlja a Current() fggvnyt. A First() mveletet az i:=m rtkads, a Next() mveletet az i:=i+1 rtkads vltja ki. Az i>n helyettesti az End() fggvnyt. (A First() mvelet itt ismtelten is kiadhat, s mindig jraindtja a felsorolst, mind a ngy mvelet brmikor, a felsorolson kvl is terminl.) Ezek alapjn a felsorol objektum feldolgozst vgz ltalnos algoritmus-smbl elllthat az egsz-intervallum klasszikus sorrend feldolgozst vgz algoritmus, amelyet szmlls ciklus formjban is megadhatunk. i := m i n F(i) i := i+1 Knny vgiggondolni, hogy miknt lehetne az intervallumot fordtott sorrendben ( i:=n, i:=i-1, i<m), vagy kettesvel nvekeden (i:=m, i:=i+2, i>n) felsorolni. Magtl rtetden lehet sorozatot felsorol tpust elkszteni. (Itt is a klasszikus, elejtl a vgig tart bejrsra gondolunk, megjegyezve, hogy ms bejrsok is vannak.) A reprezentci ilyenkor egy sorozat tpus adat (s) mellett mg egy indexvltozt (i) is tartalmaz. A sorozat bejrsa sorn az i egsz tpus indexvltozt az 1 .. s intervallumon kell vgigvezetni ppen gy, ahogy ezt az elbb lttuk. Ekkor az si-t tekinthetjk a Current() ltal visszaadott rtknek, az i:=1 a First() mvelet lesz, az i:=i+1 a Next() mvelet megfelelje, az i> s pedig az End() kifejezssel egyenrtk. (A First() mvelet ismtelten is kiadhat, amely jraindtja a felsorolst, a Next() s End() brmikor vgrehajthat, de a Current()-nek csak a felsorols alatt van rtelme.) Ezek alapjn az s sorozat elemeinek elejtl vgig trtn felsorolst vgz programot az albbi kt alakban rhatjuk fel. i = m .. n F(i)

189

8. Programozsi ttelek felsorol objektumokra

i := 1 i s F(si) i := i+1 A vektort (klasszikusan) felsorol tpus a sorozatoktl csak abban klnbzik, hogy itt nem egy sorozat, hanem egy v vektor bejrsa a cl.23 A bejrshoz hasznlt indexvltozt (jelljk ezt most is i-vel) a bejrand v vektor indextartomnyn (jelljk ezt [m..n]-nel) kell vgigvezetnnk, s az aktulis rtkre a v[i] formban hivatkoznunk. Ennek rtelmben az v[i]-t tekinthetjk a Current() mveletnek, az i:=m a First() mvelet lesz, az i:=i+1 a Next() mvelet megfelelje, az i>n pedig az End() kifejezssel egyenrtk. (A mveletek felsorolson kvli viselkedse megegyezik a sorozat felsorolsnl mondottakkal.) Egy vektor elemeinek feldolgozst az intervallumhoz hasonlan ktflekppen rjuk fel: i = 1 .. s F(si)

23

Knyvnkben gy tekintnk a vektor indextartomnyra, mint egy egsz intervallumra. A vektor tpus fogalma azonban ltalnosthat gy, hogy indextartomnyt egy felsorol objektum rja le. Ilyenkor a vektort felsorol objektum mveletei megegyeznek az indextartomnyt felsorol objektum mveleteivel egyet kivve: a Current() mveletet a v[i.Current()] implementlja, ahol i az indextartomny elemeit felsorol objektumot jelli.

190

8.3. Nevezetes felsorolk

i := 1 i s F(si) i := i+1 Mivel a mtrix vektorok vektora, ezrt nem meglep, hogy mtrixot felsorol tpust is lehet kszteni. A mtrix esetn az egyik leggyakrabban alkalmazott gynevezett sorfolytonos felsorols az, amikor elszr az els sor elemeit, azt kveten a msodikat, s gy tovbb, vgl az utols sort jrjuk be. Egy a jel n*m-es mtrix (azaz tglalap-mtrix) sorfolytonos bejrsnl a mtrixot felfoghatjuk egy n*m elem v vektornak, ahol minden 1 s n*m kz es k egsz szmra a v[k] = a[((k-1) div m) +1, ((k-1) mod m) +1]. Ezek utn a bejrst a vektoroknl bemutatott mdon vgezhetjk. Egyszersdik a kplet, ha a vektor s a mtrix indextartomnyait egyarnt 0-tl kezdden indexeljk. Ilyenkor v[k] = a[k div m, k mod m], ahol a k a 0..n*m-1 intervallumot futja be. A mtrix elemeinek sorfolytonos bejrsa igen egyszer lesz, br nem ez az ltalnosan ismert mdszer. k = 0 .. n*m-1 F(a[k div m, k mod m]) Mivel a mtrix egy ktdimenzis szerkezet tpus, ezrt a bejrshoz az elbb bemutatott mdszerrel szemben kt indexvltozt szoktak hasznlni. (Ms szval a mtrix felsoroljt a mtrix s kt indexvltoz reprezentlja.) Sorfolytonos bejrsnl az egyiket a mtrix sorai kztti bejrsra, a msikat az aktulis sor elemeinek a bejrsra hasznljuk. A bejrs sorn a[i,j] lesz a Current(). Elszr a a[1,1]-re kell lpni, gy a First() mveletet az i,j:=1,1 implementlja. A soron kvetkez mtrixelemre egy elgazssal lphetnk r. Ha a j bejr mg nem rte el az aktulis sor vgt, akkor azt kell eggyel megnvelni. Ellenkez esetben az i bejrt nveljk meg eggyel, hogy a kvetkez sorra lpjnk, a j bejrt pedig a sor elejre lltjuk. sszessgben teht az IF(j<m: j:=j+1; j=m: i,j:=i+1,1) elgazs i = 1 .. s F(si)

191

8. Programozsi ttelek felsorol objektumokra

implementlja a Next() mveletet. Az End() kifejezst az i>n helyettesti. (Ez a megolds knnyen ltalnosthat nem tglalap mtrixra is, ahol a sorok eltr hosszak s eltr indexelsek.) i, j := 1, 1 i n F( a[i,j] ) j<m j := j+1 i, j := i+1, 1

Ennek a megoldsnak a gyakorlatban jobban ismert vltozata az albbi ktciklusos algoritmus. Mindkt vltozat ugyanabban a sorrendben sorolja fel az (i,j) indexprokat az (1,1)-tl indulva az (n,m)-ig. Az egyetlen eltrs a kt vltozat kztt az, hogy lellskor (amikor i=n+1) a fenti vltozatban a j rtke 1 lesz, mg a lenti vltozatban m+1. i = 1 .. n j = 1 .. m F( a[i,j] ) A szekvencilis inputfjl felsorol tpusa egy szekvencilis inputfjllal (f), az abbl legutoljra kiolvasott elemi rtkkel (e), s az utols olvass sttuszval (st) reprezentl egy bejrt. A szekvencilis inputfjl felsorolsa csak az elejtl vgig trtn olvasssal lehetsges. st, e, f : read st=norm F(e) st, e, f : read

192

8.3. Nevezetes felsorolk

A First() mveletet az elszr kiadott st,e,f:read mvelet vltja ki. Az ismtelten kiadott st,e,f:read mvelet az f.Next() mvelettel egyenrtk. Az st,e,f:read mvelet az aktulis elemet az e segdvltozba teszi, gy a Current() helyett kzvetlenl az e rtkt lehet hasznlni. Az f.End() az olvass sikeressgt mutat st sttuszvltoz vizsglatval helyettesthet: st=abnorm. Mindegyik mvelet brmikor alkalmazhat, mert a read mvelet mindig rtelmezett, de a bejrst nem lehet ismtelten elindtani vele, hiszen egy szekvencilis inputfjl logikai rtelemben csak egyszer jrhat be, minden olvass elhagy belle egy elemet. Mind a ngy mvelet minden esetben terminl. A halmazt felsorol tpus reprezentcijban egy a felsoroland elemeket tartalmaz h halmaz szerepel. Ha a h= , akkor a halmaz bejrsa nem lehetsges vagy nem folytathat ez lesz teht az End() mvelet. Ha a h , akkor knnyen kivlaszthatjuk felsorols szmra a halmaznak akr az els, akr soron kvetkez elemt. Termszetesen az elemek halmazbeli sorrendjrl nem beszlhetnk, csak a felsorols sorrendjrl. Ez az elemkivlaszts elvgezhet a nem-determinisztikus e: h rtkkivlasztssal ppen gy, mint a halmazokra korbban bevezetett determinisztikus elemkivlaszts (e:=mem(h)). Mi ez utbbit fogjuk a Current() mvelet megvalstsra felhasznlni azrt, hogy amikor a halmaz bejrsa sorn tovbb akarunk majd lpni, akkor ppen ezt, a felsorols sorn elbb kivlasztott elemet tudjuk majd kivenni a halmazbl. Ehhez pedig pontosan ugyangy kell tudnunk megismtelni az elemkivlasztst. A Next() mvelet ugyanis nem lesz ms, mint a mem(h) elemnek a h halmazbl val eltvoltsa, azaz a h:=h{mem(h)}. Ennek az elemkivonsnak az implementcija egyszerbb, mint egy tetszleges elem kivons, mert itt mindig csak olyan elemet vesznk el a h halmazbl, amely biztosan szerepel benne, ezrt ezt kln nem kell vizsglni. A Next() mvelet is (akrcsak a Current()) csak a bejrs alatt azaz amg az End() hamis alkalmazhat. Lthatjuk azonban, hogy sem az End(), sem a Current(), sem a Next() mvelet alkalmazshoz nem kell semmilyen elkszletet tenni, azaz a felsorolst elindt First() mvelet halmazok bejrsa esetn az res (semmit sem csinl) program lesz. Ezen megjegyzseknek megfelelen a halmaz elemeinek feldolgozst az albbi algoritmus vgzi el:

193

8. Programozsi ttelek felsorol objektumokra

h F(mem(h)) h := h {mem(h)} 8.4. Programozsi ttelek ltalnostsa A programozsi tteleinket korbban az egsz szmok intervallumra fogalmaztuk meg, ahol egy intervallumon rtelmezett fggvnynek rtkeit kellett feldolgozni. Ennek sorn bejrtuk, felsoroltuk az intervallum elemeit, s mindig az aktulis egsz szmhoz tartoz fggvnyrtket vizsgltuk meg. Az egsz szmok intervallumhoz mint azt lttuk elkszthet egy klasszikus sorrend felsorol, amely ppen gy kpes az intervallumot bejrni, ahogy azt az intervallumos programozsi ttelekben lttuk.. Ezek alapjn ltalnosthatjuk az intervallumos programozsi tteleinket brmilyen ms felsorol tpusra is. A feladatokat ilyenkor nem intervallumon rtelmezett fggvnyekre, hanem egy felsorolra, pontosabban a felsorol ltal felsorolt rtkeken rtelmezett fggvnyekre mondjuk ki. A megold programokban az intervallumot befut i helyett a Current(), az i:=m rtkads helyett a First(), az i:=i+1 rtkads helyett a Next(), s az i>n felttel helyett az End() mveletet hasznljuk. Az gy kapott ltalnos ttelekre aztn brmelyik konkrt felsorolra megfogalmazott sszegzs, szmlls, maximum vagy adott tulajdonsg elem keresse visszavezethet. Ezek kztt termszetesen az intervallumon rtelmezett fggvnyekkel megfogalmazott feladatok is, teht a korbban megszerzett feladatmegoldsi tapasztalataink sem vesznek el. A programozsi ttelek ehhez hasonl ltalnostsaival egyszeregyszer mr korbban is tallkoztunk. Mr korbban is oldottunk meg olyan feladatokat, ahol nem intervallumon rtelmezett fggvnyre, hanem vektorra alkalmaztuk a tteleinket. Ezt eddig azzal magyarztuk, hogy a vektor felfoghat egy tblzattal megadott egsz intervallumon rtelmezett fggvnynek. Most mr egy msik magyarzatunk is van. Az intervallum s a vektor rokon tpusok: mindketthz kszthet felsorol. Egy felsorolra megfogalmazott sszegzs, szmlls, maximum vagy adott tulajdonsg elem keress sorn pedig mindegy,

194

8.4. Programozsi ttelek ltalnostsa

hogy egy intervallumon rtelmezett fggvny rtkeit kell-e sorban megvizsglni vagy egy vektornak az elemeit, hiszen ezeket az rtkeket gyis a felsorols lltja el. Hangslyozzuk, hogy az ltalnos programozsi ttelekben nem kzvetlenl a felsorolt elemeket dolgozzuk fel (adjuk ssze, szmoljuk meg, stb.), hanem az elemekhez hozzrendelt rtkeket. Ezeket az rtkeket bizonyos tteleknl (pl. sszegzs, maximum kivlaszts) egy f:EH fggvny (ez sokszor lehet az identits), msoknl (pl. szmlls, keress) egy :E logikai fggvny jelli ki. Ennek kvetkeztben a feldolgozs sorn ltalban nem a t.Current() rtkeket, hanem az f(t.Current()) vagy (t.Current()) rtkeket kell vizsglni. A specifikcik utfelttelben egy felsorols elemeire hivatkozhatunk indexelssel (lvn egy absztrakt sorozat a felsorol htterben), de a visszavezets szempontjbl ez sok lnyegtelen elemet tartalmaz. Ezrt egy j specifikcis jellst is bevezetnk: az e t kifejezssel (amelyik nem halmazmveletet jell, hiszen a t nem egy halmaz, hanem egy felsorol) azt a szndkot fejezzk ki, hogy az e vltozban sorban egyms utn jelenjenek meg a t felsorols elemei.

195

8. Programozsi ttelek felsorol objektumokra

1. sszegzs Feladat: Adott egy E-beli elemeket felsorol t objektum s egy f:EH fggvny. A H halmazon rtelmezzk az sszeads asszociatv, baloldali nullelemes mvelett. Hatrozzuk meg a fggvnynek a t elemeihez rendelt rtkeinek sszegt! (res felsorols esetn az sszeg rtke definci szerint a nullelem: 0). Specifikci: A = (t:enor(E), s:H) Ef = ( t=t )
t'

Algoritmus: s := 0 t.First() t.End() s := s+f(t.Current()) t.Next()

Uf = ( s =
i 1

f (ti, ) ) =
f(e) )

=( s
e t'

2. Szmlls Feladat: Adott egy E-beli elemeket felsorol t objektum s egy :E felttel. A felsorol objektum hny elemre teljesl a felttel? Specifikci: A = (t:enor(E), c:) Ef = ( t=t )
t'

Algoritmus: c:=0 t.First() t.End() ( t.Current() ) c := c+1 t.Next() SKIP

Uf = ( c
i 1 ,) (t i

1 )=

=( c

1)
e t' ( e )

196

8.4. Programozsi ttelek ltalnostsa

3. Maximum kivlaszts Feladat: Adott egy E-beli elemeket felsorol t objektum s egy f:EH fggvny. A H halmazon definiltunk egy teljes rendezsi relcit. Feltesszk, hogy t nem res. Hol veszi fel az f fggvny a t elemein a maximlis rtkt? Specifikci: A = (t:enor(E), max:H, elem:E) Ef = ( t=t t >0 )
' Uf = ( ind [1.. t ]:elem= t ind ' max=f( t ind )= max f(ti, ) ) =

t'

i 1

= ( (max, ind ) = ( max, elem

, , max f(ti ) elem= tind ) =


i 1

t'

max f(e) )
e t'

Algoritmus: t.First() max, elem:= f(t.Current()), t.Current() t.Next() t.End() f(t.Current())>max max, elem:= f(t.Current()), t.Current() t.Next() SKIP

197

8. Programozsi ttelek felsorol objektumokra

4. Kivlaszts Feladat: Adott egy E-beli elemeket felsorol t objektum s egy :E felttel. Keressk a t bejrsa sorn az els olyan elemi rtket, amely kielgti a :E felttelt, ha tudjuk, hogy biztosan van ilyen. Specifikci: A = (t:enor(E), elem:E) Ef = ( t=t i [1.. t ]: (ti) ) Uf = ( ind [1.. t ]: elem=tind (elem) = ( (ind,t) j [1..ind-1]: ( t 'j ) t = t[ind+1.. t ] ) = Algoritmus: t.First() (t.Current()) t.Next() elem:=t.Current()

' ' select (t ind ) elem= tind ) = ( (elem, t) select (elem) ) ind 1 elem t '

5. Lineris keress Feladat: Adott egy E-beli elemeket felsorol t objektum s egy :E felttel. Keressk a t bejrsa sorn az els olyan elemi rtket, amely kielgti a felttelt. Specifikci: A = (t:enor(E), l: , elem:E) Ef = ( t=t )
' Uf = ( l= i [1.. t ]: ( ti ) l ind [1.. t ]:elem=tind (elem)

Algoritmus: l := hamis; t.First() l t.End()

elem := t.Current() l := (elem) t.Next()

j [1..ind-1]:
t'

(t j )

'

t = t[ind+1.. t ] ) = = ( (l,ind,t)
' search (t i ) i 1
' elem= tind ) = ( (l, elem,t)

search (e) )
e t'

198

8.4. Programozsi ttelek ltalnostsa

6. Feltteles maximumkeress Feladat: Adott egy E-beli elemeket felsorol t objektum, egy :E felttel s egy f:EH fggvny. A H halmazon definiltunk egy teljes rendezsi relcit. Hatrozzuk meg t azon elemeihez rendelt f szerinti rtkek kztt a legnagyobbat, amelyek kielgtik a felttelt. Specifikci: A = (t:enor(E), l: , max:H, elem:E) Ef = ( t=t )
' Uf = ( l = i [1.. t ]: ( ti )

' ind [1.. t ]: elem= t ind


' f( ti ) max) ) =

(elem)

max=f(elem)
t'

' i [1.. t ]: ( ( ti )

= ( (l, max, ind) = max f(t i, )


i 1 (t' i)

' elem= tind )=

= ( (l, max, elem) = max f(e) )


e t' (e)

Algoritmus: l:= hamis; t.First() t.End() (t.Current()) SKIP (t.Current()) l ( t.Current()) l

f(t.Current())>max max, elem:= f(t.Current()), t.Current() t.Next() SKIP

l, max, elem := igaz, f(t.Current()), t.Current()

199

8. Programozsi ttelek felsorol objektumokra

Az ltalnostott programozsi ttelekhez az albbi megjegyzseket fzzk: 1. A programozsi ttelek alkalmazsakor ha krltekinten jrunk el szabad az algoritmuson hatkonysgot javt mdostsokat tenni. Ilyen pldul az, amikor ahelyett, hogy sokszor egyms utn lekrdezzk a t.Current() rtkt (mikzben a Next()-tel nem lpnk tovbb), azt az rtket az els lekrdezsnl egy segdvltozba elmentjk. A maximum kivlaszts illetve feltteles maximumkeress esetn a feldolgozs eredmnyei kztt szerepel mind a megtallt maximlis rtk, mind pedig az elem, amelyhez a maximlis rtk tartozik. Konkrt esetekben azonban nincs mindig mindkettre szksg. Pldul olyan esetekben, ahol a f fggvny identits, azaz egy elem s annak rtke megegyezik, a maximlis elem s maximlis rtk kzl elg csak az egyiket nyilvntartani az algoritmusban. 2. Kivlasztsnl nem kell a felsorol ltal szolgltatott rtksorozatnak vgesnek lennie, hiszen ez a ttel ms mdon garantlja a feldolgozs vges lpsben trtn lellst. 3. A lineris keressnl s kivlasztsnl az eredmnyek kztt szerepel maga a felsorol is. Ennek az oka az, hogy ennl a kt ttelnl korbban is lellhat a feldolgozs, mint hogy a felsorols vget rne, s ekkor maradnak mg fel nem sorolt (fel nem dolgozott) elemek. Ezeket az elemeket tovbbi feldolgozsnak lehet alvetni, ha a felsorolt tovbb hasznljuk. Felhvjuk azonban a figyelmet arra, hogy ha egy mr korbban hasznlt felsorolval dolgozunk tovbb, akkor nem szabad majd a First() mvelettel jraindtani a felsorolst. 4. Nevezetes felsorolk alkalmazsa esetn rdemes sajt specifikcis jellseket bevezetni. Ilyenkor ugyanis a specifikcit nem egy absztrakt felsorolra (t:enor(E)), hanem kzvetlenl a feldolgozand gyjtemnyre (intervallumra, tmbre, halmazra, szekvencilis fjlra) fogalmazzuk a felsorolshoz hasznlt segdadatokkal. a) Egy szekvencilis inputfjl felsoroljt maga a szekvencilis inputfjl, az abbl utoljra kiolvasott elem s az olvass sttusza reprezentlja. Szekvencilis inputfjlok feldolgozsa esetn ehhez a megllaptshoz igazthatjuk a specifikcis jellseket. Ilyenkor az llapottrben magt a szekvencilis inputfjlt vesszk fel, s az e x (x a szekvencilis inputfjl) azt jelli, hogy sorban egyms utn ki akarjuk

200

8.4. Programozsi ttelek ltalnostsa

olvasni az x fjl (amely egy sorozat) elemeit. Ennl fogva a korbban bevezetett specifikcis jellsekben szerepl e t (ahol t a felsorol kiindul llapota) szimblumot szekvencilis inputfjl bejrsakor kicserlhetjk az e x (x a szekvencilis inputfjl kezdeti llapota) szimblumra. Az e x jells termszetesen nem azt jelenti, hogy az utoljra kiolvasott elemet tartalmaz vltozt a programban is e-nek kell elnevezni, de clszer ezt tenni. sszegzs: szmlls:
s
e x'

f(e)

1
e x' (e)

maximum kivlaszts:

max,elem

max f(e)
e x'

feltteles maximumkeress: l,max,elem

max f(e)
e x' (e)

Lthattuk, hogy a kivlaszts s a lineris keress azeltt is lellhat, hogy a felsorols befejezdne, s ezrt fontos eredmnye ezen programozsi tteleknek ez a be nem fejezett felsorol is. Amennyiben az st,e,x:read mveletet hasznljuk a x szekvencilis inputfjl bejrsra, akkor a megkezdett t felsorolt az st, e, x hrmassal helyettesthetjk a specifikcis jells baloldaln. lineris keress: l,elem,(st ,e,x) search (e)
e x'

kivlaszts:

elem,(st,e,x)

elem x'

select (elem)

Az st s az e azonban redundns informcit hordoz. Kivlasztsnl az elem azonos az e-vel, az st pedig biztosan norm, hiszen ilyenkor garantltan tallunk keresett elemet. Lineris keressnl st=abnorm, ha a keress sikertelen (azaz l rtke hamis); sikeres terminlskor (ha l igaz) az elem azonos az e-vel, az st pedig biztosan norm. Ezrt megengedjk a fenti jells minden olyan egyszerstst, ami nem megy az egyrtelmsg rovsra. Ilyen pldul az albbi: lineris keress: l,elem,x search (e)
e x'

kivlaszts:

elem,x

elem x'

select (elem)

201

8. Programozsi ttelek felsorol objektumokra

b) Egy h halmaz felsoroljt maga a h halmaz reprezentlja. Ilyenkor a specifikcinl e t (ahol t a felsorol kiindul llapota) szimblum helyett az e h (h a halmaz kezdeti llapota) szimblumot rhatjuk. Jelentse: vegyk sorban egyms utn a halmaz elemeit. c) Indexelhet gyjtemnyek (vektor, mtrix, sorozat, stb.) esetn a felsorolt a gyjtemny s az azon vgigvezetett index (mtrixoknl indexpr) reprezentljk. Tulajdonkppen ilyenkor kzvetlenl nem is a gyjtemnyben trolt rtkeket, hanem azok indexeit soroljuk fel, hiszen egy indexhez brmikor hozzrendelhet az ltala megjellt rtk. Ilyenkor pldul egy maximum kivlasztsnl az f fggvny sohasem identits, mert az f rendeli az indexhez (a felsorolt elemhez) a gyjtemny megfelel rtkt. A specifikcikban szerepl elem ilyenkor egy indexet tartalmaz, ezrt az albbiakban ind-knt (mtrixok esetn dupla indexknt: ind, jnd) jelentjk meg. Ezen megfontolsok miatt hasznlhatjuk a korbbi fejezetek specifikcis jellseit, amelybl az is lthat, hogy a korbbi intervallumos programozsi ttelek a felsorols ttelek specilis esetei. sszegzs: szmlls:
n

s=
i m

f(v[i] )
n

c
i m (v[i ] )

1)
n

maximum kivlaszts: feltteles maximumkeress:

max, ind = max f(v[i] )


i m

l, max, ind = max f(v[i ] )


i m (v[i ] )

lineris keress: kivlaszts:

l , ind
ind

search (v[i ] )
i m

select (v[i] )
i m

Mr tbbszr felhvtuk a figyelmet arra, hogy a keress s kivlaszts elbb lellhat, mint maga a felsorols. Vektorok esetn a

202

8.4. Programozsi ttelek ltalnostsa

mg fel nem dolgozott elemek az ind index utn llnak, ezrt azok kln jellsre nincs szksg. d) Az nm-es mtrixokra bevezetett specifikcis jellsek (standard felsorols esetn) csak abban trnek el a vektoroktl, hogy indexprokat tartalmaznak.
n, m

sszegzs:

s=
i 1, j 1
n, m

f(a[i, j ] )

szmlls:

c
i 1, j 1 (a[i , j ] )

maximum kivlaszts: feltteles maximumkeress:

max, ind, jnd = max f(a[i, j ] )


i 1, j 1

n, m

l, max, ind, jnd =

i 1, j 1 (a[i , j ] )

max

n, m

f(a[i, j ] )

lineris keress: kivlaszts:

l , ind, jnd

i 1, j 1

search (a[i, j ] )
m

n, m

ind, jnd

i 1, j 1

select (a[i, j ] )

203

8.5. Visszavezets nevezetes felsorolkkal A most bevezetett ttelek segtsgvel egyszerv vlik az olyan feladatok megoldsa, amelyek felsorolt rtkek sszegzst, megszmolst, azok kzl maximum kivlasztst vagy adott tulajdonsg keresst rjk el. Ha a feladat specifikcijban rmutatunk arra, hogy milyen felsorolra vonatkozik a feladat (hogyan kell implementlni a First(), Next(), End() s Current() mveleteket) s milyen programozsi ttel alapjn kell a felsorolt rtkeket feldolgozni (mi helyettesti az adott programozsi ttelben szerepl fggvnyt, fggvnyeket), akkor visszavezetssel knnyen megkaphatjuk a megoldst. Radsul, ha az alkalmazott felsorols a 8.3. alfejezetben rszletesen trgyalt nevezetes felsorolk egyike, akkor nagyon egyszer lesz a dolgunk. Most ez utbbi esetre mutatunk nhny pldt, amellyekkel azt kvnjuk illusztrlni, hogy a fentiekkel milyen ers eszkzt kaptunk a mdszeres programtervezs szmra. (Azon feladatok megoldsval, amelyek megoldshoz egyedi mdon kell a felsorolt megtervezni, a kvetkez fejezetben foglalkozunk.) Elszr nagyon egyszer, a visszavezets technikjt bemutat feladatokat oldunk meg. Az els kt feladatban halmazok illetve szekvencilis inputfjl feldolgozsrl, s a maximum kivlaszts s kivlaszts tteleinek alkalmazsrl lesz sz. Utna egy mtrixos feladat megoldsa kvetkezik. Vgl az gynevezett elemenknti feldolgozsokra, az sszegzs ttelnek specilis alkalmazsaira mutatunk pldkat. Itt az sszegzs eredmnye is egy gyjtemny, az sszeads mvelete e gyjtemnybe trtn j elem bersa. 8.1. Plda. Egy halmaz egsz szmokat tartalmaz. Keressk meg a halmaz maximlis elemt! A feladat specifikcijnak felrsa nem jelent problmt. Az utfelttelbl ltszik, hogy itt egy halmaz elemeinek felsorolsra ptett maximum kivlasztsrl van sz.

204

8.5. Visszavezets nevezetes felsorolkkal

A = (h:set(), max:) Ef = ( h=h ) Uf = ( max = max e )


e h'

Ebben a specifikciban nem jelenik meg explicit mdon a felsorol, de talakthat gy, hogy annak llapotterben a halmaz helyett, a halmaz elemeit felsorol objektum szerepeljen: A = (t:enor(), max:) Ef = ( t=t ) Uf = ( max = max e )
e t'

Ez a forma nem mond el tbbet a feladatrl, mint az elz, de az ltalnos maximum kivlaszts programozsi ttelre val visszavezets most mr formlisan vgrehajthat: az ltalnos specifikci s az itt lthat specifikci nhny, jl azonosthat ponton tr csak el. A felsorol egsz szmokat llt el, a feldolgozst vgz fggvny pedig az egsz szmokon rtelmezett identits. E ~ H ~ f(e) ~ e Az identits miatt a feldolgozsnak most csak egy eredmnye (max) van, hiszen a megtallt maximlis rtk elem s annak rtke egy s ugyanaz. Ennek megfelelen talaktjuk az ltalnos algoritmust: t.First() max:= t.Current() t.Next() t.End() t.Current()>max max:=t.Current() t.Next() SKIP

205

8. Programozsi ttelek felsorol objektumokra

Ezek utn foglalkozunk a felsorol mveletekkel. A h halmaz felsorolsa ismert (lsd 8.3. alfejezet), gy a mveletek implementcija adott: First() ~ SKIP, End() ~ h= , Current() ~ mem(h), Next() ~ h:=h-{mem(h)}. Ezek alapjn elkszthet a feladatot megold program vgs vltozata. Ebben egy segdvltozt vezettnk be annak rdekben, hogy ne kelljen a mem(h)-t ugyanarra a h-ra tbbszr egyms utn vgrehajtani. A felsorolt a h halmaz reprezentlja. max:= mem(h) h:=h-{max} h e:= mem(h) e>max max:= e h:=h-{e} A gyakorlatban termszetesen nem kell ennyire rszletesen dokumentlni a visszavezets lpseit. A fenti gondolatmenetbl elegend a feladat eredeti specifikcijt, a visszavezets analgijt (itt maximum kivlaszts: E ~ Z, H ~ Z s f(e) ~ e), a felsorol mveleteit (itt elg a h halmaz nevezetes felsorolsra hivatkozni, mert ebbl kvetkezik, hogy a First() ~ SKIP, End() ~ h= , Current() ~ mem(h), Next() ~ h:=h-{mem(h)}), s vgl az algoritmust megadni. 8.2. Plda. Keressk meg egy szekvencilis inputfjlban tallhat szveg els szavnak kezdett! Ez a feladat gyakori rsze a szveg feldolgozsi problmknak. Vagy az els nem szkz karaktert kell megtallnunk, vagy ha ilyen nincs, akkor a fjl vgt; s ez az sszetett felttel biztosan teljesl. A fjl elemeinek felsorolshoz az st,e,x:read mveletet hasznljuk, ahol az st az olvass sttuszt, e a kiolvasott karaktert tartalmazza. Ha a fjl csak szkzkbl ll, akkor a feldolgozs st=abnorm felttellel lljon le. Ha lellskor st=norm, akkor az e tartalmazza a keresett els nem SKIP

206

8.5. Visszavezets nevezetes felsorolkkal

szkz karaktert, s a mg fel nem sorolt karakterek az f szekvencilis inputfjlban maradnak. Ezt tkrzi az albbi specifikci. A = (f:infile( ), st:Sttusz, e: ) Ef = ( f=f ) Uf = ( e, f select ( st abnorm e ' ' ) )
e f'

A feladatot a kivlaszts programozsi ttelre vezetjk vissza az f szekvencilis inputfjl felsorolsval. Visszavezets E ~ (e) ~ st=abnorm e First() Next() Current() End() A visszavezetssel ellltott megolds: st,e,f:read st=norm e= ~ ~ ~ ~ Felsorols felsorol

f:infile( ), st:Sttusz, e: st,e,f:read st,e,f:read e st = abnorm

st,e,f:read Ktdimenzis jellegnl fogva a mtrixokra rtelmezett maximum kivlaszts s lineris keress is rdekes tanulsgokkal jr. 8.3. Plda. Keressnk egy egsz elem mtrixban egy pros szmot s adjuk meg annak indexeit!

207

8. Programozsi ttelek felsorol objektumokra

A = (a: nm, l: , ind:, jnd:) Ef = ( a=a ) Uf = ( a=a

l , (ind , jnd )

i 1,j 1

search 2 a[i, j ] )

n, m

A feladat visszavezethet a lineris keress ttelre a mtrix indexprjainak sorfolytonos felsorolsa mellett. Visszavezets E ~ (i,j) ~ 2 a[i,j] Felsorols felsorol First() Next()

~ a: nm, i, j: ~ i, j:=1,1 ~ ha j=m akkor i, j:=i+1,1 klnben j:=j+1 ~ i, j ~ i>n

Current( ) End() A visszavezetssel ellltott megolds: l, i, j:=hamis, 1, 1 l i n

l, ind, jnd := 2 a[i,j], i, j j<m j:=j+1 i, j:=i+1, 1

Ahogy azt korbban mr jeleztk, ennek a megoldsnak megadhat dupla szmlls ciklusos vltozata:

208

8.5. Visszavezets nevezetes felsorolkkal

l, i:=hamis, 1 l i n j:=1 l jm

l, ind, jnd := 2 a[i,j], i, j j:=j+1 i:=i+1 Egy felsorol tpus adat feldolgozsnak gyakori esete az, amikor a kimen adat is elemi rtkek gyjtemnye (pldul halmaz, sorozat, vektor vagy szekvencilis outputfjl). Amikor a bemen felsorol adat aktulis elemt feldolgozzuk, a feldolgozs eredmnyeknt kapott j elemmel vagy elemekkel kibvtjk a kimen adatot (halmazhoz hozzunizunk, sorozathoz hozzfznk, stb.). Mivel a kimen adat megvltoztatsa (az uni, hozzfzs, stb.) egy baloldali egysgelemes asszociatv mvelet, ezen feladatok megoldst az sszegzs programozsi ttelre vezethetjk vissza. Ha egy ilyen feladatra mg az is igaz, hogy a bemen adat egy elemnek feldolgozsa nem fgg ms tnyeztl (nem fgg a bemen adat tbbi elemtl vagy a kimen adattl) csak magtl a feldolgozand elemtl, azaz a bemen adat feldolgozsa annak felsorolsra pl, akkor a feladatot elemenknt feldolgozhatnak, a megoldst elemenknti feldolgozsnak nevezzk. Ltezik az elemenknti feldolgozsnak egy ennl mg szigorbb rtelmezse is, amely szerint az eddig felsorolt feltteleken tl annak is teljeslnie kell, hogy egy-egy elem feldolgozsnak eredmnye a kimen adat tbbi elemtl se fggjn, azaz az eredmnnyel a kimen adatot annak tbbi elemtl fggetlenl lehessen bvteni. Az elemenknt feldolgozhat feladatosztlyhoz tartozik az adatfeldolgozs szmos alapfeladata: a msols, a kivlogats, a sztvlogats, stb. Hangslyozzuk azonban, hogy ezek a feladatok mind az sszegzs programozsi ttelre vezethetk vissza. Oldjunk meg elszr kt szigoran elemenknt feldolgozhat feladatot, amikor egy elem feldolgozsnak eredmnye nem fgg attl, hogy a kimeneti gyjtemny milyen elemeket tartalmaz ppen. Utna egy

209

8. Programozsi ttelek felsorol objektumokra

olyan elemenknti feldolgozst lthatunk, ahol ez a felttel nem teljesl. Ezt kveten egy olyan elemenknti feldolgozsrl lesz sz, ahol egy bemeneti gyjtemnybl hrom kimeneti gyjtemnyt kell egyszerre ellltani. 8.4. Plda. Msoljunk t egy karaktereket tartalmaz szekvencilis inputfjlt egy outputfjlba gy, hogy minden karaktert megduplzunk! A = (x:infile( ), y:outfile( )) Ef = ( x=x ) e, e ) Uf = ( y
e x'

Az utfelttelben hasznlt mvelet az sszefzs (konkatenci) jele. Ez egy asszociatv mvelet, amelynek az res sorozat a nulla eleme. Ezrt a feladat az sszegzs programozsi ttelre vezethet vissza gy, hogy a feldolgozs egy szekvencilis inputfjlra, annak nevezetes felsorolsra pl. Specilisan ez a feladat egy elemenknti feldolgozs (rtkek sszefzse), amely egy szekvencilis fjlbl (felsorolshoz hasznlt mvelet: st,e,x:read) olvassa azokat az elemeket, amelyekbl sszelltott rtkeket egy msik (szekvencilis output) fjlba r: E +,0 f(e) s ~ ~ ~ ~ y ,<> <e,e>

A szekvencilis outputfjlhoz a write mvelettel lehet hozzfzni egy jabb sorozatot, azaz egy y:=y <e,e> rtkadst az y:write(<e,e>) implementl.

210

8.5. Visszavezets nevezetes felsorolkkal

y:=<> st,e,x:read st = norm y:write(<e, e>) st,e,x:read Ltjuk, hogy az elemenknti feldolgozhat feladatok egy bemen adatelemhez nem felttlenl csak egy kimen adatelemet lltanak el, ugyanakkor nagyon gyakoriak azok a feladatok (ilyen a kvetkez), amelyek a bemen adat egy elemhez vagy egy j elemet, vagy semmit sem rendelnek. 8.5. Plda. Vlogassuk ki egy egsz szmokat tartalmaz halmazbl a pros szmokat, s helyezzk el ket egy msik halmazba! A feladat egy halmaz felsorolsn rtelmezett sszegzs (valjban unizs, amelynek null-eleme az res halmaz), ahol a feldolgozs f: 2 fggvnye egy pros szmhoz a szmot tartalmaz egy elem halmazt, pratlan szmhoz az res halmazt rendeli. A = (x:set(), y:set()) Ef = ( x=x ) Uf = ( y {e} )
e x' e pros

Az ilyen esetsztvlaszts f fggvnyre pl sszegzst lehetne feltteles sszegzsnek hvni. Ennek programjban megjelen y:=y f(e) rtkadst egy elgazs valstja meg, amelyben y:=y {e} rtkads vagy a SKIP program szerepel.24
24

Megjegyezzk, hogy itt az y:=y {e} rtkads implementcija itt egyszerbb, mint ltalban. Ugyanis biztosak lehetnk abban, hogy az e elem mg nincs az y halmazban, ezrt ezt nem is kell kln vizsglni. Az elem-uni mveletnek teht ugyangy az egyszerstett vltozatval dolgozhatunk itt, mint az x:=x{e} elemkivons esetben, ahol meg azt nem kell ellenrizni, hogy az e elem tnyleg benne van-e az x halmazban.

211

8. Programozsi ttelek felsorol objektumokra

A megolds teht egy elemenknti feldolgozs (egy gynevezett kivlogats) halmazbl halmazba: E +,0 f(e) s ~ ~ ~ ~ , ha e pros akkor {e} klnben y

y:= x e:=mem(h) e pros y:=y {e} x:=x{e} 8.6. Plda. Msoljuk t egy egsz szmokat tartalmaz vektorbl egy halmazba az elemek 7-tel vett osztsi maradkait! A feladat egy vektor szoksos felsorolsn rtelmezett sszegzs, ahol a feldolgozs fggvnye az adott elemnek 7-tel vett osztsi maradkt lltja el, amelyet az eredmny halmazhoz kell unizni. Ennek a lpsnek a hatsa nem fggetlen az eredmny halmaz tartalmtl, hiszen ha az jonnan hozzadand maradk mr szerepel a halmazban, akkor a halmaz nem fog megvltozni. A = (x:n, y:set()) Ef = ( x=x ) Uf = ( y
i 1

SKIP

{xi mod 7} )

Ez egy elemenknti feldolgozs (egy unizs) vektorbl halmazba:

212

8.5. Visszavezets nevezetes felsorolkkal

E +,0 f(i) s

~ ~ ~ ~

, {xi mod 7} y y:= i = 1 .. n y:=y {xi mod 7}

(rdekes, hogy ha ugyanez a feladat az eredmnyt egy sorozatba fzve krn s megengednnk azt, hogy ugyanazt a maradkot tbbszr is betegyk oda erre a sorozat lehetsget ad , akkor mr szigoran elemenknt feldolgozhat feladatrl beszlhetnk.) A kvetkez plda egy szigoran elemenknt feldolgozhat feladat, amelynek az a sajtossga, hogy ugyanazon a gyjtemnyen tbb, egymstl fggetlen feldolgozst kell elvgezni. Az ilyen feladat teljesen nll rszfeladatokra bonthat, majd a rszmegoldsokat a kzs gyjtemny bejrsra szervezett egyetlen ciklusba lehet sszevonni. Az gy kapott megoldst sztvlogatsnak is szoktk nevezni. 8.7. Plda. Vlogassunk szt egy szekvencilis inputfjlban rgztett bngyi nyilvntartsbl egy outputfjlba, egy halmazba s egy vektorba a gyanstottakat aszerint, hogy az illet 180 cm-nl magasabb-e s barna haj, vagy fekete haj s 60 kg-nl knnyebb, vagy fekete haj s nincs alibije! Az llapottrnek egy szekvencilis inputfjl a bemen adata, a kimen adatai pedig egy szekvencilis outputfjl, egy halmaz s egy vektor. Az llapottr a vektorrl csak annyit mond, hogy az egy kellen hossz vges sorozat, s majd az utfelttel fogja a vektor els n elemt jellemezni. A = (x:infile(Ember), y:outfile(Ember), z:set(Ember), v: Ember*, n:) Ember=rec(nv: *, mag:, sly:, haj: *, alibi: )

213

8. Programozsi ttelek felsorol objektumokra

Ef = ( x=x ) Uf = ( y

e x' e.mag 180 e.haj 'barna'

e x' e.sly 60 e.haj ' fekete'

{e}

v[1..n]

e x' e.haj ' fekete' e.alibi

A specifikciban jl elklnl a feladat hrom nllan is megoldhat rsze. Mindhrom egy esetsztvlasztsos fggvny sszegzsre pl, amelyhez ugyanazon x szekvencilis inputfjl st,e,x:read segtsgvel soroljuk fel az elemeket. Itt hrom elemenknti feldolgozs (hrom kivlogats) szerepel, amelyek ugyanazon szekvencilis fjlbl (st,e,x:read) egy szekvencilis fjlba, egy halmazba s egy sorozatba rnak: E H +,0 s f(e) ~ ~ ~ ~ ~ Ember Ember* ,<> y <e> ha e.mag>180 e.haj = barna Ember 2Ember , z {e} ha e.sly<60 e.haj = fekete Ember Ember* ,<> v <e> ha e.haj = fekete e.alibi n:=0 st,e,x:read st = norm e.haj=fekete e.alibi n:=n+1 SKIP v[n]:=e st,e,x:read

y:=<> st,e,x:read st = norm e.mag>180 e.haj=barna y :write(e) SKIP st,e,x:read

z:= st,e,x:read st = norm e.sly<60 e.haj=fekete z:=z {e} SKIP st,e,x:read

214

8.5. Visszavezets nevezetes felsorolkkal

A megolds csak akkor hatkony, ha a szekvencilis inputfjl elemeit egyszer jrjuk be. A hrom klnll megoldst egyetlen cikluss vonhatjuk ssze (lsd 6.3. alfejezetbeli programtalaktsokat), s a szekvencilis inputfjl minden elemt annyi szempont szerint dolgozzuk fel, ahny kimen adat van. y:=<>; z:= ; n:=0 st,e,x:read st= norm e.mag>180 y:write(e) e.sly<60 z:=z {dx} e.haj=fekete n:=n+1; v[n]:=e st,e,x:read e.haj=barna SKIP e.haj=fekete SKIP e.alibi SKIP

215

8. Programozsi ttelek felsorol objektumokra

8.6. Feladatok Adott az egsz szmokat tartalmaz x vektor. Vlogassuk ki az y sorozatba a vektor pozitv elemeit! 8.2. Szmoljuk meg egy halmazbeli szavak kztt, hogy hny a betvel kezdd van! 8.3. Egy szekvencilis inputfjl egsz szmokat tartalmaz. Keressk meg az els nem-negatv elemt! 8.4. Egy szekvencilis fjlban egy bank szmlatulajdonosait tartjuk nyilvn (azonost, sszeg) prok formjban. Adjuk meg annak az azonostjt, akinek nincs tartozsa, de a legkisebb a szmlaegyenlege! 8.5. Egy szekvencilis fjlban minden tutalsi bettszmla tulajdonosrl nyilvntartjuk a nevt, cmt, azonostjt, s szmlaegyenlegt (negatv, ha tartozik; pozitv, ha kvetel). Ksztsnk kt listt: rjuk ki egy output fjlba a htralkkal rendelkezk, egy msikba a tlfizetssel rendelkezk nevt! 8.6. Egy szekvencilis inputfjlban egyes kaktuszfajtkrl ismernk nhny adatot: nv, shaza, virgszn, mret. Vlogassuk ki egy szekvencilis outputfjlba a mexiki, egy msikba a piros virg, egy harmadikba a mexiki s piros virg kaktuszokat! 8.7. Adott egy egsz szmokat tartalmaz szekvencilis inputfjl. Ha a fjl tartalmaz pozitv elemet, akkor keressk meg a fjl legnagyobb, klnben a legkisebb elemt! 8.8. Egy szekvencilis inputfjl (megengedett mvelet: read) egy vllalat dolgozinak adatait tartalmazza: nv, munka tpus (fizikai, adminisztratv, vezet), havi br, csald nagysga, tlraszm. Vlasszuk ki azoknak a fizikai dolgozknak a nevt, akiknl a tlraszm meghaladja a 20-at, s csaldtagok szma nagyobb 4-nl; adjuk meg a fizikai, adminisztratv, vezet beoszts dolgozk tlagos havi brt! 8.9. Adott kt vektorban egy angol-latin sztr: az egyik vektor iedik eleme tartalmazza a msik vektor i-edik elemnek jelentst. Vlogassuk ki egy vektorba azokat az angol szavakat, amelyek szalakja megegyezik a latin megfeleljvel. 8.10. Alaktsunk t egy magyar nyelv szveget tvirati stlusra! 8.1.

216

9. Visszavezets egyedi felsorolkkal


Ebben a fejezetben az ltalnos programozsi tteleket olyan feladatok megoldsra alkalmazzuk, ahol nem lehet nevezetes felsorolkat hasznlni, a First(), Next(), End() s Current() mveletek ellltsa egyedi tervezst ignyel. Gyakoribbak azonban az olyan feladatok, ahol egy nevezetes gyjtemny elemeit kell bejrni, de nem a megszokott mdon, ezrt egyltaln nem, vagy csak mdostva hasznlhatjuk az azokon megszokott nevezetes felsorolkat. Ez utbbira plda az, amikor egy vektor elemeit nem egyesvel kell bejrni, ezrt a Next() mveleten vltoztatni kell; vagy nem elejtl a vge fel, hanem fordtva, s ehhez a First(), Next(), s End() mveleteket kell jragondolni. Ilyen egy nevezetes gyjtemnynek az gynevezett felttel fennllsig tart feldolgozsa (9.2. alfejezet) is, amikor az elemeket csak addig kell bejrni, amg azokra egy adott felttel teljesl. Ehhez az End() mvelet megfelel fellrsa szksges. A 9.1. alfejezet egy ktdimenzis gyjtemnynek (egy mtrixnak) bizonyos elemeit sorolja csak fel. rdekesek azok a feladatok (9.3. alfejezet), ahol egy gyjtemny elemeit csoportostva, csoportokra bontva kell feldolgozni, s egy felsorolnak ezeket a csoportokat kell valamilyen formban bejrni. Egyedi felsorolra van szksg akkor is, ha egy rekurzv fggvny ltal ellltott rtkekre van szksgnk (9.5. alfejezet), vagy ha egyidejleg tbb gyjtemny elemeit kell szimultn mdon bejrni (9.4. alfejezet). A 9.6. alfejezet olyan egyedi felsorolra mutat pldt, amelynek htterben egyltaln nincs gyjtemny.

9. Visszavezets egyedi felsorolkkal

9.1. Egyedi felsorol 9.1. Plda. Adott a skon n darab pont. llaptsuk meg, melyik kt pont esik legtvolabb egymstl! Ezzel a feladattal mr tallkoztunk a 6. fejezetben. Specifikljuk jra a feladatot! A skbeli pontokat egy derkszg koordinta rendszerbeli koordinta prokkal adjuk meg; kln-kln tmbkben az x s az y koordintkat. gy az i-edik pont koordinti az x[i] s y[i] lesznek. A feladat kzponti fogalma az i-dik s j-dik pont tvolsga, amelyet tv(i,j)-vel fogunk jellni. Ezek a tvolsgok gondolatban egy nn-es szimmetrikus mtrixba rendezhetk, s a feladat tulajdonkppen ennek a mtrixnak az alshromszg rszben tallhat rtkek kztti maximum kivlaszts. A = (x:n, y:n, ind:, jnd:) Ef = ( x=x y=y n2 ) Uf = (Ef max, (ind, jnd) = max tv(i,j) )
i 2, j 1 n,i 1

ahol tv(i, j )

( x[i] x[ j ]) 2

( y[i] y[ j ]) 2

A specifikcibl lthat, hogy most a kpzeletbeli mtrix indexprjainak felsorolst nem a szoksos mdon kell megtenni, hiszen csak a mtrix alshromszg rszt kell bejrni: (2,1) (3,1) (3,2), (4,1), , (n,1), (n,2), , (n,n-1). Formlisan jraspecifiklhatnnk a feladatot gy, hogy a bemen adatok helyett egy termszetes szmok prjait bejr felsorolt vesznk fel az llapottrbe. A = (t:enor(), ind:, jnd:) Ef = ( t=t' ) Uf = ( max, (ind, jnd) = max tv(i,j) )
(i,j) t'

A felsorol First() mvelete a (2,1) index elemre kell, hogy rlljon, a Next() j<i-1 esetn nveli a j-t, j=i-1 esetn nveli az i-t s 1re lltja a j-t. Az End() akkor lesz igaz, ha i>n. Ezt a bejrst a 8.3. alfejezetben ltottakhoz hasonlan egy dupla szmlls ciklussal is lerhatjuk, amelyet a felsorol tpusra megfogalmazott maximum kivlaszts algoritmusval kell tvznnk.

218

9.1. Egyedi felsorol

max, ind, jnd,:= tv(2,1), 2, 1 i = 3 .. n j = 1 .. i-1 tv(i,j)>max max, ind, jnd,:= tv(i,j), i, j, SKIP

9.2. Felttel fennllsig tart felsorols Sokszor egy felsorols nem gy r vget, hogy a felsoroland elemek elfogynak, hanem akkor, amikor a felsorols sorn olyan elemhez rnk, amelyre mr nem teljesl egy kln megadott :E felttel. Amennyiben a felttel a felsorols egyik elemre sem lesz hamis, akkor a feldolgozs a felsorols vgn lell, azaz a felsorol End() mvelete nem kizrlag a felttel lesz, hanem a nevezetes felsorol eredeti End() mveletnek s a felttelnek vagy kapcsolata. Programozsi tteleinket mind meg lehet fogalmazni ilyen felttel fennllsig tart vltozatra a kivlaszts kivtelvel (ennl ugyanis ennek nincs sok rtelme). A felttel fennllsig tart feldolgozsokra is rvnyes az, amit korbban a lineris keressnl vagy a kivlasztsnl elmondtunk, nevezetesen, hogy korbban is lellhat a feldolgozs, mint hogy a felsorols sszes elemt bejrnnk. Ezrt az abbahagyott felsorol is eredmnye lesz az ilyen felttel fennllsig tart feldolgozsoknak, hogy ha kell, a mg fel nem sorolt (fel nem dolgozott) elemeket al lehessen vetni majd tovbbi feldolgozsnak is. A nevezetes felsorolknak felttel fennllsig tart feldolgozss alaktsakor a specifikcijban a felsorols befejezst definil :E felttelt az albbi mdon fogjuk jellni.
(e)
(e)

sszegzs illetve szmlls esetn: s, t


e t'

f ( e) , c , t
e t' (e)
(e)

1,

maximum kivlaszts esetn: max, elem , t

max f (e) ,
e t'

219

9. Visszavezets egyedi felsorolkkal

(e)

lineris keress esetn: l , elem , t

search (e) .
e t'

9.2. Plda. Adjuk meg egy szekvencilis inputfjl elejn ll pozitv szmok kztt a prosak szmt! A = ( f:infile(), e:, st:Sttusz, db: ) Ef = ( f=f )
e 0

Uf = ( db,( st, e, f) =
e f' 2e

1)

A feladatot az f szekvencilis inputfjl felsorolsra ptett szmllsra vezetjk vissza, amely azonban korbban is lellhat, ezrt a End() mveletet a megszokott st=norm helyett az st=norm e>0 kifejezs helyettesti. db:=0; st, e, f : read st=norm e>0

2 e db:=db+1 SKIP st, e, f : read 9.3. Plda. Egy szekvencilis inputfjlban egy banknl szmlt nyitott gyfelek e havi kivt/bett forgalmt (tranzakciit) troljuk. Minden tranzakcinl nyilvntartjuk az gyfl azonostjt, a tranzakci dtumt s az sszegt, ami egy eljeles egsz szm (negatv a kivt, pozitv a bett). A tranzakcik a szekvencilis fjlban gyflazonost szerint rendezetten helyezkednek el. Keressk meg az els gyfl legnagyobb sszeg tranzakcijt. A = (f:infile(Tranzakci), df:Tranzakci, sf:Sttusz, max:Tranzakci) Tranzakci = rec(azon:, dtum:, ssz:)

220

9.2. Felttel fennllsig tart felsorols

Ef = ( f=f

f azon szerint rendezett ) ' e.azon f 1.azon e.ssz ) Uf = ( max, maxelem, ( st , e, f ) max
e f'

f >0

Ezt visszavezethetjk a maximum kivlaszts ttelre. Az eredmnyek kzl nincs szksg kln a maximlis tranzakcis sszeg rtkre, hiszen azt a maximlis elem (a rekord) tartalmazza. st, maxelem, f : read st, e, f : read st=norm e.azon=maxelem.azon

e.ssz > maxelem.ssz maxelem:= e st, e, f : read SKIP

221

9. Visszavezets egyedi felsorolkkal

9.3. Csoportok felsorolsa 9.4. Plda. Tbb egyms utni napon feljegyeztk a napi tlaghmrskleteket, s azokat egy szekvencilis inputfjlban rgztettk. Volt-e olyan nap, amikor a megelz naphoz kpest cskkent az tlaghmrsklet? A = (f:infile(), l: ) Ef = ( f=f )
f'

Uf = ( l

search( f 'i f 'i 1 0) )


i 2

A feladat nem oldhat meg a szekvencilis inputfjl nevezetes bejrsval, hiszen az nem ad lehetsget a szekvencilis inputfjl egyms utn kvetkez kt elemnek egyidej vizsglatra. Helyette a szekvencilis inputfjlra tmaszkod, de attl elvonatkoztatott, absztrakt felsorolra van szksg, amely a szekvencilis inputfjl szomszdos elemprjait sorolja fel. jrafogalmazzuk teht a feladatot egy olyan llapottren, ahol adottnak vesszk az elbb kitallt felsorolt. A = (t:enor(rec(tegnap:, ma:)), l: ) Ef = ( t=t ) Uf = ( l search(e.ma e.tegnap 0) )
e t'

Az j specifikci clja az, hogy minl knnyebben lehessen a feladat megoldst a lineris keressre visszavezetni. Termszetesen a bevezetett felsorol tpust egyedi mdon kell megvalstani: reprezentlni kell az eredeti llapottr komponenseire tmaszkodva s implementlni kell a bejrs mveleteit. Ezzel lnyegben rszfeladatokra bontottuk az eredeti problmt. Rszfeladat az j llapottren megfogalmazott lineris keress, s rszfeladatok a First(), Next(), Current(), End() implementcii is. Az jrafogalmazott feladat visszavezethet az ltalnos lineris keressre, amelybl mivel ezt specilisan eldntsre hasznljuk az elem:=t.Current() rtkadst elhagyjuk. l := hamis; t.First()

222

9.3. Csoportok felsorolsa

t.End() t.Next()

l := t.Current().ma- t.Current().tegnap < 0

Implementljuk az absztrakt felsorol mveleteit. A First() mvelet feladata az els felsorolni kvnt elemre, esetnkben az els kt hmrskletre, egy tegnap-ma szmprra (ezt nem rekordknt, hanem kt vals szmknt brzoljuk) val rlls. Ehhez az f szekvencilis inputfjlbl az els hmrskletet a tegnap vltozba, a msodikat a ma vltozba kell beolvasnunk. (A kt olvass akkor is vgrehajthat, ha a fjl nem tartalmaz kt rtket.) A Next() feladata a soron kvetkez hmrsklet-prra llni. Ehhez szksg van a korbbi szmpr mai hmrskletre (a tegnapi mra), amibl az aktulis szmpr tegnapi hmrsklete (a mai tegnap) lesz, teht tegnap:=ma, valamint be kell olvasni f fjlbl a ma vltozba az aktulis mai hmrskletet is. A Current() a tegnap-ma szmprt adja vissza. Az End() addig hamis, amg sikerlt jabb szmpr ellltshoz jabb rtket olvasni az f fjlbl, azaz amg sf=norm feltve, hogy a szekvencilis inputfjlbl trtn olvass sttuszt az sf tartalmazza. A fentiekbl az is kiderl, hogy az absztrakt felsorolt a tegnap-ma szmpr, az f szekvencilis inputfjl, s az utols olvass sf sttusza reprezentlja. Behelyettestve az algoritmusba First(), Next(), Current(), End() implementciit: sf, tegnap, f : read sf, ma, f : read l:=hamis l sf=norm tegnap:=ma sf, ma, f : read

l:= ma-tegnap< 0

223

9. Visszavezets egyedi felsorolkkal

9.5. Plda. Egy szekvencilis inputfjlban egy banknl szmlt nyitott gyfelek e havi kivt/bett forgalmt (tranzakciit) troljuk. Minden tranzakcinl nyilvntartjuk az gyfl szmlaszmt, a tranzakci dtumt s az sszegt, ami egy eljeles egsz szm (negatv a kivt, pozitv a bett). A tranzakcik a szekvencilis fjlban szmlaszm szerint rendezetten helyezkednek el. Gyjtsk ki azon szmlaszmokat s az ahhoz tartoz tranzakciknak az egyenlegt, ahol ez az egyenleg kisebb 100000 Ft-nl! A = (x:infile(Tranzakci), v:outfile(Egyenleg)) Tranzakci = rec(sz: *, dtum:, ssz:) Egyenleg = rec(sz: *, ssz:) Ef = ( x=x az x sz szerint rendezett ) Uf = (?) Az utfelttelt csak nagyon krlmnyesen lehetne lerni, mert a szekvencilis inputfjl nevezetes bejrsa nem illeszkedik a feladathoz. Neknk nem a tranzakcikat, hanem egy szmla sszes tranzakciinak eredjt kell egy lpsben feldolgozni. Olyan felsorolra van szksg, amelyik egy szmlaszm mell ezt az eredt meg tudja adni, azaz amelyik az azonos szmlaszm tranzakcik csoportjt tudja egy lpsben beolvasni. Egy ilyen kitallt (absztrakt) felsorolval a specifikci megfogalmazsa jval egyszerbb. A = (t:enor(Egyenleg), v:outfile(Egyenleg)) Ef = ( t=t ) e ) Uf = ( v
e.ssz e t' 100000

Ez a feladat visszavezethet az sszegzs programozsi ttelre, ahol az f:Egyenleg Egyenleg* tpus, s ha e.ssz<-100000 (ahol e egy egyenleg), akkor f(e) megegyezik az <e> egyelem sorozattal, klnben f(e) az res sorozat. t.First() t.End() t.Current().ssz<-100000 v:write(t.Current()) t.Next() SKIP

224

9.3. Csoportok felsorolsa

Mind a First(), mind a Next() mvelet a soron kvetkez (aktulis) szmlaszm tranzakciit sszegzi. Mivel az x szekvencilis inputfjl szmlaszm szerint rendezett, gy az ugyanolyan szmlaszm tranzakcik kzvetlenl egyms utn helyezkednek el, amelyekbl az x fjl nevezetes bejrsra pl felttel fennllsig tart sszegzssel lehet ellltani az aktulis szmlaszmhoz tartoz egyenleget (egyl). Meg kell mondanunk azt is, hogy van-e egyltaln jabb feldolgozand tranzakci-csoport (vge). Az absztrakt felsorolt egyrszt az egyl:Egyenleg s vge: adatokkal, msrszt az x szekvencilis inputfjllal s annak vgigolvasshoz szksges sx:Sttusz s dx:Tranzakci adatokkal reprezentljuk. Az aktulis szmlaszm tranzakciinak egyenlegt (egyl) a Current() mvelettel krdezhetjk le, az egyenlegek felsorolsnak vgt a vge vltoz jelzi: ezt adja vissza az End(). A Next() mvelet vgrehajtsa eltt felttelezzk, hogy az x szekvencilis fjlt mr korbban elreolvastuk, s ha van mg feldolgozand szmlaszm (azaz sx=norm), akkor az ahhoz tartoz els tranzakci a dx-ben tallhat. A vge rtke az sx kezdeti rtktl fgg (vge = (sx=abnorm)). Ha a vge mg hamis, akkor az adott szmlaszmhoz tartoz sszestett egyenleget gy kell ellltani, hogy a mr megkezdett x szekvencilis inputfjl elemeit kell tovbb sorolni addig, amg a tranzakcik szmlaszma nem vltozik. Hangslyozzuk, hogy ezen felsorols els eleme kezdetben a dx-ben van, amit ugyancsak figyelembe kell venni az sszegzsben. A felsorols ezen sajtossgt (azaz hogy nem ignyel elre olvasst) a dx (sx,dx, x) szimblummal fogjuk jellni (ahol x a mr elreolvasott fjl, sx az elreolvass sttusza, sikeres elreolvass esetn dx a korbban kiolvasott elem). Amennyiben tudjuk, hogy sx=norm, akkor a bejrs jellsre a dx (dx, x) szimblumot is hasznlhatjuk, ami szemlletesen azt fejezi ki, hogy a gondolatban sszefztt dx s x elemeit kell felsorolni. A Next() mvelet amennyiben az elreolvass sikeres volt egy felttelig tart sszegzs lesz, hiszen le kell llnia akkor is, ha olyan tranzakcit olvasunk, amelyik azonostja eltr az aktulis azonosttl. ANext =(x:infile(Tranzakci), dx:Tranzakci, sx:Sttusz, vge: , egyl:Egyenleg)

225

9. Visszavezets egyedi felsorolkkal

EfNext = ( x = x

dx = dx sx = sx x azon szerint rendezett ) UfNext = ( sx=abnorm vge=igaz ( sx=norm ( vge=hamis egyl.azon= dx.azon
dx.azon egyl.azon

egyl.ssz , ( sx, dx, x)


dx ( dx', x' )

dx.ssz ) )

t.Next() sx=norm vge := hamis egyl.azon, egyl.ssz:=dx.azon, 0 sx=norm dx.azon=egyl.azon egyl.ssz := egyl.ssz+dx.ssz sx, dx, x: read A First() mvelet csak egy elreolvasssal tbb, mint Next(), hiszen itt kell elkezdeni az x fjlnak a felsorolst. Az els olvass eredmnyre a specifikci az sx, dx, x rtkekkel hivatkozik. AFirst =(x:infile(Tranzakci), dx:Tranzakci, sx:Sttusz, vge: , egyl:Egyenleg) First Ef = ( x = x x azon szerint rendezett ) First Uf = ( sx, dx, x=read(x) sx=abnorm vge=igaz sx=norm ( vge=hamis egyl.azon = dx.azon
dx.azon egyl.azon

vge := igaz

egyl.ssz , ( sx, dx, x)


dx ( dx' ', x' ' )

dx.ssz ) )

t.First() sx, dx, x:read t.Next()

226

9.3. Csoportok felsorolsa

Jl ltszik, hogy az absztrakt felsorolt az sx, a dx, az x, az egyl s a vge adatok egyttesen reprezentljk. 9.6. Plda. Egy replgppel elrepltnk a Csendes cen szigetvilgnak egy rsze felett, s meghatrozott tvolsgonknt megmrtk a felszn tengerszint feletti magassgt. Ott, ahol cen felsznt szleltk, ez a magassg nulla, a szigeteknl pozitv. A mrst vz felett kezdtk s vz felett fejeztk be. Az gy kapott nem-negatv vals rtkeket egy n hosszsg x vektorban troljuk. Tegyk fel, hogy van legalbb egy sziget a mrsi adatokban. Adjuk meg a mrsek alapjn, hogy mekkora a leghosszabb sziget, s a repls hnyadik mrsnl kezddik ezek kzl az egyik. A feladat llapottere az albbi: A = (x:n, max:, kezd:) Most is akrcsak e feladat korbbi megoldsban (6.9. plda) maximum kivlasztst fogunk hasznlni, de nem az llapottrbeli tmb indextartomnyt jrjuk be kzvetlenl, hanem a szigetek hosszait. Ehhez egy olyan felsorolt ksztnk, amelyik a szigetek hosszait tudja sorban egyms utn megadni azok tmbbeli kezdindexvel egytt. A feladat specifikcijt ezrt nem az eredeti llapottren, hanem a kitallt felsorolra rjuk fel, amely elrejti az eredeti megfogalmazsban szerepl x tmbt. A = (t:enor(Sziget), max:, kezd:) Sziget = rec(hossz:, eleje:) Ef = ( t=t |t|>0 ) Uf = ( max, elem = max akt.hossz kezd = elem.eleje )
akt t'

A feladatot maximum kivlaszts programozsi ttelre vezetjk vissza, ahol f:Sziget s f(akt)=akt.hossz. Mind a First(), mind a Next() mveletet el lehet kszteni gy, hogy a tmb egy adott pozcijrl indulva (kezdetben ez az 1) keressk meg a kvetkez sziget elejt (az els nem-nulla rtket), majd annak a vgt (az els nullt), ebbl szmoljk ki a sziget hosszt s kezdindext. Ehhez a felsorol reprezentlsnl szksgnk van az eredeti llapottr 1-tl n-ig indexelt x tmbjre, s annak indextartomnyt befut i indexre. (A httrben teht megjelenik az

227

9. Visszavezets egyedi felsorolkkal

egydimenzis tmb, azaz a vektor klasszikus felsorolja.) A First() s a Next() mvelet kzti klnbsg csak annyi, hogy az i index kezdrtkt a Next() mvelet megkapja, mg a First() kezdetben 1-re lltja. A Current() mvelet a legutoljra tallt sziget adatait adja meg, ezrt a felsorol reprezentcijban egy akt_sziget nev Sziget tpus adatot is rgzteni kell. Az End() azutn ad vissza igaz rtket, ha egy jabb sziget keressnl i>n bekvetkezik. Ezt a tnyt egy nincs_tbb_sziget logikai vltoz fogja jellni: ha talltunk jabb szigetet, akkor az rtke hamis, ha nem, akkor igaz. sszessgben ltszik, hogy a szigetek hosszainak felsoroljt a ngy adat reprezentlja: az x tmb, az i index, a nincs_tbb_sziget s az akt_sziget. A Current() teht az akt_sziget rtkt adja vissza, az End() a nincs_tbb_sziget rtkt. A Next() mvelet bemen adatai az x tmb s annak i indexe, kimen adatai az akt_sziget , nincs_tbb_sziget s az i index. A soron kvetkez sziget elejnek keresst sajtos mdon nem lineris keresssel, hanem kivlasztssal vgezzk el gy, hogy keressk a sziget elejt vagy a tmb vgt (ez az sszetett felttel biztosan teljesl). Ha nem tallunk szigetet (i>n), akkor a nincs_tbb_sziget legyen igaz, klnben hamis. Ha tallunk szigetet, azaz az i vltoz a tmb egy nem-nulla elemre mutat, akkor az i ezen rtktl (ezt jelli a specifikci i1-gyel) kezdden kell megkeresni a sziget vgt. Ez is biztos ltezik (vagy egy nulla rtk vagy a tmb vge hatrolja), ezrt itt is kivlasztst lehet alkalmazni. Felhvjuk a figyelmet arra, hogy egyik kivlaszts eltt sem kell az i-nek kezdrtket adni, hiszen az rendelkezik a megfelel rtkkel: kezdetben a bemenetknt kapott i-vel, kzben az i1-gyel. ANext = (x:n, i:, nincs_tbb_sziget: , akt_sziget:Sziget) EfNext = ( x = x i=i ) UfNext = ( x = x i1 = select (i n x[i] 0)
i i'

nincs_tbb_sziget = i1>n nincs_tbb_sziget ( akt_sziget.eleje = i1 select ( x[i ] 0 i n) i=


i akt_sziget.eleje

akt_sziget.hossz=iakt_sziget.eleje ) ) t.Next()

228

9.3. Csoportok felsorolsa

i n

x[i] = 0 i:=i+1

nincs_tbb_sziget:= i >n nincs_tbb_sziget akt_sziget.eleje:= i i n x[i] i:=i+1 akt_sziget.hossz:= i akt_sziget.eleje A First() mvelet a Next() mvelet specializlsa. Egyrszt itt i nem bemen adat, ezrt az els kivlaszts i=1-rl indul, msrszt mivel egy sziget biztosan van, a nincs_tbb_sziget rtke biztos hamis lesz. Nem bajldunk azonban a First() egyedi implementlsval, hanem visszavezetjk a Next()-re. t.First() i:=1 t.Next() A fprogram pedig a mr korbban krvonalazott maximum kivlaszts lesz, amelyben a maximlis elem (elem) helyett elg csak annak eleje mezjt a kezd eredmny vltozban trolni, a hossz mezjnek rtke pedig gyis szerepel a max vltozban. t.First() max, kezd:= t.Current().eleje t.Next() t.End() t.Current().hossz, 0 SKIP

229

9. Visszavezets egyedi felsorolkkal

t.Current().hossz>max max, kezd := t.Current().hossz, t.Current().eleje t.Next() 9.7. Plda. Egy karakterekbl ll szekvencilis inputfjl egy szveget tartalmaz. Szmoljuk meg, hogy hny w bett tartalmaz sz tallhat a szvegben! (Egy sz olyan szkz karaktert nem tartalmaz karakterlnc, amelyet egy vagy tbb szkz, a fjl eleje vagy vge hatrol.) A feladat egy szmlls, de nem a szekvencilis inputfjl karakterei felett, hanem a szekvencilis inputfjlban tallhat szavak felett. A szmllshoz egy olyan felsorolra van szksg, amely annyi darab logikai rtket sorol fel, ahny sz szerepel a fjlban, s az i. logikai rtk akkor igaz, ha az i. sz tartalmaz w bett. A = (t:enor( ), db:) Ef = ( t=t ) Uf = ( db 1)
e t' e

SKIP

db:=0; t.First() t.End() t.Current() db:=db+1 t.Next() Valstsuk meg az absztrakt felsorolt ktflekppen! Mindkt esetben a felsorolt az f:infile( ), annak felsorolshoz szksges df: s sf:Sttusz, az aktulis szt minst logikai rtk (van_w: ), amely megmutatja, hogy van-e a szban w bet s a szavak felsorolsnak vgt jelz logikai rtk (nincs_sz: ) reprezentlja. A Current() a sz rtkelst adja vissza, az End() pedig azt, hogy elrtk-e a fjl vgt a soron kvetkez sz elejnek keresse sorn, azaz hogy nincsen tbb sz. SKIP

230

9.3. Csoportok felsorolsa

Az els vltozatban a First() s Next() mveletek azonosak, hiszen mindkettnek a soron kvetkez szt kell kirtkelnie az aktulis szekvencilis inputfjlban. (Ez a First() esetben az eredeti fjl, a Next()-nl annak azon maradka, amely az eddig feldolgozott szavakat mr nem tartalmazza.) A kirtkelshez elszr meg kell keresni a kvetkez sz elejt, ami a szkzk tlpst, az els nemszkz karakter vagy a fjl vgnek (ha nincs egyltaln sz) megtallst jelenti (azaz ez egy kivlaszts). Ha megtalltuk a sz elejt, akkor egy w bett kezdnk el keresni, de csak legfeljebb a sz vgig (felttelig tart lineris keress), vgezetl ha kell a sz vgt keressk meg (jabb kivlaszts). A formlis specifikci utfelttelbl kiolvashat a megoldsnak ez a hrom szakasza: az f fjl felsorolsra pl kivlaszts, a felsorols folytatsra pl felttelig tart lineris keress, majd tovbb folytatva a felsorolst egy jabb kivlaszts. Ezen szakaszok hatrn a felsorol llapotait fels indexekkel klnbztettk meg. Az els kivlaszts egy elreolvasssal indul, a msik kett mr elreolvasott fjllal dolgozik. A = (f:infile( ), df: , sf:Sttusz, nincs_sz: , van_w: ) Ef = ( f = f ) Uf = ( sf 1 , df 1 , f 1
select (sf
df f'

abnorm

df

' ')

nincs_sz=(sf1=norm) nincs_sz (

van _ w, ( sf , df , f )
sf , df , f select

df ' ' df ( df 1 , f 1 )

search

(df

' w' )
df ' ') ) )

df ( sf 2 , df 2 , f 2 )

( sf

abnorm

t.First()=t.Next() sf, df, f : read sf = norm df=

sf, df, f : read nincs_sz:= sf=norm

231

9. Visszavezets egyedi felsorolkkal

nincs_sz van_w:=hamis van_w sf = norm sf, df, f: read sf = norm df df SKIP van_w:=(df=w)

sf, df, f: read Valstsuk most meg az absztrakt felsorolt mskppen! Kssk ki a Next() mvelet implementcijnl, hogy a szekvencilis inputfjl a mvelet vgrehajtsa eltt olyan llapotban legyen, hogy ha mg nem rtk el a fjl vgt ( sf=norm), akkor a soron kvetkez sz elejnl lljunk (df ). (Ez a felsorol tpus invarinsa.) Ekkor a Next() mvelet implementcija nem ignyel elreolvasst, s rgtn a soron kvetkez sz vizsglatval foglalkozhat (w bet lineris keresse majd a sz vgnek megtallsa), ha van egyltaln kvetkez sz. Viszont e vizsglat utn gondoskodni kell a sz utni szkzk tlpsrl (kivlaszts) azrt, hogy az jabb Next() mvelet szmra is biztostsuk a kvnt elfelttelt. A First() mvelet annyival tbb, mint a Next() mvelet, hogy elszr biztostania kell a fenti tpus-invarinst. Ehhez a vezet szkzk tlpsre (kivlaszts) van szksg. A Current() s az End() implementcija nem vltozik. ptsnk bele a megoldsba egy msik vltoztatst is. A w bet lineris keresse majd a sz vgnek megtallsa ugyanis helyettesthet egyetlen sszegzssel pontosabban sszevagyolssal.

232

9.3. Csoportok felsorolsa

ANext = (f:infile( ), df: , sf:Sttusz, nincs_sz: , van_w: ) EfNext = ( f = f1 df = df1 sf = sf1 (sf = norm df ) ) UfNext = ( nincs_sz=(sf1=norm) nincs_sz (

van _ w, ( sf 2 , df 2 , f 2 )
sf , df , f select

df ' ' df ( df 1 , f 1 )

(df

' w' )
df ' ') ) )

df ( sf 2 , df 2 , f 2 )

( sf

abnorm

t.First() sf, df, f : read sf = norm df=

sf, df, f : read t.Next() AFirst = (f:infile( ), df: , sf:Sttusz, nincs_sz: , van_w: ) EfFirst = ( f = f ) UfFirst = (
sf 1 , df 1 , f 1
df ( sf ', df ', f ' )

select

(sf

abnorm

df

' ')

nincs_sz=(sf1=norm) t.Next()

nincs_sz

( lsd UfNext -ben ) )

nincs_sz:= sf=norm nincs_sz van_w:=hamis sf = norm df (df=w) SKIP

van_w:= van_w

sf, df, f: read sf = norm df=

sf, df, f: read

233

9. Visszavezets egyedi felsorolkkal

9.4. sszefuttats Az eddigi feladatoknl a felsorolk tbbsgnek htterben egy adat, tbbnyire valamilyen gyjtemny hzdott meg, annak elemeit vagy ezen elemek csoportjait kellett felsorolni. Mindeddig azonban egy felsorolhoz legfeljebb egy adat tartozott. Tallkozhatunk azonban olyan feladatokkal is, ahol a feldolgozand elemek tbb bemeneti adatban helyezkednek el. Ilyenkor olyan felsorolsra lesz szksg, amely sorn kpzeletben egyetlen sorozatt futtatjuk ssze a bemeneti adatok elemeit. Vegyk pldul azt a feladatot, amikor kt halmaz metszett kell ellltani. Ha fel tudjuk sorolni a halmazok sszes elemt, akkor kszen is vagyunk, hiszen ezek kzl csak azokat tesszk bele az eredmny halmazba, amelyek mindkt halmazban szerepelnek. Az albbi specifikciban ezt a megkzeltst tkrzi az utfelttel msodik alakja, amelyben az uni arra utal, hogy a feldolgozs sorn nemcsak a kzs elemeket kell megvizsglni, hanem az sszest, de azok kzl csak bizonyos elemeket kell az eredmnybe unizni. Ez a megolds az x y halmaz felsorolsra ptett sszegzs (itt unizs) lesz, amely fokozatosan fogyasztja el a kt halmaz unijt. A = (x:set(E), y:set(E), z:set(E)) Ef = ( x = x y = y ) Uf = ( z = x y ) = ( z = f(e) )
e x' y '

ahol f:E 2 s

f(e)

ha ha {e} ha

e e e

x' e x' e x' e

y' y' y'

A megolds htterben teht most is egy egyedi felsorol ll, amellyel jrafogalmazhat a feladat.

234

9.4. sszefuttats

A = (t:enor(E), z:set(E)) Ef = ( t = t ) Uf = ( z = f(e) )


e t'

Az sszefuttat felsorols tulajdonkppen az x y halmaz elemeinek bejrsa lesz. Ez akkor r vget, ha x y res lesz (t.End()). A t.Current() az x y halmazbl vlaszt ki determinisztikus mdon egy elemet (mem(x y)), amelyet majd a t.Next() mvelet fog elvenni az x y-bl, pontosabban x-bl, ha az x-beli, y-bl, ha y-beli, mindkettbl, ha mindkettnek eleme. A t.First() mvelet mint azt a halmazok bejrsnl korbban lttuk az res program. z:= x y e:=mem(x y) e x e y e x e y e x z: = z e y {e}

SKIP x:=x{e}

SKIP y:=y{e}

x, y := x{e}, y {e}

Az x y vizsglat helyettesthet az x y felttellel. A mem(x y) vgrehajtshoz sem kell minden lpsben egyesteni az x s y halmazokat. Ha x nem res akkor a e:=mem(x), egybknt a e:=mem(y) valstja meg a kivlasztst. A t.Next() ugyanazokat a feltteleket vizsglja, mint amit a feladat specifikcija egy elem feldolgozsnl. Ezrt a ciklusmagban egy elem feldolgozsa s az azt kvet Next() mvelet ugyanazon hromg elgazsba lett sszevonva. Egyszersthet a fenti program, ha figyelembe vesszk azt, hogy az x y halmaz elemei felsorolsnak clja kzs elemek kigyjtse. Ezrt a felsorolst mr akkor befejezhetjk, ha az egyik halmaz kirl, azaz az t.End() mvelet akkor igaz, ha x= y= . A t.Current() egyszersthet a mem(x) mveletre, hiszen egyfell az x tartalmazza az sszes kzs elemet, msfell erre az elem kivlasztsra akkor kerl

235

9. Visszavezets egyedi felsorolkkal

sor, amikor t.End() teljesl, azaz x biztosan nem res. A mdosult t.Current() miatt egyszersthet a t.Next() is, st egy elem feldolgozsa is, mert sosem kerl vgrehajtsra a korbbi hromg elgazs kzps ga. z:= x y

e:=mem(x) e x e y e x z := z e y {e}

SKIP x:=x{e}

x, y := x{e}, y{e}

Hasonlan egyszersdne az x y elemeit felsorol s feldolgoz ltalnos program, ha nem az x s y kzs elemeit, hanem az sszest, vagy a kizrlag az x-belieket kellene feldolgozni. ltalnostsuk a fenti feladatot gy, hogy a felsoroland elemek ne kt halmazban legyenek, hanem kt tetszleges felsorol szolgltassa azokat. Ha a felsorolsokat gondolatban az elemeikbl kpzett halmazokra cserljk, akkor a megoldst a fentire vezethetjk vissza. A feladat egyrtelm megfogalmazsa rdekben viszont clszer feltenni, hogy egy elem egy felsorolsban legfeljebb egyszer forduljon el. Feltesszk azt is, hogy a felsorolt elemeken rtelmezett egy teljes rendezs, s mindkt felsorol nvekv sorrendben jrja be az elemeket. Ennek hasznossga akkor ltszik majd, amikor egy elemrl el kell dnteni, hogy az eredetileg az x vagy az y felsorolsban szerepel-e. A feladat specifikcijban az {t} a t felsorolsbl kpzett halmazt szimbolizlja. A t azt jelli, hogy a t elemei szigoran nvekven rendezett sorrendben helyezkednek el, s termszetesen felttelezzk, hogy E-n rtelmezett ehhez egy teljes rendezs. Az eredmnyt egy tetszleges sorozatba fzzk fel.

236

9.4. sszefuttats

A = (x:enor(E), y:enor(E), z:seq(E)) Ef = ( x=x y=y x y ) f(e) ) Uf = ( z =


e { x '} { y '}

ahol f:E F* s

f(e)

f 1(e) ha e {x'} e { y '} f 2(e) ha e {x'} e { y '} f 3(e) ha e {x'} e { y '}

az f1, f2, f3:E F* pedig tetszleges fggvnyek. A megoldshoz itt is egy egyedi (absztrakt) felsorolra lesz szksg, amely a kt konkrt felsorols sszefuttatsra pl. A = (t:enor(E), z:seq(E)) Ef = ( t = t ) f(e) ) Uf = ( z =
e {t '}

A t.Current()-nek az x vagy y felsorolsnak egy elemt kell kivlasztania gy, hogy azt is megmondja, hogy a kivlasztott elem csak az x, csak y vagy mindkett felsorolsban szerepel-e. Ehhez az x.Current() s y.Current() elemeket hasznlhatja fel, ezek kzl kell vlasztania. Mindenek eltt teht el kell indtani mindkt felsorolst, azaz a t.First() az x.First() s y.First() vgrehajtsval lesz azonos. A t.Next() dolga annak a konkrt felsorolsnak a Next() mvelett vgrehajtani, amelyik felsorolsnak rsze az ppen kivlasztott elem. Az sszefuttats ltalban addig tart (t.End()), amg mindkt konkrt felsorol vget nem r. Ahhoz, hogy eldntsk, hogy x.Current() benne van-e az y felsorolsban, ltalban egy kln keressre lenne szksg. De nem minden felsorol teszi lehetv, hogy egy ilyen keress rdekben jra s jra elindtsuk, radsul nem is tnik ez tl hatkony megoldsnak. De ha feltesszk (s ezt feltettk), hogy mindkt konkrt felsorols szigoran nvekeden rendezett, akkor a krds egy egyszer vizsglattal eldnthet. Mindenek eltt tegyk fel azt is (ez lesz az egyedi felsorolnk tpus-invarinsa), hogy x.Current() s y.Current() nagyobb az x s y korbban felsorolt elemeinl. Ez kezdetben, a t.First() vgrehajtsa utn biztos fenn ll, ksbb pedig, ha a t.Next() mveletet a fentiek rtelmben valstjuk meg, meg is marad.

237

9. Visszavezets egyedi felsorolkkal

Ennlfogva ha x.Current()<y.Current(), akkor a szigoran nveked rendezettsg miatt biztosak lehetnk abban, hogy az x.Current() egyltaln nem szerepelhet az y felsorolsban. Ha teht ilyenkor x.Current()-et vlasztjuk az absztrakt felsorols kvetkez elemnek, akkor errl kijelenthetjk, hogy csak az x-ben lelhet fel. Szimmetria okokbl az x.Current()>y.Current() esetn az y.Current()-et fogjuk felsorolni. Az x.Current()=y.Current() esetn pedig olyan elemmel van dolgunk, amelyik mindkt felsorolsban szerepel. Az eddigi vizsglatoknl feltettk, hogy egyik konkrt felsorols sem rt vget ( x.End() y.End()). Nem vettk azonban eddig figyelembe azt, amikor valamelyik konkrt felsorols mr befejezdtt, azaz nincs neki aktulis eleme, amelyet a msik felsorol aktulis elemvel sszehasonlthatnnk. Ha pldul mr y.End() teljesl, akkor (az x.End() mg biztos hamis) az x.Current() a tpusinvarins rtelmben biztos nem szerepelt az y felsorolsban, azaz ugyanahhoz az esethez tartozik, mint a x.Current()<y.Current(). Figyelembe vve az eddigieket az albbi programhoz jutunk. z := <> x.First(); y.First(); x.End() y.End() x.End() y.End() x.Current()= y.Current()

y.End() x.End() ( x.End() ( y.End() x.Current()< x.Current()> y.Current() ) y.Current() )

z:write( z:write( z:write( f1(x.Current())) f2(y.Current())) f3(x.Current())) x.Next(); y.Next() x.Next(); y.Next()

Vegyk szre, hogy az elgazs felttelei egyrszt a ciklusfelttel miatt, msrszt az gynevezett lusta kirtkelst felttelezve egyszersdtek. Pldul az els g felttele eredetileg az ( x.End() y.End()) ( x.End() y.End() x.Current()<y.Current()) lett volna. A t.Next() elgazst most is sszevontuk a feldolgozs elgazsval.

238

9.4. sszefuttats

Ha a feldolgozs fggvny specilis, mert a hrom eset kzl valamelyikben az res sorozatot lltja el (azaz nem kell ilyenkor semmit tenni a kimeneti adattal), akkor a program tovbb egyszersthet. Ha pldul csak az x s y felsorolsok kzs elemeit kell feldolgozni, azaz f1(e)= f2(e)=< >, akkor az albbi program is megfelel. (Szigorodott a ciklus felttel, s ennek kvetkeztben egyszersdtek az elgazsok felttelei.) z := <> x.First(); y.First(); x.End() x.Current()< y.Current() SKIP x.Next(); y.End() x.Current()= y.Current() z:write(f3(x.Current())) x.Next(); y.Next()

x.Current()> y.Current() SKIP y.Next()

A fentiek alapjn az sszefuttatsos feldolgozs knnyen adaptlhat sorozatok, szekvencilis inputfjlok vagy vektorok sszefuttatsra is. Megjegyezzk, hogy az eredmny sorozat minden esetben egyrtelm s rendezett lesz. Egy ilyen feladat a kvetkez is. 9.8. Plda. Adott kt nvsor egy-egy szekvencilis inputfjlban, mindkett szigoran nvekeden rendezett az bc szablyai szerint. Az els nvsor egy kt flves tantrgy els flvt felvev hallgatk neveit, a msik a msodik flvre jelentkez hallgatk neveit tartalmazza. Kik azok, akik elkezdtk a tantrgyat, de mr a msodik flvet nem vettk fel, azaz kik azok, akik csak az els nvsorban szerepelnek, a msodikban nem?

239

9. Visszavezets egyedi felsorolkkal

A = (x:seqin( *), y:seqin( *), z:seqout( *)) Ef = ( x=x y=y x y ) f(e) ) Uf = ( z =


e { x '} { y '}

e f(e)

ha ha ha

e {x '} e { y '} e {x '} e { y '} e {x '} e { y '}

Halmazokkal megfogalmazva a feladatot, itt tulajdonkppen kt halmaz klnbsgt kell meghatrozni. A feladat a kt szekvencilis inputfjl sszefuttatsra ptett sszegzssel oldhat meg. Az ltalnos megoldst most gy kell alkalmazni, hogy az x s y elemeinek felsorolshoz a szekvencilis inputfjl nevezetes felsorolst kell hasznlni. (Az x.First() s x.Next() helyett sx,dx,x:read, x.End() helyett sx=norm, x.Current() helyett dx.) A megold program ciklusfelttele az sx=norm sy=norm helyett az sx=norm-ra egyszersdhet, s ennlfogva egyszerbbek lehetnek az elgazs felttelei is. z := <> sx,dx,x:read; sy,dy,y:read sx=norm sy=abnorm dx<dy z:write(dx) sx,dx,x:read sy=norm dx>dy SKIP sy,dy,y:read sy=norm dx=dy SKIP sx,dx,x:read; sy,dy,y:read

Az sszefuttats alkalmazsnak egyik klasszikus pldja az albbi adatkarbantartsrl szl feladat. 9.9. Plda. Adott egy rukszletet, mint az ruk azonostja szerint egyrtelm s nvekven rendezett szekvencilis inputfjl, tovbbiakban trzsfjl, valamint az egyes rukra vonatkoz

240

9.4. sszefuttats

vltoztatsokat tartalmaz, ugyancsak az ruk azonostja szerint egyrtelm s nvekven rendezett msik szekvencilis inputfjl, tovbbiakban mdost fjl. A vltoztatsok hrom flk lehetnek: j ru felvtele (beszrs), meglev ru leselejtezse (trls) s meglev ru mennyisgnek mdostsa. Ksztsk el a vltoztatsokkal megjtott, gynevezett idszerstett rukszletet. A trzsfjl ru=rec(azon:, me:) tpus elemek; a mdost fjl pedig Vltozs=rec(azon:, mv:{I, D, U}, me:) tpus elemek sorozata. Az I (beszrs), D (trls), U (mdosts) a megfelel vltoztats tpusra utal, a mennyisg a trls esetn rdektelen, mdosts esetn ennyivel kell az eddigi mennyisget mdostani. Az j trzsfjl a rgi trzsfjllal megegyez szerkezet. A feladat llapottere: A= (t:infile(ru) , m:infile(Vltozs) , u:outfile(ru)) Ef = ( t = t' m = m' t azon m azon ) A t azon azt jelzi, hogy a t szekvencilis inputfjl elemei (rekordjai) az azon mezjk alapjn szigoran nvekeden rendezettek. Szksgnk van egy olyan felsorolra, amelyik fel tudja sorolni a kt szekvencilis inputfjlban elfordul sszes ruazonostt, meg tudja mondani, hogy az melyik inputfjlban tallhat (trzsfjl, mdost fjl vagy mindkett), s kpes megadni az aktulis ruazonosthoz tartoz trzsfjlbeli illetve mdost fjlbeli rekordot. A specifikciban az azon(t) az sszes t-beli azonostt tartalmaz halmazt, az azon(m) az sszes m-beli azonostt tartalmaz halmazt jelli. Ha a azon(t), akkor a(t) a t-beli a azonostj rekordot jelli. Hasonlan, ha a azon(m), akkor az a(m) az m-beli a azonostj rekord.

241

9. Visszavezets egyedi felsorolkkal

A= (x:enor(), u:outfile(ru)) Ef = ( x = x' ) Uf = ( u f(a) )


a x'

f(a)

a (t ' ) f 2 (a) f 3 (a)

ha ha ha

a a a

azon (t ' ) azon (t ' ) azon (t ' )

a a a

azon (m' ) azon (m' ) azon (m' )

f 2(a)

(a, a(m' ).me)


hiba

ha e.mv k lnben I

hiba

ha ha ha

a(m' ).mv

f 3(a) g (a)

a(m' ).mv D a(m' ).mv U

g(a)

a, a(t ' ).me a(m' ).me a(t ' ) hiba

ha a(t ' ).me a(m' ).me 0 ha a(t ' ).me a(m' ).me 0

A feladat megoldst a fent krvonalazott sszefuttat felsorol feletti sszegzsre vezetjk vissza annak figyelembe vtelvel, hogy most a kt konkrt felsorol egy-egy szekvencilis inputfjl nevezetes felsorolja lesz. Az egyikhez st,dt,t:read, a msikhoz sm,dm,m:read mveletet hasznljuk. Az sszefuttats hrom esete vagy egy kizrlag trzsfjlbeli elemet (dt) ad meg (ilyenkor nincs vltoztats a dt-re), vagy egy kizrlag mdost fjlbelit (ez olyan vltoztats, amelyik a trzsfjlban nem szerepl rura vonatkozik; csak beszrsknt lehet rtelmes), vagy mindkt fjl egyez azonostj elemeit (dt-t kell dm alapjn mdostani; dm beszrs nem lehet).

242

9.4. sszefuttats

u := <> st, dt, t: read; sm, dm, m: read st=norm sm=abnorm (st=norm dt.azon < dm.azon) u:write(dt) dm.mv=I u:write( dm.azon, dm.me) H I B A I H I B A D S K I P st=abnorm (sm=norm dt.azon> dm.azon) sm=norm st=norm sm=norm dt.azon=dm.azon

dm.mv= U c := dt.me+dm.me c<0 H I B A dt.me:=c

u:write(dt) st, dt, t: read sm, dm, m: read st, dt, t: read sm, dm, m: read

letszerbb lenne a problma, ha nem kvetelnnk meg azt, hogy a mdost fjl egyrtelm legyen, azaz egy azonosthoz tbb vltoztatst is rendelhetnk. Ekkor a fenti algoritmusban a mdost fjlnak nem az egyes elemeit (rekordjait) kellene felsorolni, hanem a megegyez azonostj rekordjainak csoportjait, s egy-egy ilyen csoportot hasonltannk ssze a trzsfjl egy-egy rekordjval, s egy ilyen csoport vltoztatsait hajtannk vgre egyms utn ugyanarra az azonostra, pontosabban az ahhoz tartoz adatra. A csoportok kiolvasshoz a korbban (9.4. alfejezet) mutatott technikval tudunk felsorolt kszteni. Egy msik megoldsi lehetsg egy alkalmas rekurzv fggvny bevezetse lehetne. Rekurzv fggvnyek feldolgozsval majd a kvetkez alfejezetben foglalkozunk.

243

9. Visszavezets egyedi felsorolkkal

Hasonl problmt vet fel az, amikor a mdostsok tbb klnbz mdost fjlban tallhatk. Ilyenkor elbb ssze kell futtatni ezeket egyetlen mdost fjlba, vagy legalbbis egy olyan felsorolt kell bevezetni, amely egyetlen, azonost szerint nvekv sorozatknt bnik a mdost fjlokkal. Ennek lnyegt emeli ki a kvetkez feladat. 9.10. Plda. Adott n darab szekvencilis inputfjl, amelyek egsz szmokat tartalmaznak, mindegyik egyrtelm s nvekven rendezett. Ksztsnk olyan felsorolt, amely a fjlokban elfordul sszes egsz szmot felsorolja gy, hogy ugyanazt a szmot csak egyszer adja meg. A felsorolt az sszes elreolvasott szekvencilis inputfjllal reprezentljuk. Ez hrom 1-tl n-ig indexelhet tmbbel brzolhat: f:infile()n, df:n , sf:Sttuszn. A kezdeti beolvassokat a First() mvelet vgzi. Az End() mvelet akkor ad igazat, ha mindegyik fjl olvassi sttusza abnorm lesz. Ennek eldntsre az 1..n intervallum feletti optimista lineris keressre van szksg: vizsgljuk, hogy i [1..n]:sf[i]=abnorm teljesl-e. A Current() mvelet a soron kvetkez egsz szmot az aktulisan beolvasott egsz szmok kztti feltteles minimumkeresssel hatrozza meg, ugyanis ki kell hagynia a vizsglatbl azon fjlokat, amelyek olvassi sttusza mr abnorm. Vegyk szre, hogy ez a feltteles minimumkeress helyettesti az End() mveletet implementl optimista lineris keresst, hiszen mellkesen eldnti, hogy van-e mg nem res fjl. Tegyk teht bele ezt a feltteles minimumkeresst a First() s a Next() mveletek implementciiba, a felsorol reprezentcijhoz pedig vegyk hozz a minimum keress eredmnyt trol l logikai rtket, s min egsz szmot. Ekkor az End() rtke egyszeren a l lesz, a Current() rtke pedig a min. A Next() mveletnek mindazon fjlokbl kell j elemet olvasnia, amelyek aktulisan kiolvasott rtke megegyezik a min rtkkel, majd vgre kell hajtania az elbb emltett feltteles minimumkeresst. Az albbi algoritmus nem rszletezi a feltteles minimumkeress struktogrammjt, ezt az Olvasra bzzuk.

244

9.4. sszefuttats

First() i = 1 .. n sf[i],df[i],f[i]:read
n

l, min := min df [i ]
i 1 sf [ i ] norm

Next() i = 1 .. n sf[i]=norm sf[i],df[i],f[i]:read


n

df[i]=min SKIP

l, min := min df [i ]
i 1 sf [ i ] norm

9.11. Plda. Egy vllalat raktrba tbb klnbz cg szllt rut. A raktrkszletet egy szekvencilis inputfjlban (trzsfjl) tartjk nyilvn gy, hogy minden ruazonost mellett feltntetik a kszlet mennyisgt. A beszllt cgek minden nap elkldenek egy-egy ezzel megegyez formj szekvencilis inputfjlt (mdost fjl), amelyek az adott napon szlltott ruk mennyisgt tartalmazzk. Minden szekvencilis fjl ruazonost szerint szigoran nvekven rendezett. Aktualizljuk a raktr-nyilvntartst. A= (t:infile(ru), m:infile(ru)n, u:outfile(ru)) ru=rec(azon:, menny:) Ef = ( t = t' m = m' t azon i [1..n]:m[i] azon ) A megoldshoz az m tmbre olyan y felsorolt vezetnk be, amely a mdost fjlokbl mindig a soron kvetkez azonostj rura vonatkoz sszestett beszlltsi adatot olvassa be. (Alternatv megolds lehetne az is, ha az sszestst nemcsak az n darab beszlltsi fjlra vgzi el a felsorol, hanem a trzsfjllal egytt n+1 darab fjlra, s ilyenkor csak egyszeren ki kell msolni a felsorols elemeit a kimeneti fjlba. Ez utbbi esetben azonban nincs lehetsg

245

9. Visszavezets egyedi felsorolkkal

annak a hibnak a kiszrsre, amikor a nyilvntartsban nem szerepl rubl rkezik beszllts.) Mind az y.First(), mind az y.Next() mvelet a beszlltsokban szerepel legkisebb azonostj, mg feldolgozatlan ttelek mennyisgeit sszegzi. Ehhez elszr egy feltteles minimumkeresssel megkeressk a legkisebb (min) azonostj rut az aktulisan beolvasott ttelek kztt (a felttel az, hogy az adott beszllts fjlnak van-e mg feldolgozatlan ttele, azaz sm[i]=norm). Majd, ha talltunk ilyet (azaz nem mindegyik fjl res), akkor a min azonostj ttelek mennyisgeit sszegezzk (ez egy feltteles sszegzs az sm[i]=norm dm[i]=min felttellel). Az y.First() mvelet csak abban klnbzik az y.Next()-tl, hogy legelszr minden beszllts fjl els (legkisebb azonostj) ttelt be kell olvasni (ha van ilyen), ksbb mr csak azokbl a beszllts fjlokbl kell jabb ttelt olvasni, amelyek a korbbi lpsben sszegzett rekordokat adtk. Ezt az olvasst viszont ezrt rdemes a megelz Next (vagy First) mvelet vgre tenni, mert sszevonhat az ott tallhat feltteles sszegzssel. Ezzel lnyegben azt mondjuk, hogy a felsorol invarinsa elrja, hogy a beszllts fjlokbl legyenek a soron kvetkez, mg feldolgozatlan ttelek beolvasva. Az y.First() mvelet teht miutn minden beszllts fjlbl olvasott egyet azonos az y.Next()-tel. A beszllts fjlok bejrshoz a szekvencilis inputfjl nevezetes felsoroljt hasznljuk. y.First() i = 1 .. n sm[i],dm[i],m[i]:read y.Next() Az y.Next() mvelet a feltteles minimumkeresssel kezddik (ennek struktogrammjt nem adjuk meg, ezt az Olvasra bzzuk), amelyet a feltteles sszegzssel sszevont fjlonknti tovbbolvass kvetkezik. Ezt a msodik rszt csak akkor rdemes vgrehajtani, ha van legalbb egy olyan fjl, amely mg nem res, azaz ha a feltteles minimumkeress logikai eredmnye igaz.

246

9.4. sszefuttats

y.Next()
n

l, ind, min :=

i 1 sm[i ] norm

min

dm[i].azon

l dm.azon, dm.menny:=min, 0 i = 1 .. n sm[i]=norm dm[i]=min SKIP

dm.menny:= SKIP dm.menny+dm[i].menny sm[i],dm[i],m[i]:read Az y.Current() mvelet a minimlis azonostt s az sszestett beszlltsi mennyisget adja vissza (dm), az y.End() pedig akkor lesz igaz, ha a feltteles minimumkeress sikertelen (l=hamis), azaz mr minden beszllts sszes ttelt megvizsgltuk. Az y felsorol segtsgvel jraspecifikljuk a feladatot: A= (t:infile(ru), y:enor(ru), u:outfile(ru)) ru=rec(azon:, menny:) Ef = ( t = t' y = y' t azon y azon ) f(a) ) Uf = ( u
a azon(t ') azon( y ')

a (t ' ) f(a)
hiba

ha ha ha

a a a

azon (t ' ) azon (t ' ) az (t ' )

a a a

azon ( y ' ) azon ( y ' ) azon ( y ' )

g (a)
g(a)

a(t ' ) menny menny a ( y ' ).menny

A t fjl a szekvencilis inputfjlok nevezetes felsoroljval jrjuk be. Ekkor a kt felsorolra ptett sszefuttatsos sszegzssel oldhatjuk meg a feladatot.

247

9. Visszavezets egyedi felsorolkkal

u : =<> st,dt,t:read; y.First(); st=norm y.End() (st=norm dt.azon< y.Current().azon) u:write(dt) y.End() st=norm y.End() dt.azon= y.Current().azon dt.menny:= dt.menny+dm.menn y u:write(dt) st,dt,t:read y.Next() st,dt,t:read; y.Next()

st=abnorm (st=norm dt.azon> y.Current().azon) HIBA

9.5. Rekurzv fggvny feldolgozsa Az intervallumon rtelmezett programozsi ttelek kzl nem ltalnostottuk felsorolra a rekurzv fggvny helyettestsi rtkt kiszmol ttelnket. Ennek az oka az, hogy a 4. fejezetben bevezetett rekurzv fggvnyeket az egsz szmok egy intervallumn definiltuk, teht ez a fogalom az intervallumhoz kttt, ezrt nincs rtelme a kiszmtst vgz programozsi ttelt ltalnostani. Elfordulhat azonban, hogy olyan esetben is rekurzv fggvny rtknek kiszmolshoz folyamodunk, amikor a feladat adatai nem mutatjk meg kzvetlenl a rekurzv fggvny rtelmezsi tartomnyt kijell intervallumot. Helyette egy felsorolnk van, amelynek ha az elemeit a felsorols sorrendjben megsorszmozzuk, akkor a keresett intervallumhoz jutunk. A 6.4. alfejezetben lttuk, hogy milyen hatkony megoldst eredmnyez egy programozsi ttelbe gyazott rekurzv fggvny kibontsval kapott program. Ehhez ott arra volt szksg, hogy a programozsi ttel intervallumn legyen rtelmezve a rekurzv fggvny is. Vajon lehet-e ezt a technikt alkalmazni akkor is, ha felsorolra fogalmazott programozsi ttelekkel dolgozunk? Erre adnak vlaszt az albbi feladatok-megoldsai.

248

9.5. Rekurzv fggvny feldolgozsa

Az albbi szveg-tmrt feladatot ktflekppen is megoldjuk: elszr egy rekurzv fggvny rtknek kiszmolsval, majd egy felsorolra pl feldolgozsban trtn rekurzv fggvny kibontssal. 9.12. Plda. Msoljuk t a karaktereket egy szekvencilis inputfjlbl egy outputfjlba gy, hogy ott, ahol tbb szkz kvette egymst, csak egyetlen szkzt tartunk meg! Kpzeljk el azt a tbbkomponens r:[0.. x ] * fggvnyt, amelyiknek els komponense az i-edik helyen az x inputfjl els i karakternek tmrtett vltozatt adja meg, msodik komponense arra szolgl, hogy emlkezzen arra, hogy az i1-dik karakter szkz volt-e. Ezt a fggvny az albbi mdon definilhatjuk.

i [1.. x ] : r(i) (r1 (i 1) xi , hamis ) ha (r1(i 1) xi , igaz ) ha (r(i 1)) ha xi ' ' xi ' ' r2(i 1) xi ' ' r2(i 1)

r(0) ( , hamis ) Ezek utn a feladat specifikcija igen egyszer: szmoljuk ki az r rekurzv fggvny utols rtkt. A = (x:infile( ), y:outfile( )) Ef = ( x=x ) Uf = ( y r1 ( x' ) )
A feladat visszavezethet a rekurzv fggvny helyettestsi rtkt kiszmol programozsi ttelre, de a kapott algoritmussal van egy kis bkken. Nem megengedett az x szekvencilis inputfjl i-dik elemre trtn kzvetlen hivatkozs, ahhoz csak egy felsorolssal tudunk hozzfrni.

249

9. Visszavezets egyedi felsorolkkal

y, l, i :=<>, hamis, 1 i xi y:write(xi) l := hamis x xi = l xi = SKIP l

y:write(xi) l := igaz i := i+1

Ebben az esetben jl ltszik, hogy az i indexvltoznak csupn az a szerepe, hogy segtsgvel bejrjuk az x szekvencilis inputfjl elemeit. Cserljk ht le a szekvencilis fjl megengedett felsoroljra, azaz hasznljunk a read mveletet. y, l :=<>, hamis st, ch, x : read st = norm ch ch = l ch = SKIP l

y:write(ch) l := hamis

y:write(ch) l := igaz st, ch, x : read

ltalban elfordulhat, hogy a rekurzv kpletnek az i indexre kzvetlenl is szksge van, ezrt olyankor az i-re vonatkoz mveletek is megmaradnak az algoritmusban, azaz egyms mellett zajlik az intervallum s mondjuk egy szekvencilis inputfjl felsorolsa. A msodik megoldsi t abba gondolatba kapaszkodik bele, hogy ez a feladat els ltsra egy olyan elemenknti feldolgozsnak tnik, amelyeket az elz fejezetekben oldottunk meg, hiszen az eredmny (y) ellltshoz bizonyos rtkeket kell egyms utn fzni. Alaposan szemgyre vve azonban lthat, hogy itt nem egy msolsrl van sz: ahhoz ugyanis, hogy eldntsk, mit kell az aktulis karakterrel csinlni (hozz kell-e rni az y-hoz vagy sem), ismerni kell, hogy a megelz

250

9.5. Rekurzv fggvny feldolgozsa

i [1.. x ] : r(i) ( xi , hamis ) ha ( xi , igaz ) ha ( , r2 (i 1)) ha xi ' ' xi ' ' r2(i 1) xi ' ' r2(i 1)

r (0) ( , hamis ) karakter szkz volt-e vagy sem. A feladat lershoz ezrt itt is egy rekurzv fggvnyt kell bevezetnnk, amely termszetesen hasonlt az elz megoldsban hasznlthoz. A lnyeges klnbsg az, hogy most az r:[0.. x ] * rekurzv fggvny els komponense csak az eredmnyhez hozzfzend egy karakternyi vagy res sorozatot lltja el, s nem a teljes eredmnyt. A specifikci pedig: A = (x:infile( ), y:outfile( )) Ef = ( x=x )
x'

Uf = ( y

i 1

r1 (i ) )

A feladatot teht a rekurzv fggvny els komponense ltal adott rtkeinek az sszefzsvel (sszegzs) oldhatjuk meg. A soron kvetkez ilyen rtk ellltshoz a szekvencilis fjl aktulis karakterre s a megelz karakterrl informcit ad logikai rtkre van szksg. Ugyanakkor nincs kzvetlenl szksg arra az indexre, amelyik a rekurzi lpseit szmolja. A rekurzv kplet ltalnos h:Hk H fggvnyt most egy h: * alak fggvny biztostja, hiszen r(i)=h(xi, r2(i1)). Ha rendelkeznnk egy olyan felsorolval, amely a h kiszmolshoz szksges karakter-logikai rtk prokat a megfelel sorrendben kpes adagolni, akkor a feladat megoldsval kszen is lennnk. ltalnossgban is igaz az, hogy ha egy rekurzv fggvny egyms utni rtkeit kell ellltanunk egy feldolgozs szmra, akkor a rekurzv kplet h:Hk H fggvnyt kell a szmra szksges k+1 darab argumentummal jra s jra kiszmolni, s ehhez ezen argumentum-csoportokat kell egy alkalmas felsorolval megadni. Ezen gondolatmenet mentn a feladatunkat jraspecifiklhatjuk.

251

9. Visszavezets egyedi felsorolkkal

A = (t:enor(Pr), y:outfile( )) Ef = ( t=t ) h1(ch,l) ) Uf = ( y


(ch, l ) t '

Pr = rec(e: , l: )

ahol h:

h(ch,l)

( ch , hamis ) ( ch , igaz )

ha ha

ch ' ' ch ' ' l

( ,l) ha ch ' ' l A felsorol reprezentlshoz egyfell az x szekvencilis inputfjlra van szksg, tovbb az abbl val olvasshoz a kiolvasott aktulis karakterre (ch) s az olvass sttuszra (st). Msfell kell egy logikai vltoz (l), amely az elz karakterrl mondja meg, hogy szkz volt-e vagy sem. A First() mvelet egyrszt a szekvencilis inputfjl els karaktert ksrli meg beolvasni, msrszt a logikai komponenst a rekurzv fggvny kezdeti defincijnak (r(0) = (<>,hamis)) megfelelen hamis-ra lltja. A Next() a fggvnydefinci rekurzv formulja alapjn (itt kap szerepet a h2) j rtket ad a logikai vltoznak (l:=ch= ), majd beolvassa a kvetkez karaktert a szekvencilis inputfjlbl. A Current() visszaadja a ch s l rtkeit, az End() pedig akkor lesz igaz, ha az st=abnorm. Az ltalnos sszegzs f fggvnye most a h1, amely a Current() mvelet ltal szolgltatott ch s l rtkekhez rendel egy karaktersorozatot, amelyet az y-hoz kell hozzrni. Mivel h1 egy esetsztvlaszts, az y:write(h1(ch,l)) utastst egy elgazssal kdoljuk. Ez az algoritmus megegyezik az els megolds sorn kapott vltozattal.

252

9.5. Rekurzv fggvny feldolgozsa

y:=<> l:=hamis st,ch,x:read sx = norm ch y:write( ) ch= l:= ch= st,ch,x:read Ugyancsak egy rekurzv fggvnynek egy msik programozsi ttelben trtn kibontsra ad pldt az albbi megolds. 9.13. Plda. Egy kirnduls sorn bejrt tvonalon adott tvolsgonknt mrtk a tengerszint feletti magassgot (pozitv szm), s ezen rtkeket egy szekvencilis inputfjlban rgztettk. Azt az rtket, amelyik nagyobb az sszes elznl, kszbnek hvjuk. Hny kszbbel tallkoztunk a kirnduls sorn? Specifikljuk elszr a feladatot egy alkalmas rekurzv fggvny segtsgvel. A = (x:infile(), db:) Ef = ( x=x )
x'

ch= SKIP

y:write(ch)

Uf = ( db
x'i

1
i 2 f(i 1)

ahol f(i1) az els i-1 elem maximuma. Ezt szekvencilis inputfjl feldolgozsrl lvn sz nem maximum kivlasztssal, hanem egy alkalmas rekurzv fggvny segtsgvel lltjuk el: f:[1.. x ] f(1) = x1 f(i) = max(f(i-1), xi) (i>1) A feladat most is jrafogalmazhat egy alkalmas felsorol segtsgvel, ha szrevesszk, hogy a rekurzv kplet kiszmolshoz a szekvencilis inputfjl aktulis elemt s a korbbi elemek maximumt kell megadni:

253

9. Visszavezets egyedi felsorolkkal

A = (t:enor(Pr), db:) Ef = ( t=t ) 1 ) Uf = ( db


( e, max ) t ' e max

Pr = rec(e:, max:)

A feladat a szmllsra veszethet vissza. Az elem-maximum prok felsorolsa azzal kezddik (First), hogy a fjl els elemt beolvassuk a max, msodik elemt az e vltozba. A kvetkez maximum a korbbi maximumtl s az aktulis elemtl fgg, ezt kveten pedig jabb elemet kell olvasnunk (Next). A szmlls elgazsnak felttele ugyanaz, mint a Next() mveletbeli elgazs felttele, ezrt a kt elgazs sszevonhat. A felsorols aktulis eleme (Current) az (e,max) pr. A felsorols addig tart, amg a fjlbl sikerl jabb elemet olvasni (End). db := 0 st,max,x:read st,e,x:read st = norm e>max db, max:=db+1, e st,e,x:read 9.6. Felsorol gyjtemny nlkl 9.14. Plda. Hatrozzuk meg egy n pozitv egsz szm prmosztinak az sszegt! A feladat megfogalmazhat egy feltteles sszegzsknt, amely sorn a [2..n] intervallum azon elemeit kell sszeadnunk, amelyek osztjk az n-t s prm szmok. SKIP

254

9.6. Felsorol gyjtemny nlkl

A = (n:, sum:) Ef = ( n=n' n>0 )


n

Uf = ( Ef

sum =
in

i
i 2 prim(i)

A feladat kznsges sszegzsknt is megfogalmazhat, ha bevezetjk azt a felsorolt, amely kzvetlenl az n szm prm osztit sorolja fel, s a feladatot ennek megfelelen jraspecifikljuk. A = (t:enor(), sum:) Ef = ( t=t' ) e ) Uf = ( sum =
e t'

Ezt visszavezethetjk az ltalnos sszegzsre gy, hogy abban az E=H= s minden e termszetes szmra f(e)= e. sum := 0 t.First() t.End() sum := sum+t.Current() t.Next() Az n szm prmoszti kzl az elshz, mondjuk a legkisebbhez, gy juthatunk hozz, hogy amennyiben az n legalbb 2, akkor egyesvel elindulunk 2-tl s az n szm els (legkisebb) osztjt megkeressk. Ez biztosan prm. (Ez a tevkenysg egy kivlaszts.) A soron kvetkez prmoszt keresshez a korbban megtallt prmosztt ezt teht meg kell jegyezni ki kell valahogy venni az n szmbl, azaz elosztjuk vele az n-t ahnyszor csak tudjuk. A hnyadosnak (az n j rtknek) prmoszti az eredeti n szmnak is prmoszti lesznek, s ezek ppen azok, amelyeket eddig mg nem soroltunk fel. Teht a kvetkez prmoszt ellltshoz meg kell ismtelni az elz lpseket. A felsorols addig tart, amg az egyre cskken n nem lesz 1. Ez vges lpsben biztosan be fog kvetkezni.

255

9. Visszavezets egyedi felsorolkkal

Az eredeti szm sszes prmosztjt felsorol objektumot egyfell a folyamatosan cskken n, msfell annak legkisebb prmosztja (d) reprezentlja. A First() mvelet az eredeti n legkisebb prmosztjt (lko) keresi meg, ha n>1, s elhelyezi a d vltozban. A Next() mvelet elosztja az n-t a d-vel ahnyszor csak tudja, majd ha gy mg mindig n>1, akkor megkeresi az n legkisebb prmosztjt, s elhelyezi a d vltozban. A Current() mvelet a kiszmolt d rtkt adja vissza. Az End() n=1 esetn ad igazat. t ~ n, d t.First() ~ d:=lko(n) t.Next() ~ LOOP(d|n; n:=n/d); d:=lko(n) t.End() ~ n=1 t.Current() ~ d A d:=lko(n) megoldsa az IF(n>1, d : select (d n) ) lesz.
d 2

sum:=0; d:=2; d:=lko(n) n>1 sum := sum + d d|n n:=n/d d:=lko(n)

d:=lko(n) n>1 d|n d:=d+1 SKIP

Az lko() megvalstshoz a kivlaszts korbbi, egsz szmegyenesre megfogalmazott vltozatt ppgy hasznlhatjuk, mint a kivlaszts ltalnos programozsi ttelt, amelyben a :E felttel most a (d)= d|n lesz. A felsorol az egsz szmokat jrja be 2-tl indtva, s lellsakor a felsorolst vgz index megegyezik a kivlaszts eredmnyvel. St, ez mg gyorsthat, ha mr korbban talltunk egy d prmosztt, mert ilyenkor nem kell jra 2-tl indtani a keresst, hanem elg d+1-tl. Azrt, hogy e mdosts utn ne kelljen az els prmoszt keresst megklnbztetni a tbbitl, a d rtkt kezdetben a First() mveletben kell 2-re lltani.

256

9.7I.9.7. Feladatok

9.7. Feladatok 9.1. Egy kmreplgp vgigreplt az ellensg hadllsai felett, s rendszeres idkznknt megmrte a felszn tengerszint feletti magassgt. A mrt adatokat egy szekvencilis inputfjlban troljuk. Tudjuk, hogy az ellensg a harcszati raktit a lehet legmagasabb horpadsban szokta elhelyezni, azaz olyan helyen, amely eltt s mgtt magasabb a tengerszint feletti magassg (loklis minimum). Milyen magasan tallhatk az ellensg rakti? Szmoljuk meg egy karakterekbl ll szekvencilis inputfjlban a szavakat gy, hogy a 12 betnl hosszabb szavakat dupln vegyk figyelembe! (Egy szt szkzk vagy a fjl vge hatrol.) Alaktsunk t egy bitsorozatot gy, hogy az els bitjt megtartjuk, utna pedig csak darabszmokat runk annak megfelelen, hogy hny azonos bit kveti kzvetlenl egymst! Pldul a 00011111100100011111 sorozat tmrtve a 0362135 szmsorozat lesz. Egy szveges fjlban a bekezdseket res sorok vlasztjk el egymstl. A sorokat sorvge jel zrja le. Az utols sort zrhatja a fjl vge is. A sorokban a szavakat a sorvge vagy elvlasztjelek hatroljk. Adjuk meg azon bekezdsek sorszmait, amelyek tartalmazzk az elre megadott n darab sz mindegyikt! (A nem-res sorokban mindig van sz. Bekezdsen a szvegnek azt a szakaszt rtjk, amely tartalmaz legalbb egy szt, s vagy a fjl eleje illetve vge, vagy legalbb kt sorvge jel hatrolja.) Egy szveges llomny legfeljebb 80 karakterbl ll sorokat tartalmaz. Egy sor utols karaktere mindig a specilis \eol karakter. Msoljuk t a szveget egy olyan szveges llomnyba, ahol legfeljebb 60 karakterbl ll sorok vannak; a sor vgn a \eol karakter ll; s gyelnk arra, hogy az eredetileg egy szt alkot karakterek tovbbra is azonos sorban maradjanak, azaz sorvge jel ne trjn kett egy szt. Az eredeti llomnyban a szavakat egy vagy tbb szhatrol jel vlasztja el (Az \eol is ezek kz tartozik), amelyek kzl elg egyet megtartani. A szhatrol jelek egy karaktereket

9.2.

9.3.

9.4.

9.5.

257

9. Visszavezets egyedi felsorolkkal

9.6.

9.7.

9.8.

9.9.

tartalmaz szhatr nev halmazban tallhatk. Feltehetjk, hogy a szavak 60 karakternl rvidebbek. Adott egy keresztneveket s egy virgneveket tartalmaz szekvencilis fjl, mindkett abc szerint szigoran nvekeden rendezett. Hatrozzuk meg azokat a keresztneveket, amelyek nem virgnevek, illetve azokat a neveket, amelyek keresztnevek is, s virgnevek is! Egy x szekvencilis inputfjl egy knyvtr nyilvntartst tartalmazza. Egy knyvrl ismerjk az azonostjt, a szerzjt, a cmt, a kiadjt, a kiads vt, az aktulis pldnyszmt, az ISBN szmt. A knyvek azonost szerint szigoran nvekven rendezettek. Egy y szekvencilis inputfjl az aznapi knyvtri forgalmat mutatja: melyik knyvbl hnyat vittek el, illetve hoztak vissza. Minden bejegyzs egy azonostt s egy eljeles egszszmot - ha elvittk: negatv, ha visszahoztk: pozitv - tartalmaz. A bejegyzsek azonost szerint szigoran nvekven rendezettek. Aktualizljuk a knyvtri nyilvntartst! A feldolgozs sorn keletkez hibaeseteket egy h sorozatba rjuk bele! Egy vllalat dolgozinak a fizetsemelst kell vgrehajtani gy, hogy az azonos beoszts dolgozk fizetst ugyanakkora szzalkkal emeljk. A trzsfjl dolgozk sorozata, ahol egy dolgozt hrom adat helyettest: a beosztskd, az egyni azonost, s a br. A trzsfjl beosztskd szerint nvekven, azon bell azonost szerint szigoran monoton nvekven rendezett. A mdost fjl beosztskd-szzalk prok sorozata, s beosztskd szerint szigoran monoton nvekven rendezett. (Az egyszersg kedvrt feltehetjk, hogy csak a trzsfjlban elfordul beosztsokra vonatkozik emels a mdost fjlban, de nem felttlenl mindegyikre.) Adjuk meg egy j trzsfjlban a dolgozk emelt breit! Egy egyetemi kurzusra jr hallgatknak hrom gptermi zrthelyit kell rnia a flv sorn. Kt flvkzit, amelyikbl az egyiket .Net/C#, a msikat Qt/C++ platformon. Azt, hogy a harmadik zrthelyin ki milyen platformon dolgozik, az dnti el, hogy a flvkzi zrthelyiken hogyan szerepelt. Aki mindkt flvkzi zrthelyit teljestette, az szabadon vlaszthat platformot. Aki egyiket sem, az nem vehet rszt a flvvgi

258

9.7I.9.7. Feladatok

zrthelyin, szmra a flv rvnytelen. Aki csak az egyik platformon rta meg a flvkzit, annak a flvvgit a msik platformon kell teljestenie. Minden gyakorlatvezet elkszti azt a kimutatst (szekvencilis fjl), amely tartalmazza a sajt csoportjba jr hallgatk flvkzi teljestmnyt. Ezek a fjlok hallgati azonost szerint rendezettek. A fjlok egy eleme egy hallgati azonostbl s a teljestmny jelbl (X mindkt platformon teljestett, Q csak Qt platformon, N csak .net platformon, 0 egyik platformon sem) ll. Rendelkezsnkre llnak tovbb a flvvgi zrthelyire bejelentkezett hallgatk azonosti rendezett formban egy szekvencilis fjlban. lltsuk el azt a szekvencilis outputfjlt, amelyik a zrthelyire bejelentkezett hallgatk kzl csak azokat tartalmazza, akik legalbb az egyik flvkzi zrthelyit teljestettk. Az eredmny fjlban minden ilyen hallgat azonostja mellett tntessk fel, hogy milyen platformon kell a hallgatnak dolgoznia: .Net-en, Qt-vel vagy szabadon vlaszthat. 9.10. Az x szekvencilis inputfjlban egsz szmok vannak. Van-e benne pozitv illetve negatv szm, s ha mindkett van, akkor melyik fordul el elbb?

259

10. Feladatok megoldsa

10. Feladatok megoldsa


1. fejezet feladatainak megoldsa 1.1. Mi az llapottere, kezdllapotai, adott kezdllapothoz tartoz clllapotai az albbi feladatnak? Egy egyenes vonal egyenletesen halad piros Opel s kilomtert t id alatt tesz meg. Mekkora az tlagsebessge? Els megolds: A bemen adatok rtkt megrzi a clllapot llapottr: A = (t: Kezdllapotok: Olyan vals szm nem negatv, a Formlisan: { (s, t, Clllapotok: Egy (s, t, clllapot: (s, t, s/t) , id: , seb:) szm hrmasok, ahol az els msodik pedig pozitv. x) s 0 t>0 } x) kezdllapothoz tartoz

Msodik megolds: A bemen adatok rtkt nem rzi meg a clllapot llapottr: A = (t: , id: , seb:) Kezdllapotok: Olyan vals szm hrmasok, ahol az els szm nem negatv, a msodik pedig pozitv. Formlisan: { (s, t, x) s 0 t>0 } Clllapotok: Egy (s, t, x) kezdllapothoz tartoz clllapotok (*, *, s/t), ahol az els kt komponens tetszleges. Harmadik megolds: Egyik bemen adat helyn kpezzk az eredmnyt llapottr: A = (a: , b:) Kezdllapotok: Olyan vals szm prok, ahol az els szm nem negatv, a msodik pedig pozitv. Formlisan: { (s, t) s 0 t>0 } Clllapotok: Egy (s, t) kezdllapothoz tartoz clllapotok (s/t, t) Negyedik megolds: Az llapottr eleve kizrja a nem lehetsges kezdllapotokat

260

1. fejezet feladatainak megoldsa

llapottr: A = (t: 0+ , id: + , seb: 0+) Kezdllapotok: Brmelyik (s, t, x) llapot a feladat kezdllapota is Clllapotok: Egy (s, t, x) kezdllapothoz tartoz clllapotok: (*, *, s/t). 1.2. Mi az llapottere, kezdllapotai, adott kezdllapothoz tartoz clllapotai az albbi feladatnak? Adjuk meg egy termszetes szmnak egy valdi prm osztjt! Megolds: llapottr: A = (n:, d:, l: ) Kezdllapotok: Az sszes llapot. Clllapotok: Ha x sszetett szm, akkor egy (x,y,z) kezdllapothoz az sszes olyan (x,p,igaz) clllapot tartozik, ahol a p az x-nek valdi prm osztja. Ha x nem sszetett szm, akkor egy (x,y,z) kezdllapothoz az (x, *,hamis) clllapotok tartoznak. 1.3. Tekintsk az A = (n:, f:) llapottren az albbi programot! 1. Legyen f rtke 1 2. Amg n rtke nem 1 addig 2.a. Legyen f rtke f*n 2.b. Cskkentsk n rtkt 1-gyel! rjuk fel e program nhny vgrehajtst! Vlasz: < (5,y) (5,1) (5,5) (4,5) (4,20) (3,20) (3,60) (2,60) (2,120) (1,120) > < (1,y) (1,1) > < (0,y) (0,1) (0,0) (-1,0) (-1,0) (-2,0) > (vgtelen ciklus) < (5,y) (5,1) (5,5) (6,5) (6,30) (7,30) > (vgtelen ciklus) Hogyan lehetne a vgrehajtsokat ltalnosan jellemezni? Vlasz:

261

10. Feladatok megoldsa

ha x > 0 < (x, y) (x,1) (x,x) (x1,x) (1, x!) > ha x 0 < (x, y) (x,1) (x,x) (x1,x) (x1,x(x1)) (x2,x(x1)) > Megoldja-e a fenti program azt a feladatot, amikor egy pozitv egsz szmnak kell a faktorilist kiszmolni? Vlasz: Igen. Ehhez elg felrni a feladatot kezdllapotclllapot prok formjban: llapottr: A = (n:, f:) Kezdllapotok: Azok az (x,y) egsz szm prok, ahol az x pozitv. Clllapotok: Egy (x,y) kezdllapothoz a (*,x!) clllapot tartozik. Vigyzat! Nem lenne helyes, ha a feladatot gy hatroznnk meg, hogy rizze meg a clllapotnak els komponensben a bemen adatot, azaz az (x,y) kezdllapothoz csak az (x,x!) clllapot tartozzon. A program ugyanis elrontja az els komponens rtkt. 1.4. Tekintsk az A = (x:, y:) llapottren az albbi programot! 1. Legyen x rtke xy 2. Legyen y rtke x+y 3. Legyen x rtke yx rjuk fel e program nhny vgrehajtst! Vlasz: < (5,3) (2,3) (2,5) (3,5) > < (1,1) (0,1) (0,1) (1,1) > < (0,1) (1,1) (1,0) (1,0) > < (-5,3) (8,3) (8,5) (3,5) > Hogyan lehetne a vgrehajtsokat ltalnosan jellemezni? Vlasz: < (u,v) (uv,v) (uv,u) (v,u) > Megoldja-e a fenti program azt a feladatot, amikor kt, egsz tpus vltoz rtkt kell kicserlni?

262

1. fejezet feladatainak megoldsa

Vlasz: Igen. Ehhez elg felrni a feladatot kezdllapotclllapot prok formjban. llapottr: A = (x:, y:) Kezdllapotok: Brmelyik llapot egyben a feladat kezdllapota is. Clllapotok: Egy (u,v) kezdllapothoz tartoz clllapot a (v,u). Ebbl lthat, hogy a feladat az (u,v) (v,u) alak hozzrendelsekbl ll. A program pedig az (u,v)-bl elindulva minden esetben terminl, s ppen a (v,u) llapotban ll meg. 1.7. Tekintsk az albbi kt feladatot: 1) Adjuk meg egy 1-nl nagyobb egsz szm egyik osztjt! 2) Adjuk meg egy sszetett termszetes szm egyik valdi osztjt! Tekintsk az albbi hrom programokat az A = (n:, d:) llapottren: 1) Legyen a d rtke 1 2) Legyen a d rtke n 3) Legyen a d rtke n1. Amg a d nem osztja n-t addig cskkentsk a d-t. Melyik program melyik feladatot oldja meg? Vlasz: Az els feladatot mindhrom program megoldja. A msodik feladatot csak a harmadik program. 1.8. Tekintsk az A=(m:+, n:+, x:) llapottren mkd albbi programokat! 1) Ha m<n, akkor legyen az x rtke elszr a (1)m, majd adjuk hozz a (1)m+1-t, utna a (-1)m+2-t s gy tovbb, vgl a (-1)n-t! Ha m=n, akkor legyen az x rtke a (1)n! Ha m>n, akkor legyen az x rtke elszr a (-1)n, majd adjuk hozz a (-1)n+1-t, utna a (-1)n+2-t, s gy tovbb, vgl a (-1)m-t! 2) Legyen az x rtke a ((1)m+ (1)n)/2!

263

10. Feladatok megoldsa

rjuk fel e programok nhny vgrehajtst! Lssuk be, hogy mindkt program megoldja az albbi feladatot: Kt adott nem nulla termszetes szmhoz az albbiak szerint rendelnk egsz szmot: ha mindkett pros, adjunk vlaszul 1-et; ha pratlanok, akkor 1-et; ha paritsuk eltr, akkor 0-t! Megolds: Els program nhny vgrehajtsa: < (5,7,2351), (5,7,1), (5,7,0), (5,7,1) > < (7,7,333), (7,7,1) > < (8,4,0), (8,4,1), (8,4,0), (8,4,1), (8,4,0), (8,4,1) > < (8,8,0), (8,4,1) > < (8,5,0), (8,4,1), (8,4,0), (8,4,1), (8,4,0) > Induljunk el egy (m,n,x) llapotbl. Ha m n, akkor a harmadik komponens helyn tagonknt kpzdik a (1)m+(1)m+1+ + ( 1)n vagy a (1)n+(1)n+1+ + (1)m sszeg attl fggen, hogy m<n vagy m>n. Ez az sszeg 1 s +1 tagok vltakozsbl ll, ahol a szomszdos tagok kinullzzk egymst. Ha n s m egyszerre pratlanok vagy prosak, akkor az sszegnek csak a legutols tagja marad meg: (1)n vagy (1)m, amely pratlan esetben 1, pros esetben +1. Hasonl a helyezet m=n esetn is. Ha n s m paritsa eltr ilyenkor nyilvn m n , az sszeg pros darab tagbl ll, azaz az rtke ppen 0 lesz. Teht a program ppen a feladat ltal kijellt clllapotban ll meg. Msodik program nhny vgrehajtsa: < (5,7,2351), (5,7,1) > < (7,7,333), (7,7,1) > < (8,4,0), (8,4,1) > < (8,8,0), (8,4,1) > < (8,5,0), (8,4,0) > Elindulva egy (m,n,x) llapotbl abban az llapotban llunk meg, ahol a harmadik komponens ((1)m+(1)n)/2. Pros n-re s m-re az a kifejezs +1, pratlan n-re s m-re 1, eltr parits esetn

264

1. fejezet feladatainak megoldsa

pedig 0. Teht a program ppen a feladat ltal kijellt clllapotban ll meg. 1.7. Tekintsk az A 1,2,3,4,5 llapottren az albbi programot. (Itt tnyleg egy programot adunk meg, amelybl kiolvashat, hogy az egyes llapotokbl indulva az milyen vgrehajtsi sorozatot fut be.)

1 S 2 4 5

1,2,4,5 2,1 4,1,5,1,4 5,2,4

1 2 4 5

1,4,3,5,2 2,4 4,3,1,2,5,1 5,3,4

1 3 4 5

1,3,2,... 3,3,... 4,1,5,4,2 5,2,3,4

Az F feladat az albbi kezd-clllapot prokbl ll: {(2,1), (4,1), (4,2), (4,4) ,(4,5)}. Megoldja-e az S program az F feladatot? Megolds: Nem, mert a program nem minden esetben mkdik helyesen. A 2-es llapotbl indulva a program vagy az 1-es, vagy a 4-es llapotban ll meg, de a feladat a 2-hz csak az 1-et rendeli. 1.8. Legyen S olyan program, amely megoldja az F feladatot! Igaz-e, hogy a) ha F nem determinisztikus, b) ha F determinisztikus, akkor S is az? akkor S sem az?

Megolds: a) Nem igaz. Egy adott kezdllapot esetn a megold programnak elg a feladat ltal kijellt egyik clllapotban terminlnia. b) Nem igaz. Azokbl az llapotokbl indulva, ahol a feladat nincs rtelmezve, a program brhogyan viselkedhet. 1.9. Az S1 bvebb, mint az S2, ha S2 minden vgrehajtst tartalmazza. Igaz-e, hogy ha egy S1 program megoldja az F feladatot, akkor azt megoldja az S2 is. Megolds: Igaz. Egyrszt az S2 program a feladat kezdllapotaibl indulva biztosan terminl. Ha ugyanis lenne a feladat egy kezdllapotbl indul vgtelen hossz vgrehajtsa, akkor ez az S1 programnak is rsze lenne, teht az S1 program sem oldan

265

10. Feladatok megoldsa

meg a feladatot. Msrszt adott kezdllapot esetn az S2 program a feladat ltal kijellt clllapotok valamelyikben ll meg. Ha ugyanis mshol is meg tudna llni, akkor az S1 program is ilyen lenne, teht az S1 program sem oldan meg a feladatot. 1.10. Az F1 bvebb, mint az F2, ha F2 minden kezd-clllapot prjt tartalmazza. Igaz-e, hogy ha egy S program megoldja az F1 feladatot, akkor megoldja az F2-t is. Megolds: Nem igaz. Egyfell ugyan igaz, hogy S program az F2 feladat kezdllapotaibl indulva biztosan terminl (hiszen ezek a kezdllapotok egyben az F1 feladat kezdllapotai is, s az S program megoldja az F1 feladatot. Msfell azonban elkpzelhet, hogy egy adott kezdllapothoz az F1 feladat kt clllapotot is rendel, mondjuk a-t s b-t, de ezek kzl az F2 feladat csak a-t jelli ki clllapotnak, ugyanakkor az S program a b-ben terminl. Az S program teht megoldja az F1-et, de F2-t nem.

266

2. fejezet feladatainak megoldsa 2.1. Mit rendel az albb specifiklt feladat a (10,1) s a (9,5) llapotokhoz? Fogalmazzuk meg szavakban a feladatot! (prm(x) = x prmszm.) A = ( k:, p:) Ef = ( k=k k>0 ) Uf = ( k=k prm(p) Megolds: lltsuk el egy adott pozitv egsz szmhoz legkzelebb es prmszmot! (Nha kett ilyen is van.) (10,1) (10,11), (9,5) (9,7), (9,5) (9,11) 2.2. rjuk le szvegesen az albbi feladatot! (A perm(x') az x' permutciinak halmaza.) A = (x:n) Ef = ( x=x') Uf = ( x perm(x') Megolds: Rendezzk nvekv sorba az x tmb elemeit! 2.3. Specifiklja: Adott egy hmrskleti rtk Celsius fokban. Szmtsuk ki Farenheit fokban! Megolds: A = ( c:, f:) Ef = ( c=c ) Uf = (Ef f=c*(9/5)+ 32 ) 2.4. Specifiklja: Adott hrom egsz szm. Vlasszuk ki kzlk a legnagyobb rtket! Megolds:

i>1: (prm(i)

ki

kp ) )

i,j [1..n]: (i<j

x[i]

x[j]) )

267

10. Feladatok megoldsa

A = (a:, b:, c:, max:) Ef = ( a=a b=b c=c ) Uf = (Ef (ab ac) max=a (ba bc) max=b (ca cb) max=c ) 2.5. Specifiklja: Adottak egy ax+b=0 alak elsfok egyenlet a s b vals egytthati. Oldjuk meg! Megolds: A = (a:, b:, x:, v: *) Ef = (a=a b=b) Uf = ( Ef ( a=0 b=0 ) v=Azonossg ( a=0 b0 ) v=Ellentmonds a0 ( v=Egy megolds van

x=b/a ) )

2.6. Specifiklja: Adjuk meg egy termszetes szm sszes termszetes osztjt! Megolds: A = ( n:, h:2) Ef = ( n=n ) Uf = ( Ef h={d d n } ) 2.7. Specifiklja: Adjuk meg egy termszetes szm valdi termszetes osztjt! Megolds: A = ( n:, l: , d:) Ef = ( n=n ) Uf = ( Ef l=( k [2 .. n-1]:k n) l (d [2 .. n1] d n) = ( Ef l=( k : valdi_oszt(k,n)) l (valdi_oszt(d,n) ) 2.8. Specifiklja: Dntsk el, hogy prmszm-e egy adott termszetes szm? Megolds:

268

2. fejezet feladatainak megoldsa

A = ( n:, l: ) Ef = ( n=n ) Uf = ( Ef l = (n 1 ( Ef l=prm(n) )

k [2 .. p1]: (k p) ) =

2.9. Specifiklja: Adott egy sakktbln egy kirlyn (vezr). Helyezznk el egy msik kirlynt gy, hogy a kt kirlyn ne sse egymst! Megolds: A = (x1:, y1:, x2:, y2:) Ef = (x1=x1 y1=y1 x1, y1 [1..8] ) Uf = ( Ef x2, y2 [1..8] ( (x1 x2 y1= y2) (x1= x2 y1 y2) ( x1 x2 = y1 y2 )) ) 2.10. Specifiklja: Adott egy sakktbln kt bstya. Helyezznk el egy harmadik bstyt gy, hogy ez mindkettnek az tsben lljon! Megolds: A = (x1:, y1:, x2:, y2:, l: , x:, y:) Ef = (x1=x1 y1= y1 x2=x2 y2=y2 x1, y1, x2, y2 [1..8]) Uf = ( Ef l = ( (x1=x2 y1 y2 1) (y1= y2 x1 x2 1) ) l ( x, y [1..8] (x1=x2) (x=x1 y1<y2 y1<y<y2 y1>y2 y1>y>y2) (y1=y2) (y=y1 x1<x2 x1<x<x2 x1>x2 x1>x>x2 ) (x1 x2 y1 y2) (x=x1 y=y2 x=x2 y=y1) )

269

3. fejezet feladatainak megoldsa 3.1. Fejezzk ki a SKIP, illetve az ABORT programot egy tetszleges S program s valamelyik programszerkezet segtsgvel! Megolds: SKIP: hamis S ABORT: hamis S1 hamis S2

3.2. a) Van-e olyan program, amit felrhatunk szekvenciaknt, elgazsknt, s ciklusknt is? Vlasz: Igen. Pldul a SKIP ilyen. hamis S igaz SKIP hamis S SKIP SKIP

b) Felrhat-e minden program szekvenciaknt, elgazsknt, s ciklusknt is? Vlasz: Nem. Egy ltalnos S program ciklusknt nem rhat fel. 3.3. a) Adjunk meg olyan vgrehajtsi sorozatokat, amelyeket az r:=p+q rtkads az A= (p:, q:, r:) llapottren befuthat! Adjunk meg olyan feladatot, amelyet ez az rtkads megold!! Vgrehajtsok (1.1, 2.3, 0) < (1.1, 2.3, 0), (1.1, 2.3, 3.4)> (0, 0, 0) < (0, 0, 0), (0, 0, 0) > (3, 0, 5) < (3, 0, 5), (3, 0, 3) > Feladat: A= (p:, q:, r:) Ef = ( p=p q=q ) Uf = ( Ef r=p+q ) b) Adjunk meg olyan vgrehajtsi sorozatokat, amelyeket az n,m:=3,n-5 rtkads az A= (n:, m:) llapottren befuthat! Adjunk meg olyan feladatot, amelyet ez az rtkads megold!

270

3. fejezet feladatainak megoldsa

Vgrehajtsok (7, 1) < (7, 1), (3, 2)> (3, 1) < (3, 1), (3, 1), (3, 1) > Feladat: A= (n:, m:) Ef = ( n=n m=m n-5>0 ) Uf = ( Ef n=3 m= n5 ) 3.4. Adjunk meg olyan vgrehajtsi sorozatokat, amelyeket a (r:=p+q; p:=r/q) szekvencia befuthat az A= (p:, q:, r:) llapottren! Adjunk meg olyan egyetlen rtkadsbl ll programot, amely ekvivalens ezzel a szekvencival! Vgrehajtsok (1,1,1) < (1,1,1), (1,1,2), (2,1,2) > (3,0,1) < (3,0,1), (3,0,3), (3,0,3), (3,0,3)> (5,4,3) < (5,4,3), (5,4,9), (2.25,4,9) > rtkads: p,r:=(p+q)/q, p+q 3.5. Igaz-e, hogy az albbi hrom program ugyanazokat a feladatokat oldja meg? f1 S1 f1 S1 f2 S2 f3 S3 SKIP SKIP S1 S2 S3 SKIP f2 S2 f3 S3 f1 f2 f3 SKIP

271

10. Feladatok megoldsa

Vlasz: Nem. Az els elgazs abortl, ha egyik felttel sem teljesl, a msik kett ilyenkor SKIP-knt mkdik. A msodik elgazs (S1;S2;S3) szekvenciaknt mkdik, ha kezdetben f1 teljesl, majd S1 vgrehajtsa utn f2 teljesl, vgl S2 vgrehajtsa utn f3 is teljesl. A harmadik program viszont csak S1 hajtja vgre, ha kezdetben f1 teljesl. 3.6. rtelmezze az albbi feladatot! Adja meg nhny vgrehajtsi sorozatt a megadott elgazsnak! Mutassa meg, hogy a feladatot megoldja a program! A = (x:, n:) Ef = ( x=x ) Uf = ( n=abs(x) ) x0 n:=x x 0 n:=x

Bizonyts: Az elgazs felttelrendszere lefedi az sszes elfordul esetet, azaz minden llapotra legalbb az egyik felttel teljesl. Ha x0, akkor az x abszolt rtke maga az x, ezrt az n:=x rtkads megoldja a feladatot. Ha x 0, akkor az x abszolt rtke az x ellentetje, azaz n:=x. 3.7. Oldjuk meg az ax2+bx+c=0 alak egyenletet, amelynek adottak az a, b s c vals egytthati! Specifikci: A = ( a:, b:, c :, x1:, x2:, v: *) Ef =( a=a b=b c=c ) Uf = ( Ef (a 0 ( (b2+4ac < 0) v = Nincs vals gyk (b2+4ac = 0) (b2+4ac > 0) ( v = Kzs vals gyk ( v = Kt vals gyk
x1 x2 b ) 2a

x1

b2 2a

4ac

x2

b2 2a

4ac

))

272

3. fejezet feladatainak megoldsa

(a=0

(b 0

( v = Elsfok gyk

x1

c ) b

(b=0 c=0) v = Azonossg (b=0 c 0) v = Ellentmonds ) ) Algoritmus, amely az utfelttel ltal sugallt tbbszrs elgazs lesz. a 0
d : b2 4ac

b 0 d>0 vlasz:= Kt vals gyk vlasz:= Elsfok gyk


c b

d<0 vlasz:= Nincs vals gyk

d=0 vlasz:= Kzs vals gyk

b=0 c=0 vlasz := A z o n o s s g

b=0 c 0 vlasz := E l l e n t m o n d s

x1 , x 2 :
b 2a

x1 , x 2 :
b d 2a

x1

3.8. rtelmezze az albbi feladatot! Adja meg nhny vgrehajtsi sorozatt a megadott ciklusnak! Mutassa meg, hogy a feladatot megoldja a program. (Segtsgl megadtuk a ciklus egy invarins lltst s a htralev lpsszmra adhat fels becslst.) A = (x:) Ef = ( igaz ) Uf = ( x = 0 ) x 0 x:=x sgn(x) legfeljebb abs(n) htralev lps invarins llts: igaz

273

10. Feladatok megoldsa

Bizonyts: A feladat elfelttelbl kvetkezik az invarins llts, hiszen mindkett az igaz llts. Az invarins llts valban invarins, hiszen a ciklusmag vgrehajtsa utn is teljeslni fog az igaz llts. Ha egy llapotra az invarins mellett a ciklusfelttel tagadottja is teljesl, akkor teljesl a feladat utfelttele is, hiszen mindkett az x=0 llts. Ezzel a haladsi kritriumot igazoltuk. A lellsi kritriumhoz azt kell csak ltni, hogy az abs(x) rtke pozitv, ha a ciklusfelttel igaz, s ilyenkor a ciklusmag eggyel cskkenti az rtkt. gy vges lpsen bell olyan llapotba fogunk eljutni, amelyre a ciklusfelttel hamis. 3.9. rtelmezze az albbi feladatot! Adja meg nhny vgrehajtsi sorozatt a megadott programnak! Mutassa meg, hogy a feladatot megoldja a program. (Segtsgl megadtuk a ciklus egy invarins lltst s a htralev lpsszmra adhat fels becslst.) A = (n:, f:) Ef = ( n=n) Uf = ( f=n! ) f:=1 n 0 f:=f n n:=n1 Bizonyts: A program egy rtkadssal indul, amely hatsra egy (n,1) alak llapotba jutunk. Ez utn egy ciklus kvetkezik. Az (n,1) alak llapotok megfelel kiindul llapotai a ciklusnak, mert biztosan kielgtik a ciklus invarins lltst ( 1 n!=n! ). Az invarins llts valban invarins, hiszen a ciklusmag kt rtkadsa egy invarinst kielgt (n0,f0) llapotbl (f0 n0!=n!) az (n01, f0 n0) llapotba vezet, amelyre ugyancsak kielgti az invarinst: f0 n0 (n01)!=n! Ha egy llapotra az invarins mellett a ciklusfelttel tagadottja is teljesl, akkor teljesl a feladat utfelttele is (hiszen f n!=n! n=0 f=n!). Ezzel a haladsi kritriumot igazoltuk. legfeljebb n htralev lps ivarins llts: f n!=n!

274

3. fejezet feladatainak megoldsa

A lellsi kritriumhoz azt kell csak ltni, hogy az n vltoz rtke mindig pozitv, ha a ciklusfelttel teljesl s minden iterciban eggyel cskken. gy vges lpsen bell olyan llapotba fogunk eljutni, amelyre a ciklusfelttel hamis. 3.10. rtelmezze az albbi feladatot! Adja meg nhny vgrehajtsi sorozatt a megadott programnak! Mutassa meg, hogy a feladatot megoldja a program. (Segtsgl megadtuk a ciklus egy invarins lltst s a htralev lpsszmra adhat fels becslst.) A = (x:, n:, z:) Ef = (n=n x=x) Uf = ( z=(x)n ) z := 1 n 0 n pros x, n := z, n := x x, n/2 z x, n1 Bizonyts: A program egy rtkadssal indul, amely hatsra egy (x,n,1) alak llapotba jutunk. Ezutn egy ciklus kvetkezik, amelynek invarinst ez az llapot kielgti, hiszen 1 (x)n=(x)n. Az invarins llts valban invarins, mert a ciklusmag egy invarinst kielgt (x0,n0,z0) llapotbl (z0 (x0)n0=(x)n) indulva az n0 prossga esetn az (x0 x0,n0/2,z0) llapotba jut, amelyre z0 (x0 x0)n0/2=(x)n invarins fennll. Az n0 pratlansga esetn viszont az (x0,n01,x0 z0) llapotba jut, amelyre teljesl az x0 z0 (x0)n01=(x)n invarins. Tovbb, ha egy llapotra az invarins mellett a ciklusfelttel tagadottja is teljesl, akkor teljesl a feladat utfelttele is (hiszen z xn=(x)n n=0 z=(x)n). Ezzel a haladsi kritriumot igazoltuk. A lellsi kritriumhoz azt kell csak ltni, hogy az n vltoz rtke mindig pozitv, ha a ciklusfelttel teljesl s minden iterciban legalbb eggyel cskken. gy vges lpsen bell olyan llapotba fogunk eljutni, amelyre a ciklusfelttel hamis. legfeljebb n htralev lps ivarins llts: z xn=(x)n

275

4. fejezet feladatainak megoldsa 4.1. Szmoljuk ki kt termszetes szm szorzatt, ha a szorzs mvelete nincs megengedve! Specifikci: A = ( x:, y:, z:) Ef = ( x=x y=y )
x

Uf = ( Ef sszegzs: m..n ~ s ~ z f(i) ~

z=x*y ) = ( Ef

z
i 1

y)

1..x y

Algoritmus: z, i :=0, 1 i x z := z+y i := i+1 i: rvidebben

z := 0 i = 1 .. x z := z+y i:

4.2. Keressk meg egy termszetes szm legkisebb pros valdi osztjt! Specifikci: A = ( n:, l: , d:) Ef = ( n=n ) Uf = ( Ef

l, d

search(i n 2 i) )
i 2

n/2

Lineris keress: m..n ~ 2 .. n div 2 ind ~ d (i) ~ i|n 2|i

Algoritmus:

276

4. fejezet feladatainak megoldsa

l, i:=hamis, 2 l i n div 2 2|i, i

i:

l, d:= i|n

i := i+1 4.3. Vlogassuk ki egy egsz szmokat tartalmaz tmbbl a pros szmokat! Specifikci: A = ( x:n, y:n, k:) Ef = ( x=x )
n

Uf = ( Ef

y[1..k]=
i 1 2 x[ i ]

x[i ] ) (

az sszefzs jele)

sszegzs: m..n ~ 1..n s ~ y[1..k] f(i) ~ ha x[i] pros akkor <x[i]> klnben <> Algoritmus: k, i:=0, 1 k := 0 i: i n vagy i = 1 .. n x[i] pros k := k+1 y[k] := x[i] SKIP i: x[i] pros k := k+1 y[k] := x[i] i := i+1 Egymst kvet napokon megmrtk a dli hmrskletet. Hnyadikra mrtnk elszr 0 Celsius fokot azeltt, hogy elszr fagypont alatti hmrskletet regisztrltunk volna? Specifikci: SKIP

277

10. Feladatok megoldsa

A = ( x:, l: , d:) Ef = ( x=x ) Uf = ( Ef

l, d

search( x[i] 0
i 1

n 1

x[i 1] 0) )

Lineris keress: m..n ~ 1..n-1 ind ~ d (i) ~ x[i]=0 x[i+1]<0 Algoritmus: l, i:=hamis, 1 l i n-1 x[i+1]<0, i

i:

l, d:= x[i]=0

i := i+1 4.4. Egy tmbben a tornarn megjelent dikok magassgait troljuk. Keressk meg a legmagasabb dik magassgt! Specifikci: A = (x:n, max:) Ef = ( x=x 1 n ) Uf = ( Ef max = max x[i] )
i 1 n

Maximum kivlaszts: (az maximum indexnek elhagysval) m..n ~ 1..n f(i) ~ x[i] Algoritmus: max, i := x[1], 2 max := x[1] i: i n max< x[i] max := x[i] SKIP vagy i = 2 .. n max< x[i] max := x[i] SKIP i:

i := i + 1 4.5. Az f:[m..n] fggvnynek hny rtke esik az [a..b] vagy a [c..d] intervallumba?

278

4. fejezet feladatainak megoldsa

Specifikci: A = (m, n, a, b, c, d:, db:) Ef = ( m=m n=n a=a b=b


n

c=c

d=d )

Uf = ( Ef

db
i m f (i ) [ a..b] [c..d ]

1)

Szmlls: m..n ~ m..n c ~ db (i) ~ a f(i) b Algoritmus: db, i := 0, m i n a f(i) b db := db+1 c f(i) d SKIP

c f(i) d i: vagy db := 0 i = m .. n a f(i) b db := db+1 c f(i) d SKIP i:

i := i + 1 4.6. Egy tmbben szneket trolunk az sznskla szerinti nvekv sorrendben. Keressk meg a tmbben a vilgoskk sznt! Specifikci: A = (x:Sznn, l: ) Ef = ( x=x x rendezett ) Uf = ( Ef l=( i [m..n]: x[i]=vilgoskk) l (i [m..n] x[i]=vilgoskk) ) Logaritmikus keress: m..n ~ 1..n (i) ~ x[i]=vilgoskk

Algoritmus:

279

10. Feladatok megoldsa

ah, fh, l :=1, n, hamis l ah fh i: f(i)=h l := igaz

i := (ah+fh) div 2 f(i)>h fh := i-1 f(i)<h ah := i+1

4.7. A Fld felsznnek egy vonala mentn egyenl tvolsgonknt megmrtk a terep tengerszint feletti magassgt (mterben), s a mrt rtkeket egy tmbben troljuk. Melyik a legmagasabban fekv horpads a felsznen? Specifikci: A = ( x:n, ind:) Ef = ( x=x )
n 1

Uf = ( Ef

l,max,ind =

i 2 x[i 1] x[i ] x[i 1]

max

x[i ] )

Feltteles maximum keress: m..n ~ 2..n-1 f(i) ~ x[i] (i) ~ x[i1]>x[i]<x[i+1] Algoritmus: l := hamis i = 2 .. n-1 (x[i1]>x[i] l x[i1]>x[i] x[i]<x[i+1] x[i]<x[i+1]) SKIP max< x[i] max, ind := x[i], i SKIP l x[i1]>x[i] x[i]<x[i+1] i:

l, max, ind := igaz, x[i], i

4.8. Egymst kvet napokon megmrtk a dli hmrskletet. Hnyszor mrtnk 0 Celsiust gy, hogy kzvetlenl utna fagypont alatti hmrskletet regisztrltunk? Specifikci:

280

4. fejezet feladatainak megoldsa

A = ( x:n, db:) Ef = ( x=x )


n 1

Uf = ( Ef Szmlls: m..n ~ c ~ db (i) ~ Algoritmus:

db
i 1 x[i] 0 x[i 1] 0 ]

1)

1..n-1 x[i]=0 db := 0 x[i+1]<0

i = 1 .. n-1 x[i]=0 x[i+1]<0 SKIP

i:

db := db+1

4.9. Egy n elem tmbben trolt egsz szmoknak az sszegt egy rekurzv fggvnv n-edik helyen felvett rtkvel is megadhatjuk. Definiljuk ezt a rekurzv fggvnyt s oldjuk meg a feladatot a rekurzv fggvny helyettestsi rtkt kiszmol programozsi ttel segtsgvel! Specifikci: A = (x:n, s:) Ef = ( x=x ) Uf = ( Ef s=f(n) )ahol f(0)=0 s i [1..n]: f(i)=f(i1)+x[i] Rekurzv fggvny helyettestsi rtke: k, m ~ 1, 1 y ~ s em1 ~ 0 h(i,f(i1)) ~ f(i1)+x[i] Algoritmus: s := 0 i = 1 .. n s := s+x[i] i:

281

5. fejezet feladatainak megoldsa 5.1. Adott a skon nhny pont a koordintival. Keressk meg az orighoz legkzelebb es pontot! Specifikci: A = (x:n, y:n, ind:) Ef = ( x=x y=y n>0 ) Uf = ( Ef
2

min, ind = min ( x[i]2


i 1
2

y[i]2 ) )

(Az x[i] +y[i] az (x[i], y[i]) koordintj pont origtl vett tvolsgnak ngyzete.) Minimum kivlaszts: m..n ~ 1..n f(i) ~ x[i]2+y[i]2 max ~ min min, ind:= x[1]2+y[1]2, 1 i = 2 .. n min > x[i]2+y[i]2 min, ind:= x[i]2+y[i]2, i SKIP 5.2. Egy hegyoldal hegycscs fel vezet svnye mentn egyenl tvolsgonknt megmrtk a terep tengerszint feletti magassgt, s a mrt rtkeket egy vektorban troljuk. Megfigyeltk, hogy ezek az rtkek egyszer sem cskkentek az elz rtkhez kpest. Igaz-e, hogy mindig nvekedtek? Specifikci: A = (x:n, l: ) Ef = ( x=x i [2..n]:x[i] x[i1] ) Uf = ( Ef l = i [2..n]:x[i] x[i1] ) = = ( Ef i:

search( x[i]
i 2

x[i 1]) )

Optimista lineris keress (eldnts):

282

6. fejezet feladatainak megoldsa

m..n (i)

~ ~

2..n x[i] x[i1] i:

l,i:= igaz, 2 l i n l := x[i] x[i1] i := i+1

5.3. Hatrozzuk meg egy egsz szmokat tartalmaz tmb azon legkisebb rtkt, amely k-val osztva 1-et ad maradkul! Specifikci: A = (x:n, l: min:, ind:) Ef = ( x=x )
n

Uf = ( Ef

l, min, ind =

i 1 x[ i ] mod k 1

min x[i ] )

Feltteles minimumkeress: m..n ~ 1..n f(i) ~ x[i] (i) ~ x[i] mod k =1 max ~ min l := hamis i = m .. n x[i] mod k 1 SKIP l x[i] mod k =1 min< x[i] min, ind:= x[i], i SKIP l x[i] mod k =1 l, min, ind := igaz, x[i], i i:

5.4. Adottak az x s y vektorok, ahol az y elemei az x indexei kzl valk. Keressk meg az x vektornak az y-ban megjellt elemei kzl a legnagyobbat! Specifikci:

283

10. Feladatok megoldsa

A = (x:m, y:n, max:, ind:) Ef = ( x=x n>0 m>0 j [1..n]:y[j] [1..m] ) Uf = ( Ef max, ind = max x[ y[i]] )
i 1 n

Maximum kivlaszts: m..n ~ 1..n f(i) ~ x[y[i]] max, ind := x[y[1]], 1 i = 2 .. n max <x[y[i]] max, ind:= x[y[i]], i SKIP 5.5. Igaz-e, hogy egy tmbben elhelyezett szveg odafel s visszafel olvasva is ugyanaz? Specifikci: A = (x: n, l: ) Ef = ( x=x ) Uf = ( Ef l = i [1.. n div 2]:(x[i]=x[ni+1]) ) = = ( Ef l= search ( x[i]
i 1 ndiv2

i:

x[n i 1]) )

Optimista lineris keress: m..n ~ 1.. n div2 (i) ~ x[i]=x[ni+1] l, i:= igaz, 1 l i
n div2

i:

l := x[i]=x[ni+1] i := i+1 5.6. Egy mtrix egsz szmokat tartalmaz sorfolytonosan nveked sorrendben. Hol tallhat ebben a mtrixban egy tetszlegesen megadott rtk!

284

6. fejezet feladatainak megoldsa

Specifikci: A = (t:0..n-10..m-1, l: , ind:, jnd:) Ef = ( t=t t sorfolytonosan nveked ) Uf = ( Ef l= k [0..nm1]:(t[k div m, k mod m]=h) l (k [0..nm1] ind=k div m jnd = k mod m t[ind, jnd]=h) ) Logaritmikus keress: m..n ~ 0.. nm1 i ~ k (i) ~ t[k div m, k mod m]=h ah ,fh, l :=0, nm1, hamis l ah fh k: =h l := igaz SKIP kzs

k :=(ah+fh) div 2 t[k div m, k mod m] >h fh := k1 l ind, jnd := k div m, k mod m <h ah := k+1

5.7. Keressk meg kt termszetes szm legkisebb tbbszrst! Specifikci: A =(n:, m:, d:) Ef = ( n=n n=m ) Uf = ( Ef n|d m|d i [n..d1]: (n|i m|i) ) = = ( Ef d= select (n d m d ) )
d n

Kivlaszts: m ~ n i ~ d (i) ~

n|d

m|d

285

10. Feladatok megoldsa

d: = n (n|d m|d)

d := d+1 5.8. Keressk meg kt termszetes szm legnagyobb kzs osztjt! Specifikci: A = (n:, m:, d:) Ef = ( n=n n=m ) Uf = ( Ef d|n d|m i [d+1..n]: (i|n i|m) ) = = ( Ef d= select (d n d m) )
d n

Kivlaszts: m ~ n i ~ d (i) ~

n|d d := n (d|n

m|d

d|m)

d := d1 5.9. Prm szm-e egy egynl nagyobb egsz szm? Specifikci: A = (n:, l: ) Ef = ( n=n n>1 ) Uf = ( Ef l = i [2.. n ]: i|n ) =
n

= ( Ef

search i n] )
i 2

Optimista lineris keress: m..n (i) ~ ~ 1.. n i|n

286

6. fejezet feladatainak megoldsa

l, i:= igaz, 2 l i

i:

l := i|n i := i+1 5.10. Egy n elem tmb egy b alap szmrendszerben felrt termszetes szm szmjegyeinek rtkeit tartalmazza gy, hogy a magasabb helyirtkek vannak ell. Mdostsuk a tmbt gy, hogy egy olyan termszetes szm szmjegyeit tartalmazza, amely az eredetinl eggyel nagyobb, s jelezzk, ha ez a megnvelt rtk nem brzolhat n darab helyirtken! Specifikci: A = (x:{0..9}n, c:{0,1}) Ef = ( x=x ) Uf = ( (x,c) = f(n) ) f:[0 .. n] {0..9}n{0,1} f(0) = (x,1) i [1..n1]: ha f(i)2=0 akkor f(i+1) = f(i) klnben f(i+1)1 = f(i)1f(i)1[n i ] ( f(i)1[n i ] 1) mod 10 f(i+1)2 = ( f(i)1[n i] 1) div 10 Rekurzv fggvny helyettestsi rtke: (Nem ez a leghatkonyabb megolds.) k, m ~ 1, 0 y ~ x, c em1 ~ x, 1 y:=h(i,f(i1)) ~ x[ni], c:=(x[ni]+1) mod 10, (x[ni]+1) div 10 c := 1 i = 0 .. n c=0 SKIP x[ni], c := (x[ni]+1) mod 10, (x[ni]+1) div 10 i:

287

10. Feladatok megoldsa

6. fejezet feladatainak megoldsa 6.1. Volt-e a lversenyen olyan napunk, amikor gy nyertnk, hogy a megelz k napon mindig vesztettnk (Oldjuk meg ktflekppen is a feladatot: lineris keressben egy lineris keresssel, illetve lineris keressben egy rekurzv fggvnnyel!) a) Specifikci: A = (x:n, k:, l: ) Ef = ( x=x k=k ) Uf = ( Ef l = i [k+1..n]:(x[i]>0 mlt(i)) =
n

= ( Ef

search ( x[i ] 0
i k 1

mlt(i)) )

ahol mlt:[k+1..n]

s
search ( x[ j ] 0 )
j i k i 1

mlt(i) = j [ik..i1]: x[j]<0 =

Lineris keressbe gyazott optimista lineris keress: l, i:= hamis, k+1 l i n mlt(i) i: l:=mlt(i) l, j:= igaz, ik l j i1 l := x[j]<0 j :=j+1 b) Specifikci: j:

l := x[i]>0

i := i+1

288

6. fejezet feladatainak megoldsa

A = (x:n, k:, l: ) Ef = ( x=x k=k ) Uf = ( Ef l= i [2..n]:(x[i]>0


n

mlt(i)=k) )=
mlt(i) k) )

= ( Ef

search ( x[i ] 0
i 2

ahol mlt(1) = 0 s mlt(i) =


mlt(i 1) 1 ha x[i 1] 0 0 ha x[i 1] 0

Lineris keressben rekurzv fggvny kibontsa: l, i:= hamis, 2 l i n mlt(i)=k m: i : l, i, m:= hamis, 2, 0 l i n x[i1]<0 m := m+1 l := x[i]>0 i := i+1 6.2. Egymst kvet napokon dlben megmrtk a leveg hmrsklett. llaptsuk meg, hogy melyik rtk fordult el leggyakrabban! A feladat megoldsakor azt a napot hatrozzuk meg, amelyiken mrt hmrsklet a leggyakrabban fordult el. Specifikci: A = (x:n, nap:) Ef = ( x=x ) Uf = ( Ef max, nap= max hny(i) )
i 1
i 1

l := x[i]>0

i := i+1

m:=0 m=k

ahol hny:[1..n] s hny(i) =

1
j 1

x[ j ] x[i ]

Maximum kivlasztsba gyazott szmlls:

289

10. Feladatok megoldsa

max, nap:= 1, 1 i := 2 .. n h := hny(i) h>max max, nap:=h, i SKIP i:

h:=hny(i) h := 0 j = 1 .. i-1 x[j]=x[i] h := h+1 SKIP j:

6.3. A tornarn nvsor szerint sorba lltottuk a dikokat, s megkrdeztk a testmagassgukat. Hnyadik dikot elzi meg a legtbb nla magasabb? Specifikci: A = (x:n, dik:) Ef = ( x=x ) Uf = ( Ef max,dik = max hny (i ) )
i 1 n

ahol hny:[1..n]

s hnyt(i) =

i 1

1
j 1

x[ j ] x[i ]

Maximum kivlasztsba gyazott szmlls: max, dik := 0, 1 i = 2 .. n h := hny(i) h>max max, dik:=h, i SKIP i : h:=hny(i) h := 0 j = 1 .. i1 x[j]>x[i] h := h+1 SKIP j:

6.4. llaptsuk meg, hogy egy adott sz (egy karakterlnc) elfordul-e egy adott szvegben (egy msik karakterlncban)! a) Specifikci: A = (s: n, p: m, l: ) Ef = ( s=s p=p ) Uf = (Ef l = i [1..nm+1]: (s[i..i+m1]=p[1..m]) = = ( Ef
l search ( search ( s[i
i 1 j 1 n m 1 m

j 1]

p[ j ])) )

Lineris keressbe gyazott optimista lineris keress:

290

6. fejezet feladatainak megoldsa

l, i:= hamis, 1 l l := s[i..i+m1]=p[1..m] i := i+1 i nm+1

i:

l := s[i..i+m1]= p[1..m] l, j:= igaz, 1 l j m j := j+1 l := s[i+j1]= p[j] j:

6.5. Keressk meg a t ngyzetes mtrixnak azt az oszlopt, amelyben a ftlbeli s a feletti elemek sszege a legnagyobb! Specifikci: A = (t:nn, oszlop:) Ef = ( t=t ) Uf = ( Ef max,oszlop = max (sszeg ( j )) )
j 1 n

ahol sszeg:[1..n] s sszeg(j) =

t[i, j ] , s pldul
i 1

sszeg(1) = t[1,1]. Maximum kivlasztsba gyazott sszegzs: max, oszlop:= t[1,1], 1 j = 2 .. n s := sszeg(j) s>max max, oszlop:=s, j SKIP j: s:=sszeg(i) s := 0 i = 1 .. j s := s+t[i,j] i:

6.6. Egy hatrllomson feljegyeztk az tlp utasok tlevlszmt. Melyik tlevlszm utas fordult meg leghamarabb msodszor a hatron? A feladat ktflekppen is rtelmezhet. Vagy azt az utast keressk, akirl legelszr derl ki, hogy korbban mr tlpett a hatron, vagy azt, akinek kt egymst kvet tlpse kzt a lehet legkevesebb msik utast talljuk. a) Specifikci: A = (x:( *)n, l: , szm: *) Ef = ( x=x )

291

10. Feladatok megoldsa

Uf = ( Ef = ( Ef

l = i [1..n]: j [1..i1]: x[i]= x[j] ) =


l , ind search ( search ( x[i]
i 1 j 1 n i 1

x[ j ]))

l szm=x[ind] ) Lineris keressbe gyazott lineris keress: l,i:= hamis, 1 l i n l := bels keress(i) szm :=x[i] i := i+1 b) Specifikci: A = (x:( *)n, l: , i:) Ef = ( x=x )
n

i:

l := bels keress(i) l,j := hamis, 1 l j i1 j := j+1 j:

l := x[i]= x[j]

Uf = ( Ef

min ( k
k 1 f 1(k)

f 2(k)) )

ahol f:[1..n] egy ktrtk fggvny, azaz f1(k) egy logikai rtk, f2(k) pedig egy termszetes szm.
1

k [1..n]: f(k) - keres ( x[k ]


j k 1

x[ j ])

Feltteles minimum keressbe gyazott fordtott lineris keress: l := hamis k := 1 .. n ll, d := f(k) ll SKIP l ll l ll min>kd min, i := kd, k SKIP k: ll: , d:

l, min, i := igaz, kd, k

292

6. fejezet feladatainak megoldsa

ll, d := f(k) ll, j := hamis, k-1 ll j 1 j:

ll, d := x[k]=x[j], j j := j1 6.7. Egymst kvet htvgeken feljegyeztk, hogy a lversenyen mennyit nyertnk illetve vesztettnk (ez egy eljeles egsz szm). Hnyadik hten fordult el elszr, hogy az sszestett nyeresgnk (az addig nyert illetve vesztett pnzek sszege) negatv volt? Specifikci: A = (x:n, l: , i:) Ef = ( x=x k=k ) Uf = ( Ef

l, i

search (nyeresg ( i ) 0) )
i 1
i

ahol nyeresg:[0..n] s nyeresg(i) =

x[ j ]
j 1

vagy nyeresg(0)=0 s nyeresg(i)=nyeresg(i1)+x[i] Lineris keressbe gyazott rekurzv fggvny: l, i:= hamis, 1 l i n ny: l := nyeresg(i)<0 i := i+1 i: l, i, ny:= hamis, 1, 0 l i n

ny := ny+x[i] l := ny<0 i := i+1

6.8. Dntsk el, hogy egy termszetes szmokat tartalmaz mtrixban e) van-e olyan sor, amelyben elfordul prm szm (van-e a mtrixban prm szm) Specifikci:

293

10. Feladatok megoldsa

A = (t:nm, l: ) Ef = ( t=t )
n m j 1

Uf = ( Ef

search ( search prm (t[i, j ])) )


i 1

ahol prm:

s prm(a) = (a>1

search( (k a)) )
k 2

Keressben keressbe gyazott optimista keress: 25 l := sor(i) l, i:= hamis, 1 l i n l, j := hamis, 1 l j m l := prm(t[i,j]) l, k := t[i,j]>1, 2 l j

t[i, j ]

l := sor(i) i := i+1

l := prm(t[i,j]) j := j+1

l := (k t[i,j]) k := k+1

f) van-e olyan sor, amelyben minden szm prm A = (t:nm, l: ) Ef = ( t=t )


n m j 1

Uf = ( Ef

search( search prm (t[i, j ])) )


i 1

ahol prm:

s prm(a) = (a>1

search( (k a)) )
k 2

Keressben optimista keressbe gyazott optimista keress: l := sor(i) l, i:= hamis, 1 l i n l, j := igaz, 1 l j m l := prm(t[i,j]) l, k := t[i,j]>1, 2 l j

t[i, j ]

l := sor(i) i := i+1

l := prm(t[i,j]) j := j+1

l := (k t[i,j]) k := k+1

g) minden sorban van-e legalbb egy prm


25

Mostantl kezdve nem tntetjk fel kln a programok segdvltozit.

294

6. fejezet feladatainak megoldsa

A = (t:nm, l: ) Ef = ( t=t )
n m j 1

Uf = ( Ef

search ( search prm (t[i, j ])) )


i 1

ahol prm:

s prm(a) = (a>1

search( (k a)) )
k 2

Optimista keressben lineris keressbe gyazott optimista keress: l := sor(i) l ,i:= igaz, 1 l i n l, j := hamis, 1 l j m l := prm(t[i,j]) l, k := t[i,j]>1, 2 l j

t[i, j ]

l := sor(i) i := i+1

l := prm(t[i,j]) j := j+1

l := (k t[i,j]) k := k+1

h) minden sorban minden szm prm (a mtrix minden eleme prm) A = (t:nm, l: ) Ef = ( t=t )
n m j 1

Uf = ( Ef

search( search prm (t[i, j ])) )


i 1

ahol prm:

s prm(a) = (a>1

search( (k a)) )
k 2

Optimista keressben optimista keressbe gyazott optimista keress: l := sor(i) l, i:= igaz, 1 l i n l, j := igaz, 1 l j m l := prm(t[i,j]) l, k := t[i,j]>1, 2 l j

t[i, j ]

l := sor(i) i := i+1

l := prm(t[i,j]) j := j+1

l := (k t[i,j]) k := k+1

295

10. Feladatok megoldsa

6.9. Egy kutya killtson n kategriban m kutya vesz rszt. Minden kutya minden kategriban egy 0 s 10 kztti pontszmot kap. Van-e olyan kategria, ahol a kutyk kztt holtverseny (azonos pontszm) alakult ki? Specifikci: A = (t:nm, l: ) Ef = ( t=t ) Uf = ( Ef
i

i search (rt 1 (m) 1) ) i 1

ahol rt :[0..m] egy rekurzv fggvny, amelynek j-edik helyen felvett msodik rtke (max) azt mutatja, hogy az i-edik kategriban az els j pontszm kzl melyik a legnagyobb, az els rtke (db) pedig azt, hogy ez a pontszm az els j pontszm kztt hnyszor fordult el. rti (0)=
i i (rt 1 (j 1) 1, rt 2 (j 1)) ha t[i, j ]

(0,-1)
i rt 2 (j 1) i rt 2 (j 1)

rt i (j)

(1, t[i, j ])
i i (rt 1 (j 1), rt 2 (j 1))

ha t[i, j ]

i ha t[i, j ] rt 2 (j 1)

Lineris keressben rekurzv fggvny: l ,i := hamis, 1 db:=rti1(m) l j n db, max :=0, -1 j = 0 .. m t[i,j]=max t[i,j]>max t[i,j]<max SKIP db := db+1 db, max := 1,t[i,j] l := rti1(m)>1 i := i+1

Az alprogram futsi ideje gyorsthat, ha az kzvetlenl az l:=rti1(m)>1 rszfeladatot oldja meg, de gy, hogy amikor a rekurzv fggvny db komponense elri a 2-t, akkor lell, azaz az l := j [1..m]: rti1(m)=2 feladatra ad megoldst. Ekkor ezt egy lineris keressre

296

6. fejezet feladatainak megoldsa

vezethetjk vissza, amelyen bell a rekurzv fggvny kibontsra kerl sor. l := j [1..m]: rti1(m)=2 l, j, db, max := hamis, 1, 0, -1 l t[i,j]=max db := db+1 j m t[i,j]<max SKIP

t[i,j]>max db, max := 1,t[i,j] l:=db=2 j:=j+1

6.10. Madarak letnek kutatsval foglalkoz szakemberek n klnbz teleplsen m klnbz madrfaj elfordulst tanulmnyozzk. Egy adott idszakban megszmoltk, hogy az egyes teleplsen egy madrfajnak hny egyedvel tallkoztak. Hny teleplsen fordult el mindegyik madrfaj? Specifikci: A = (t:nm, db:) Ef = ( t=t )
n

Uf = ( Ef

db

1)
i 1 mind(i)

ahol mind:[1..n]

s mind(i) =

search (t[i, j ] 0 )
j 1

Szmllsban optimista keress: db := 0 i = 1 .. n mind(i) db := db+1 SKIP l:=mind(i) l, j := igaz, 1 l j m j := j+1

l := t[i,j] >0

297

7. fejezet feladatainak megoldsa 7.1. Valstsuk meg a racionlis szmok tpust gy, hogy kihasznljuk azt, hogy minden racionlis szm brzolhat kt egsz szmmal, mint azok hnyadosa! Implementljuk az alapmveleteket! Megolds: A = (a:, b:, c:) c := a b A = (a:, b:, c:) c := a*b A = (a:, b:, c:) c := a/b : (x1, x2) = x1/x2 I(x1, x2) = x2 0 a-t az x1, x2, b-t az y1, y2, c-t a z1, z2 reprezentlja ahol x1, x2, y1, y2, z1, z2:
msodik szm nem nulla

z1, z2 := x1*y2 x2*y1, x2*y2 z1, z2 := x1*y1, x2*y2 z1, z2 := x1*y2, x2*y1

7.2. Valstsuk meg a komplex szmok tpust! brzoljuk a komplex szmokat az algebrai alakjukkal (x+iy)! Implementljuk az alapmveleteket! Megolds: A = (a:, b:, c:) c := a b A = (a:, b:, c:) c := a*b A = (a:, b:, c:) c := a/b

298

8. fejezet feladatainak megoldsa

(x1, x2) = x1 + i x2 a-t az x1, x2, b-t az y1, y2, c-t a z1, z2 reprezentlja ahol x1, x2, y1, y2, z1, z2:

z1, z2 := x1 y1, x2 y2 z1, z2 := x1y1 x2y2 , x1y2 + x2y1 z1, z2 := (x1x2+y1y2)/(x12+y12), (x1y2y1x2)/(x12+y12)

7.3. Valstsuk meg a skvektorok tpust! Implementljuk kt vektor sszegnek, egy vektor nyjtsnak, s forgatsnak mveleteit! Megolds: Vektor A = (a:V, b:V, c:V) c := a+b A = (a:V, k:, c:V) c := k*a A = (a:V, :, c:V) c := F (a) : V (x1, x2) = Px1 x 2 a-t az x1, x2, b-t az y1, y2, c-t a z1, z2 reprezentlja ahol x1, x2, y1, y2, z1, z2, k, : z1, z2 := x1+y1, x2 + y2 z1, z2 := k*x1, k* x2 z1, z2 := x1 cos x2 sin , x1 sin + x2 cos

7.4. Valstsuk meg a ngyzet tpust! Ennek rtkei a sk ngyzetei, amelyeket el lehet tolni egy adott vektorral, s fel lehet nagytani!

299

10. Feladatok megoldsa

Megolds: brzoljuk a ngyzetet (N) a kzppontjval s az egyik tljnak felvel, azaz kt vektorral. A vektor tpust (V) az elz feladatban mr megvalstottuk. A ngyzet cscsait gy kaphatjuk meg, hogy a kzpponthoz hozzadjuk a fltlt, annak ellentetjt, a derkszg elforgatottjt, s ennek ellentetjt. N A = (a:N, v:V, c:N) c := eltol(a,v) A = (a:N, k:, c:N) c := k*a :VV N (x1, x2) = a-t x1, x2, a c-t z1, z2 reprezentlja ahol x1, x2, z1, z2: V, k : VV z1 := x1+v z2 := k* x2 7.5. Valstsuk meg azt a zsk tpust, amelyikrl tudjuk, hogy csak az 1 s 100 kztti termszetes szm kerlhet bele, de egy szm tbbszr is! Implementljuk az j elem behelyezse, egy elem kivtele s egy elem hnyszor van benne a zskban mveleteket! Megolds: Elszr egy absztrakt tpussal rjuk le a zsk fogalmt, majd ezt egy olyan konrt tpussal valstjuk meg, ahol egy zskot egy 100 elem termszetes szmokbl ll tmbben brzolunk gy, hogy ennek e-edik eleme azt mutassa meg, hogy az e szm hnyszorosan van benn a zskban. Jl lthat, hogy a konkrt tpus sokkal hatkonyabb (tmrebb reprezentci, rvidebb implementci) lesz, mint az absztrakt.
1 s 100 kztti egsz szmokat tartalmaz

betesz kivesz hnyszor

Zsk

300

8. fejezet feladatainak megoldsa

:2

Zsk

identits (e,m) h (e,m) h (e,m) h (e,m) h (e,m) h

I(h)={ (e,m) h e [1..100]} h: 2, e:, db: h:= h-{(e,m)}) h:=h {(e,1)} h:= h-{(e,m)} db:= m db:= 0 v[e] 0} v:100, e:, db: {(e,m+1)}

1 s 100 kztti egsz szm s darabszm prok

halmaza 2

:100 100

NN

(v)={(e,v[e]) | e [1..100]

v[e]:=v[e]+1 v[e]:=0 db:= v[e]

7.6. Valstsuk meg az egsz szmokat tartalmaz sor tpust! A sor elemeit egy tmbben troljuk, a sor mveletei pedig a sor vgre betesz, sor elejrl kivesz, megvizsglja, hogy res-e illetve telee a sor. Megolds: Elszr egy absztrakt tpussal rjuk le a sor fogalmt, majd ezt egy olyan konkrt tpussal valstjuk meg, ahol egy sort egy 0-tl 99-ig indexelt egsz szmokat tartalmaz tmbben brzoljuk. Ezt a tmbt ciklikusan kpzeljk el, azaz utols elemt az els eleme kveti. Ekkor egy i indexszel az albbiak szerint lpnk a kvetkez pozcira: i:=(i+1) mod 100. A sor elemeit ebben a tmbben kt megadott index kztt troljuk.
egsz szmokat tartalmaz

betesz kivesz res-e Tele-e

Sor

301

10. Feladatok megoldsa

: * Zsk *

identits s:*, e:, l: s:= s, e s, e: = s2, ,s l:= s = 0 l:= s = 100


s

, s1

: 100 * (v,a,f,db) = v[a], ,v[f] db=fa+1 100 I(v,a,f,db) = v: 100

a,f [0..99] a,f,db:, e:

db<100

f:=(f+1) mod 100 v[f]:=e db:=db+1 e:=v[a] a:=(a+1) mod 100 db:=db-1

db>0

l:= db=0 l:= db=100 7.7. brzoljuk a nagyon nagy termszetes szmok tpust! A szmokat decimlisan brzoljunk egy kellen hossz tmbben! Megolds: brzoljuk a nagy szmokat helyirtk szerint nvekv sorrendben, azaz az egyes helyirtk a sorozat legelejn lljon. A = (a:, b:, c:) c := a+b A = (a:, b:, c:) c := a*b

302

8. fejezet feladatainak megoldsa

:{0..9}* I: {0..9}* {0..9}*

(x) =

x i 1

xi 10 i 1 , I(x) = x x 0

az a, b, c-t rendre az x,y,z :{0..9}* reprezentlja (z) := (x)+ (y) (z) := (x)* (y) Az sszeads egy rekurzv fggvnynek a max( x , y ) helyen trtn kiszmtsval oldhat meg: z=f1(max( x , y )) f2(max( x , y )). A msodik komponens a kvetkez helyirtkre tvitt rtk. f:[0..max( x , y )] {0..9}*{0..9} f(0) = (<>,0) i>0: f(i) = (f1(i-1) ((xi+yi+f2 (i-1)) mod 10) , (xi+yi+ f2(i-1)) div 10)

Terjesszk ki az xi illetve yi rtelmezst arra az esetre is, ha i> x illetve i> y . Ezzel az sszeadsban szerepl kevesebb szmjegybl ll szmot annyi nullval egsztjk ki, hogy a nagyobbikkal azonos hosszsg legyen. Az algoritmusban a mveletet egy sorozat j szmjeggyel val kiegsztsre alkalmazzuk. (z):= (x)+ (y) vagy z:=x+y z, d, i := <>, 0 ,1 i x z, d, i: = z i y

((xi+yi+d) mod 10), (xi+yi+d) div 10, i+1 z := z <d>

A szorzst visszavezethetjk tbb egy szmjeggyel val szorzsra s az gy kapott szorzatok sszeadsra. Az egy szmjeggyel ( cvel) val szorzs is egy rekurzv fggvnnyel fogalmazhat meg: w = f1( x ) f2( x ).

303

10. Feladatok megoldsa

f:[0.. x ] f(0) f(i) = (

= f1 (i-1) ((xi*c+f2 (xi*c+ f2 (i-1)) div 10

{0..9}*{0..9} (<>,0) (i-1)) mod 10) , ) i [1..n]

(w):= (x)*c vagy w:=x*c w, d, i := <>, 0 ,1 i x w, d, i: = w ((xi*c+d) mod 10), (xi*c+d) div 10, i+1 w := w <d>

Ezt, valamint a korbbi sszeads mveletet felhasznlva kapjuk meg a kt szm szorzst kiszmol programot. A szorzst valjban az sszegzs programozsi ttelre vezethetjk vissza, hiszen:
y

( z)
k 1 y

( x) y k 10 k z
k 1

azaz
yk )

0 ... 0
k 1darab

(x

A kpletben ltszik, hogy amikor a k-dik helyirtkrl szrmaz szmjeggyel szorzunk egy szmot, akkor azt mg 10k-1-gyel is meg kell szorozni, azaz k-1 darab nullt kell az elejre (itt vannak az alacsonyabb helyirtkek) hozzrakni. z,k: = < >,0 k< y z := z+(<0..k-1 darab..0> k := k+1 7.8. Valstsuk meg a vals egytthatj polinomok tpust az sszeads, kivons, szorzs mveletekkel! (x* yk))

304

8. fejezet feladatainak megoldsa

Megolds:

A = (p:P, q:P, r:P) r := pq A = (p:P, q:P, r:P) r := p q

:* P I:* *

(a) = a0+a1 x + +a a x a , I(a) = a a 0 a p, q, r-t rendre az a,b,c :*reprezentlja k [0..max( a , b )]: c[k ] a[k ] b[k ] ) k [0.. a * b ]:
n

c[k ]

a[l ] b[k
l k n l 0

l]

7.9. Valstsuk meg a diagonlis mtrixtpust (amelynek mtrixai csak a ftljukban tartalmazhatnak nulltl klnbz szmot)! Ilyenkor elegend csak a ftl elemeit reprezentlni egy sorozatban. Implementljuk a mtrix i-edik sornak j-edik elemt visszaad mveletet, valamint kt mtrix sszegt s szorzatt! Megolds: Diag(nn) a:Diag(nn), i, j:,e: e: = a[i,j] a, b, c: Diag(nn) c: = a+b a, b, c: Diag(nn) c := a*b :n Diag(nn) (x)[i,j] =
x[i ] ha i 0 ha i j j

305

10. Feladatok megoldsa

az a, b, c-t rendre az x ,y ,z : n reprezentlja, tovbb i:, j:, e: n i=j i j e e=0 = x[i]

i [1..n]: z[i] = x[i]+y[i] i [1..n]: z[i] = x[i]*y[i] 7.10. Valstsuk meg az alshromszg mtrixtpust (a mtrixok a ftljuk alatt csak nullt tartalmaznak)! Ilyenkor elegend csak a ftl s az alatti elemeket reprezentlni egy sorozatban. Implementljuk a mtrix i-edik sornak j-edik elemt visszaad mveletet, valamint kt mtrix sszegt s szorzatt! Megolds: AlsH(nn) a, b, c:AlsH(nn) c := a+b a, b, c: AlsH(nn) c := a*b a: AlsH(nn),i:, j:,e: e := a[i,j] :n(n+1)/2 AlsH(nn) (x)[i,j] = x[n (i 1) j ] ha i
0 ha i j j

az a, b, c-t rendre az x, y, z: n(n+1)/2 reprezentlja, tovbb i:, j:, e: i [1..n(n+1)/2]: z[i] = x[i]+y[i]
n(n+1)/2

i,j [1..n]: ha i j akkor


i

z[i(i 1) / 2

j]
k j

x[i(i 1) / 2 k ] y[k (k 1) / 2

j]

i j i<j

e e=0

x[i

(i1)/2+j]

306

8. fejezet feladatainak megoldsa

8. fejezet feladatainak megoldsa 8.1. Adott az egsz szmokat tartalmaz x vektor. Vlogassuk ki az y sorozatba a vektor pozitv elemeit! Specifikci: A = (x: , y:*) Ef = ( x=x ) Uf = ( x=x
y
n
i 1 x[i ] 0

x[i]

Sorozatot elllt feltteles sszegzs (kivlogats) az x tmb nevezetes felsoroljval (i:), ahol az sszeads mvelete az sszefzs. E H +,0 f(e) Algoritmus: y :=<> i = 1 .. n x[i]>0 SKIP y :=y x[i] Szmoljuk meg egy halmazbeli szavak kztt, hogy hny a betvel kezdd van! Specifikci: ~ ~ ~ ~ * ,<> <e> ha e>0 <> klnben

307

10. Feladatok megoldsa

A = ( h:set( *), db:) Ef = ( h=h ) Uf = ( db 1 )


sz h ' sz1 ' a '

Algoritmus: db := 0 h sz := mem(h) sz1=a db := db+1 h := h-{sz} Ez a szmlls programozsi ttele a h halmaz felsorolsval (E ~ *), ahol a szmlls felttele az aktulis elem (sz) els betjnek megfelel vizsglata ( (e) ~ sz1=a). A mem(h) (aktulis sz) rtknek ideiglenes trolsra a sz segdvltozt vezetjk be. Egy szekvencilis inputfjl egsz szmokat tartalmaz. Keressk meg az els nem-negatv elemt! Specifikci: A = (f:infile(), l: , elem:) Ef = ( f=f ) Uf = ( l, elem, f search(e 0) )
e f'

SKIP

8.2.

A feladatot szekvencilis inputfjl felsorolsra (E ~ ) ptett lineris keressre vezetjk vissza, ahol a fjlban egy nemnegatv elemet keresnk ( (e) ~ e0). A szekvencilis inputfjlok esetn a felsorolt egy st, e, f rtkhrmas reprezentlja, ahol st az f-re vonatkoz olvass sttusza, e a kiolvasott elemet tartalmaz segdadatok.

308

8. fejezet feladatainak megoldsa

Algoritmus: l:=hamis; l st,e,f:read

st=norm elem:= e l:= e 0 st,e,f:read

8.3.

Egy szekvencilis fjlban egy bank szmlatulajdonosait tartjuk nyilvn (azonost, sszeg) prok formjban. Adjuk meg annak az azonostjt, akinek nincs tartozsa, de a legkisebb a szmlaegyenlege! Specifikci: A = (x:infile(gyfl), l: , a: *) gyfl=rec(az: *, egyl:) Ef = ( x=x ) Uf = ( l,min,elem = min e.egyl a=elem.az )
e x' e.egyl 0

Feltteles minimum keress az x szekvencilis inputfjl nevezetes felsorolsval (st,e,x:read). E H max (e) f(e) ~ ~ ~ ~ ~ gyfl min e.egyl0 e.egyl

309

10. Feladatok megoldsa

Algoritmus: l := hamis st,e,x:read st = norm e.egyl<0 SKIP l e.egyl 0 l e.egyl 0

min >e.egyl min, a:= e.egyl, e.az SKIP

l, min, a := igaz, e.egyl, e.az

st,e,x:read 8.4. Egy szekvencilis fjlban minden tutalsi bettszmla tulajdonosrl nyilvntartjuk a nevt, cmt, azonostjt, s szmlaegyenlegt (negatv, ha tartozik; pozitv, ha kvetel). Ksztsnk kt listt: rjuk ki egy output fjlba a htralkkal rendelkezk, egy msikba a tlfizetssel rendelkezk nevt! Specifikci: A = (x:infile(gyfl), y:outfile( ), z:outfile( )) gyfl = rec(nv: *, cm: *, az: *, egyl:) Ef = ( x=x ) Uf = ( y e.nv z e.nv )
e x' e.egyl 0 e x' e.egyl 0

Kt szekvencilis outputfjlt elllt feltteles sszegzs (sztvlogats) amelyeket sszevonunk , az x szekvencilis inputfjl nevezetes felsoroljval (st,e,x:read). E H ~ ~ gyfl
*

E H +,0 f(e)

~ ~ ~ ~

gyfl
*

+,0 ~ f(e) ~

,<> e.egyl ha e.egyl<0

,<> e.egyl ha e.egyl>0

Algoritmus:

310

8. fejezet feladatainak megoldsa

st,e,x:read

y := <> st = norm e.egyl<0

z := <>

y:write(e.nv) e.egyl>0 z: write(e.nv) st,e,x:read 8.5.

SKIP SKIP

Egy szekvencilis inputfjlban egyes kaktuszfajtkrl ismernk nhny adatot: nv, shaza, virgszn, mret. Vlogassuk ki egy szekvencilis outputfjlba a mexiki, egy msikba a piros virg, egy harmadikba a mexiki s piros virg kaktuszokat! Specifikci: A = (x:infile(Kaktusz), y:outfile(Kaktusz), z:outfile(Kaktusz), u:outfile(Kaktusz)) Kaktusz = rec(nv: *, virg: *, s: *) Ef = ( x=x ) Uf = ( y e
e x' e.virg " piros"

e x' e.s " Mexik "

e x' e.virg " piros" e.s " Mexik"

Hrom szekvencilis outputfjlt elllt feltteles sszegzs (kivlogatsok) amelyeket sszevonunk az x szekvencilis inputfjl nevezetes felsoroljval (st,e,x:read).

311

10. Feladatok megoldsa

E H +,0 f(e)

~ ~ ~ ~ ha

Kaktusz
*

Kaktusz
*

Kaktusz
*

,<> <e.nv> e.virg= piros

,<> <e.nv> e.s= Mexik

,<> <e.nv> e.virg= piros e.s= Mexik

Algoritmus: st,e,x:read y:=<> z:=<> u:=<> st = norm e.virg=piros y:write(e) e.s=Mexik z:write(e) e.virg=piros u:write(e) st,e,x:read 8.6. Adott egy egsz szmokat tartalmaz szekvencilis inputfjl. Ha a fjl tartalmaz pozitv elemet, akkor keressk meg a fjl legnagyobb, klnben a legkisebb elemt! Specifikci: A = (x:infile(), m:) Ef = ( x=x x >0) Uf = ( max = max e min = min e
e x' e x'

SKIP SKIP e.s=Mexik SKIP

(max>0 m=max) (max 0 m=min) ) Egy ciklusba sszevont maximum- s minimumkeress (E s H mindkt esetben a , az f pedig identits), az x szekvencilis inputfjl nevezetes felsoroljval (st,e,x:read).

312

8. fejezet feladatainak megoldsa

Algoritmus: st,e,x:read max, min := e, e st,e,x:read st = norm max <e max:= e min e max SKIP st,e,x:read max>0 m := max 8.7. m := min min>e min:= e

Egy szekvencilis inputfjl egy vllalat dolgozinak adatait tartalmazza: nv, munka tpus (fizikai, adminisztratv, vezet), havi br, csald nagysga, tlraszm. Vlasszuk ki azoknak a fizikai dolgozknak a nevt, akiknl a tlraszm meghaladja a 20-at, s csaldtagok szma nagyobb 4-nl; adjuk meg ezen kvl a fizikai, adminisztratv, vezet beoszts dolgozk tlagos havi brt! Specifikci:

313

10. Feladatok megoldsa

A = (x:infile(Dolgoz), y:outfile( *), f,a,b:) Dolgoz = rec(nv: *, tipus:{fiz, adm, vez}, br:, csald:, tl:) Ef = ( x=x ) f ( e.br ) ( / 1 ) Uf = ( y e
e x'
e.tipus fiz e.t l 20 e.csald 4

e x' e.tipus fiz

e x' e.tipus fiz

a ( v (

e.br ) ( / e.br ) ( /

e x' e.tipus adm e x' e.tipus vez

e x' e.tipus adm

1 ) )

e x' e.tipus vez

Az eredmny kiszmolshoz ngy feltteles sszegzs (ebbl egy kivlogats) s hrom szmlls kell ugyanazon az x szekvencilis inputfjl felsorolsval (st,e,x:read). Algoritmus: st,e,x:read y,f,fdb,a,adb,v,vdb := <>,0,0,0,0,0,0 st = norm e.tpus=fiz e.tl>20 e.tpus=fiz f, fdb := f+e.br, fdb+1 e.tpus=adm a, adb := a+e.br, adb+1 e.tpus=vez v, vdb := v+e.br, vdb+1 st,e,x:read f , a, v := f/fdb, a/adb, v/vdb SKIP SKIP SKIP e.csald>4 SKIP

y:write(e)

314

8. fejezet feladatainak megoldsa

8.8.

Adott kt vektorban egy angol-latin sztr: az egyik vektor iedik eleme tartalmazza a msik vektor i-edik elemnek jelentst. Vlogassuk ki egy vektorba azokat az angol szavakat, amelyek szalakja megegyezik a latin megfeleljvel. Specifikci: A = (x: , y: , z: *, k:) Ef = ( x = x' y = y') Uf = ( x = x' y = y'
n n

z[1..k ]

n
i 1 x[ i ] y[ i ]

x[i ] )

Ez egy tmbt elllt feltteles sszegzs az 1..n intervallum felett. Algoritmus: k:=0 i = 1 .. n x[i] = y[i] z,k:=z x[i], k+1 8.9. SKIP

Alaktsunk t egy magyar nyelv szveget tvirati stlusra! Specifikci:

315

10. Feladatok megoldsa

A = (x:infile( ), y:outfile( )) Ef = ( x=x) Uf = ( y tvirat(ch ) )


ch x'

tvirat:

" aa" " ee" " i" " oe" " ue" tvirat (ch) " o" " Aa" " Ee" " I"

ha ha ha ha ha ha ha ha ha

ch " " ch " " ch " " ch " " vagy ch " " ch " " vagy ch " " ch " " ch " " ch " " ch " "

ch " " vagy ch " " " Oe" ha "Ue" ha ch " " vagy ch " " " O" ha ch " " ch klnben

Algoritmus: st,ch,x:read y:= <> st = norm y: write(tvirat(ch)) st,ch,x:read

316

9. fejezet feladatainak megoldsa

9. fejezet feladatainak megoldsa 9.1. Egy kmreplgp vgig replt az ellensg hadllsai felett, s rendszeres idkznknt megmrte a felszn tengerszint feletti magassgt. A mrt adatokat egy szekvencilis inputfjlban troljuk. Tudjuk, hogy az ellensg a harcszati raktit a lehet legmagasabb horpadsban szokta elhelyezni, azaz olyan helyen, amely eltt s mgtt magasabb a tengerszint feletti magassg (loklis minimum). Milyen magasan tallhatk az ellensg rakti? Specifikci: A = (f:infile(), max:) Ef = ( f = f' ) A feladat feltteles maximum keresssel trtn megoldshoz (a felttel, hogy van-e egyltaln a mrt felsznen mlyeds) a mrt rtkeket gy kell felsorolni, hogy egyszerre hrom egyms utn rtket lssunk: a megelzt, az aktulisat s a rkvetkezt. A = (t:enor(rec(e:, a:, k:)) , max:) Ef = ( t=t ) max elem.a ) Uf = ( max
elem t' elem.e elem.a elem.k

Algoritmus: l:= hamis; t.First()

t.End() e, a, k =t.Current() (e>a<k) SKIP l e>a<k max<a max := a SKIP l e>a<k

l, max := igaz, a

t.Next() Nzzk ezek utn a felsorolt! Ennek minden lpsben hrom rtket, az elz, az aktulis s a kvetkez alkotta rtkhrmast

317

10. Feladatok megoldsa

kell mutatnia (Current()). Az els hrmas ellltshoz (First()) hrom olvassra van szksg az f szekvencilis inputfjlbl. A kvetkez hrmas ellltshoz (Next()) felhasznlhatjuk az jelenlegi hrmas aktulis s kvetkez rtkt, amelyekbl a kvetkez hrmas elz s aktulis rtkei lesznek, s egy olvasssal megszerezhetjk a kvetkez rtket. A felsorols akkor r vget (End()), ha mr nem sikerl kvetkez rtket olvasni az f szekvencilis inputfjlbl. A felsorolt teht hrom vals szm (e, a, k), valamint az utols olvass sttusza (sf) reprezentlja. A mveletek pedig: t.First() sf,e,f:read sf,a,f:read sf,k,f:read t.Next() e:=a a:=k sf,k,f:read l:= t.End() l:= sf = abnorm (e, a, k ):=t.Current() SKIP

9.2. Szmoljuk meg egy karakterekbl ll szekvencilis inputfjlban a szavakat gy, hogy a 12 betnl hosszabb szavakat dupln vegyk figyelembe! (Egy szt szkzk vagy a fjl vge hatrol.) Specifikci: A = (f:infile( ), s:) Ef = ( f = f' ) A feladat megoldhat egy olyan sszegzssel, amelyhez szvegbeli szavak hosszait kell felsorolnunk. Ha egy sz hosszabb, mint 12, akkor az sszegzs eredmnyhez kettt, klnben egyet kell hozzadni. A = (t:enor(), s:) Ef = ( t=t ) f (e) ) Uf = ( s
e t'

f: f(e)=

1 ha 2 ha

e e

12 12

318

9. fejezet feladatainak megoldsa

Algoritmus: s := 0 t.First() t.End() t.Current()>12 s := s+2 s := s+1 t.First() A felsorolnak minden lpsben a soron kvetkez sz hosszt kell mutatnia. Ha feltesszk, hogy minden lps eltt a soron kvetkez sz elejn llunk, akkor egy olyan sszegzssel hatrozhatjuk meg az aktulis sz hosszt, amely annak minden betjre egyet ad hozz az sszegzs eredmnyhez. Ez egy felttel fennllsig tart sszegzs, hiszen a vgt a fjl- vagy a sz vge jelzi. A sz vgnek elrse utn egy kivlasztssal megkeressk a kvetkez sz elejt. ANext = (f infile( ), df: , sf:Sttusz, van_sz: , hossz:) EfNext = ( f = f1 df = df1 sf = sf1 (sf=norm df ) ) UfNext = ( van_sz=(sf1=norm) van_sz ( hossz , sf , df , f
sf , df , f select ( sf
2 2 2 df ' '

1
df ( df 1 , f 1 )

df ( sf 2 , df 2 , f 2 )

abnorm

df

' ') ) )

A First() mvelet annyival tbb, hogy elszr biztostania kell a tpus-invarinst. Ehhez a vezet szkzk tlpsre van szksg, ami a mr ltott kivlaszts lesz, s csak ezutn hajtja vgre a Next() mveletnl lertakat. AFirst = (f:infile( ), df: , sf:Sttusz, van_sz: , hossz:) EfFirst = ( f = f ) UfFirst = ( sf 1 , df 1 , f 1
select (sf
df f'

abnorm df

' ')

van_sz=(sf1=norm)

319

10. Feladatok megoldsa

van_sz ( hossz , sf 2 , df 2 , f 2
sf , df , f select ( sf

df ' '

1
df ( df 1 , f 1 )

df ( sf 2 , df 2 , f 2 )

abnorm

df

' ') ) )

t.First() sf, df, f : read sf = norm df=

t.Next() van_sz:= sf=norm van_sz hossz:=0 sf = norm df SKIP

sf, df, f : read van_sz:= sf=norm t.Next()

hossz:=hossz+ 1 sf, df, f: read sf = norm df=

sf, df, f: read A felsorols akkor r vget, ha a Next() mvelet nem tall jabb szt. Ezt az informcit a van_hossz logikai vltoz rzi. Ennek rtkt krdezi le a t.End(). A t.Current() a hossz vltoz rtkt adja vissza. Ezek szerint a t felsorolt az sf, df, f, van_sz, hossz egyttesen reprezentljk. 9.3. Alaktsunk t egy bitsorozatot gy, hogy az els bitjt megtartjuk, utna pedig csak darabszmokat runk annak megfelelen, hogy hny azonos bit kveti kzvetlenl egymst! Pldul a 00011111100100011111 sorozat tmrtve a 0362135 szmsorozat lesz. Specifikci: A = (f:Bit*, g:*) Ef = ( f=f' ) Kpzeljk el azt a felsorolt, amelyik mr ez eredmnysorozatban kvnt rtkeket sorolja fel. Ekkor a megolds egy msols (specilis sszegzs) lesz

320

9. fejezet feladatainak megoldsa

A = (t:enor(), g:*) Ef = ( x=x' ) Uf = ( g=x' ) Algoritmus: g:= <> t.First() t.End() g:write(t.Current()) t.Next() A felsorolt az f sorozat, a sorozat elemeinek sorszmain vgig vezetett i vltoz, az azonos bitekbl ll aktulis szakasz hossza (hossz) s egyik bitje (bit) reprezentlja. A t.End() az i |f| kifejezs lesz, a t.Current() a hossz vltoz rtkt adja vissza, ami a legeslegels esetben az els bit rtke. AFirst = (f:Bit*, e:, i:) EfFirst = ( f = f ) UfFirst = ( f = f (|f| 0 i=1 hossz=f1) ) ANext = (f:Bit*, e:, i:) EfNext = ( f = f i = i ) UfNwxt = ( f = f
hossz , i
fi fi ' i f i i'

1 ))

t.Fist() |f| 0 i, hossz:= 1, 0 SKIP

t.Next() bit, hossz:= fi, 0 i |f| bit = fi i:=i+1

hossz:=hossz+1

9.4. Egy szveges llomnyban a bekezdseket res sorok vlasztjk el egymstl. A sorokat sorvge jel zrja le. Az utols sort zrhatja fjlvge jel is. A sorokban a szavakat a sorvge vagy

321

10. Feladatok megoldsa

elvlasztjelek hatroljk. Adjuk meg azon bekezdseknek sorszmait, amelyek tartalmazzk az elre megadott n darab sz mindegyikt! (A nem-res sorokban mindig van sz. Bekezdsen a szvegnek azt a szakaszt rtjk, amely tartalmaz legalbb egy szt, s vagy a fjl eleje illetve vge, vagy legalbb kt sorvge jel hatrolja.) Specifikci: A = (f:infile( ), h:( *)n, g:outfile()) Ef = ( f=f' h=h' ) Kpzeljk, hogy minden bekezdshez hozzrendeljk annak sorszmt s egy logikai rtket, amelyik akkor igaz, ha a bekezdsben szerepelnek a megadott szavak. Ha egy alkalmas felsorolval ezeket a szm-logikai rtk prokat soroltatjuk fel, akkor a feladat visszavezethet egy sszegzsre (kivlogatsra). A = (x:enor(Pr), h:( *) , g:outfile()) Pr = rec(ssz: , van: ) Ef = ( x=x' ) e.ssz ) Uf = ( g
e x' e.van
n

Algoritmus: x.First(); g:= <> x.End() x.Current().van g : write(x.Current().ssz) x.Next() A x.First() s x.Next() mveletek egyarnt egy bekezdsnyit olvasnak a szvegbl. Ehhez egy olyan absztrakt felsorolt (u) is hasznlunk, amely szakaszokat (szavakat, csupa sorvge-jelbl ll rszeket, s egyb jelekbl ll rszeket) olvas a szvegbl. Amg bekezds vghez (legalbb kt sorvge-jelbl ll szakaszhoz) nem rnk, addig a szavakat egyenknt beledobljuk egy klnleges trolba, amely szmolja, hogy a kezdetben megadott szavak kzl hny kerlt mr bele. Ha a trol SKIP

322

9. fejezet feladatainak megoldsa

szmllja a bekezds feldolgozsa vgn ppen n, akkor a bekezds megfelel a feladatban lert felttelnek. Definiljuk elszr a trol tpust! Ennek ltrehozshoz megadjuk az n darab vizsgland szt. Ezek kzl megjelltek lesznek azok, amelyekkel mr tallkoztunk egy bekezds szavai kztt. Nyilvntartunk egy szmllt (count) is, amely azt mutatja, hogy a megadott szavak kzl eddig hnyat jelltnk meg. Hrom mveletet vezetnk be. Az Init() lenullzza a szmllt s az sszes elre megadott szt jelletlennek lltja be. A Mark(sz) jabb szt helyez el a trolban. Ha a sz szerepel az elre megadott szavak kztt (ezt egy lineris keress dnti el) s mg jelletlen, akkor megjelljk s a szmllt eggyel nveljk. A Full() igazat ad, ha az elre megadott szavak mindegyike jellt, azaz count=n. Trol Init() Mark(sz) l:=Full() v: ( (
* *

)n, count:, sz:

, l:

)n

i [1..n]: v[i].jel := hamis count := 0


n

l , i : search (v[i ].sz


i 1

sz )

v[i].jel SKIP

v[i].jel := true count:= count+1 l := count=n

Az x.First() s x.Next() mveletek kztt csak annyi klnbsg van, hogy a bekezds legels szakaszt az u.First() mvelettel

323

10. Feladatok megoldsa

olvassuk, nem az u.Next()-tel, s a legels bekezds sorszmt 1re kell lltani, nem pedig az elz sorszm eggyel megnvelt rtkre. A trolba mindenfle szakaszt bedoblhatunk (ezt programoztuk le), de hatkonyabb lenne, ha csak a szavakkal tennnk ezt. A BekVg() ellenrzi, hogy a vizsglt szakasz (u.Current()) legalbb kt sorvge-jelbl ll-e. Az x.Current() adja vissza a p-t, az x.End() pedig a vge-t. A mveleteket formlisan nem specifikljuk. x.First() u.First() vge:= u.End() vge p.ssz := 1; a.Init() u.End() BekVg(u.Current()) a .Mark(u.Current()) u.Next() p.van:= a.Full() S K I P x.Next() u.Next() vge:= u.End() vge p.ssz := p.ssz +1; a.Init() u.End() BekVg(u.Current()) a .Mark(u.Current()) u.Next() p.van:= a.Full() S K I P

Egy szakasz kiolvasshoz az eredeti szveget karakterenknt kell tudni bejrni. Ehhez a szveget szekvencilis inputfjlknt bejr nevezetes felsorolst, az sf,df,f:read mveletet hasznljuk. Az u.Next() mveletnl felttelezzk, hogy a fjl elre olvasott, az u.First() mveletnl ezt az elre olvasst el kell vgezni. A mveleteket formlisan nem specifikljuk. Az u.Next() mvelet egy felttel fennllsig tart sszegzs, amely az aktulis szakasz jeleit fzi ssze. Ehhez hasznljuk a Jel: {bet, kz, sorvg} fggvnyt, amely egy karakterrl eldnti, hogy az milyen fajtj. Az aktulis szakasz addig tart, amg azonos jel karaktereket olvasunk be egyms utn. Az u.Current() az aktulis szakasz-t adja vissza, az u.End() pedig

324

9. fejezet feladatainak megoldsa

akkor igaz, ha a szekvencilis inputfjl bejrsa vget rt, azaz van_szakasz. x.First() sf, df, f : read u.Next() x.Next() van_szakasz:= sf=norm van_szakasz szakasz:= jel:=Jel(df) sf = norm Jel(df)=jel S K I P

szakasz:=szak asz+df sf, df, f: read

9.5. Egy szveges llomny legfeljebb 80 karakterbl ll sorokat tartalmaz. Egy sor utols karaktere mindig a specilis \eol karakter. Msoljuk t a szveget egy olyan szveges llomnyba, ahol legfeljebb 60 karakterbl ll sorok vannak; a sor vgn a \eol karakter ll; s gyelnk arra, hogy az eredetileg egy szt alkot karakterek tovbbra is azonos sorban maradjanak, azaz sorvge jel ne trjn kett egy szt. Az eredeti llomnyban a szavakat egy vagy tbb szhatrol jel vlasztja el (Az \eol is ezek kz tartozik), amelyek kzl elg egyet megtartani. A szhatrol jelek egy karaktereket tartalmaz szhatr nev halmazban tallhatk. Feltehetjk, hogy a szavak 60 karakternl rvidebbek. Specifikci: A = (f:infile( ), g:outfile( )) Ef = ( f=f' ) A feladat megoldshoz a szveg szavainak felsorolsra lesz szksgnk, hiszen a szavakat kell ms trdelssel az outputfjlba kirni. Ennek rdekben az eredmnyt egy specilis tpus objektumnak kpzeljk el, amelyre bevezetjk a Write60() mveletet. Ez sort emel, mieltt egy olyan szt rna ki, amelyiknek hossza (az elrt szkzzel egytt) nem fr mr ki az

325

10. Feladatok megoldsa

aktulis sorba. Az objektumot a szekvencilis outputfjl mellett az a szm reprezentlja, amely megmutatja, hogy a legutols sorban hny karakternyi szabad hely van mg. (res sor esetn ez ppen 60.) outfile60 g: outfile( ), sz: outfile( ) g := <> free:=60 hossz(sz)+1>free g:write(sorvg) free:=60 g:write( ) free:=free-1 Open() Write60(sz)
*

, free:,

g:write(sz) free:=free- hossz(sz) Ezek utn jraspecifikljuk a feladatot. A = (x:enor(Sz), y:outfile60( )) Ef = ( x=x' ) Uf = ( u ) e
e x'

Algoritmus: x.First(); y.Open() x.End() x.Current().van y:write60(x.Current()) x.Next() A felsorolnak minden lpsben a soron kvetkez szt kell megadnia. Ezt a felsorolt mr nem elszr ksztjk el (lsd 9.2 feladat). SKIP

326

9. fejezet feladatainak megoldsa

9.6. Adott egy keresztneveket s egy virgneveket tartalmaz szekvencilis fjl, mindkett abc szerint szigoran nvekeden rendezett. Hatrozzuk meg azokat a keresztneveket, amelyek nem virgnevek, illetve azokat a neveket, amelyek keresztnevek is, s virgnevek is! Specifikci: A = (c:infile(E), f:infile(E), ko:outfile(E), cf:outfile(E)) Ef = ( c = c j = j c f ) g (e) cf h ( e) ) Uf = ( ko
e {c '} { f '} e {c '} { f '}

e g( e )

ha e { c' } e { f ' } ha e { c' } e { f ' } ha e { c' } e { f ' } ha e { c' } e { f ' } ha e { c' } e { f ' } ha e { c' } e { f ' }

h( e ) e

Ez egy sszefuttatsos (lsd szekvencilis inputfjlok felett. Algoritmus:

9.5.

alfejezet)

sszegzs

sc,dc,c:read ; sf,df,f:read ; ko := <>; cf := <> sc=norm sf=abnorm (sc=norm dc<df) ko:write(dc) sc,dc,c:read sf=norm sc=norm sf=norm dc=df cf:write(dc) sc,dc,c:read sf,df,f:read

sc=abnorm (sf=norm dc>df) SKIP sf,df,f:read

9.7. Egy x szekvencilis inputfjl (megengedett mvelet: read) egy knyvtr nyilvntartst tartalmazza. Egy knyvrl ismerjk az azonostjt, a szerzjt, a cmt, a kiadjt, a kiads vt, az aktulis pldnyszmt, az ISBN szmt. A knyvek azonost szerint szigoran nvekven rendezettek. Egy y szekvencilis

327

10. Feladatok megoldsa

inputfjl (megengedett mvelet: read) az aznapi knyvtri forgalmat mutatja: melyik knyvbl hnyat vittek el, illetve hoztak vissza. Minden bejegyzs egy azonostt s egy eljeles egszszmot - ha elvittk: negatv, ha visszahoztk: pozitv tartalmaz. A bejegyzsek azonost szerint szigoran nvekven rendezettek. Aktualizljuk a knyvtri nyilvntartst! A feldolgozs sorn keletkez hibaeseteket egy h sorozatba rjuk bele! Specifikci: Vezessnk be nhny jellst. Ha x olyan elemeknek a sorozata, amelyek olyan rekordok, hogy rendelkeznek pldul egy azon nev komponenssel (ilyen ebben a feladatban a trzs- s a mdost fjl), akkor x azon jellje azt, hogy x-ben az elemek azonost szerint szigoran nvekeden rendezettek. Amennyiben x-re ez a felttel fenn ll, akkor az azon(x) jellje az x-ben tallhat azonostknak (x sszes elemnek azonostinak) a halmazt, s ilyenkor ha a azon(x), akkor a(x) jellje az x-nek az a azonostj elemt. A = (t:infile(Knyv), m:infile(Vlt), u:outfile(Knyv), h:outfile( *)) Knyv = rec(azon: *, szerz: *, cm: *, kiad: v:, pld:, isbn: *) Vlt = rec(azon: *, forg:) Ef = ( t = t' m = m' t azon m azon ) f 1 (a) Uf = ( u
a azon(t ') azon( m')

a azon(t ') azon( m')

f 2 (a) )

a(t ' ), f (a) , " hiba" g (a)

ha ha ha

a a a

azon (t ' ) azon (t ' ) azon (t ' )

a a a

azon (m' ) azon (m' ) azon (m' )

g (a)

a(t ' ) , " hiba" a(t ' ) pld pld a ( m'). forg ,

ha a(t ' ). pld a(m' ). forg 0 ha a(t ' ). pld a(m' ). forg 0

328

9. fejezet feladatainak megoldsa

Az a(t)pld pld+a(m).forg jells azt a Knyv tpus elemet jelzi, amely abban klnbzik az a(t) rekordtl, hogy annak pld mezje az a(m).forg mezjnek rtkvel mdosult. Az aktualizlt nyilvntartst is, a hibafjlt is egy szekvencilis inputfjlok feletti azonost szerinti sszefuttatsos sszegzssel llthatjuk el. A hibazenet pontos szvegt a specifikci nem tartalmazza. Algoritmus: u,h : =<>,<> st,dt,t:read st=norm sm=abnorm st=norm dt.azon<dm.azon sm,dm,m:read sm=norm st=norm sm=norm dt.azon=dm.azon a := dt.pld+dm.forg a u:hiext(dt) st,dt,t:read h:hiext(hiba) sm,dm,m:read 0 HIBA

st=abnorm sm=norm dt.azon>dm.azon

dt.pld := a

u:hiext(dt) st,dt,t:read sm,dm,m:read

9.8. Egy vllalat dolgozinak a fizetsemelst kell vgrehajtani gy, hogy az azonos beoszts dolgozk fizetst ugyanakkora szzalkkal emeljk. A trzsfjl dolgozk sorozata, ahol egy dolgozt hrom adat helyettest: a beosztskd, az egyni azonost, s a br. A trzsfjl beosztskd szerint nvekven, azon bell azonost szerint szigoran monoton nvekven rendezett. A mdost fjl beosztskd-szzalk prok sorozata, s beosztskd szerint szigoran monoton nvekven rendezett. (Az egyszersg kedvrt feltehetjk, hogy csak a trzsfjlban elfordul beosztsokra vonatkozik emels a mdost fjlban, de nem felttlenl mindegyikre.) Adjuk meg egy j trzsfjlban a dolgozk emelt breit.

329

10. Feladatok megoldsa

Specifikci: Legyen T=infile(DT) a trzsfjl tpusa, ahol DT=rec(beo:, az: *, br:). Az U=infile(DT) j trzsfjl a T-vel megegyez szerkezet szekvencilis outputfjl. Legyen a mdost fjl tpusa M=infile(DM), ahol DM=rec(beo:, emel:). Most is hasznljuk az elz feladat megoldsnl bevezetett jellseket. A= (t:T, m:M, u:U) Ef = ( t = t' m = m' beo(t) beo(m) t (beo,az) m beo ) Kpzeljk el azt a felsorolt, amely alapveten a t fjl elemeit, a dolgozkat jrja be, de gy, hogy minden dolgoznl vgrehajtja a rvonatkoz fizetsemelst is. A= (x:enor(DT), u:U) Ef= ( x = x' ) Uf= ( u e )
e x'

Algoritmus: Ez a feladat a legegyszerbb sszegzsre, a msolsra vezethet vissza. A First() mvelet beolvassa az els dolgozt s az els fizetsemelst. A Next() mvelet beolvassa a kvetkez dolgozt, s amennyiben a kvetkez dolgoz beosztskdja nagyobb lenne, mint az aktulis fizetsemels beosztskdja, akkor a kvetkez fizetsemelst is. A beo(t) beo(m) elfelttel garantlja, hogy mindkt mvelet vgrehajtsa utn az aktulis dolgoz beosztskdja nem lehet nagyobb a fizetsemels beosztskdjnl. A Current() mvelet ha a fizetsemels beosztskdja megegyezik a dolgozval, akkor azt a megemelt fizetssel, egybknt az eredeti fizetssel adja vissza a dolgozt. Az End() mvelet akkor lesz igaz, ha a dolgozk felsorolsa vget r.

330

9. fejezet feladatainak megoldsa

Algoritmus: u : =<> st,dt,t:read; sm,dm,m:read st=norm sm=norm dt.beo=dm.beo SKIP dt.br:= dt.br+ dt.br* dm.emel u:write(dt) st,dt,t:read st=norm sm=norm dt.beo>dm.beo SKIP

sm,dm,m:read

9.9. Egy egyetemi kurzusra jr hallgatknak hrom gptermi zrthelyit kell rnia a flv sorn. Kt flvkzit, amelyikbl az egyiket .Net/C#, a msikat Qt/C++ platformon. Azt, hogy a harmadik zrthelyin ki milyen platformon dolgozik, az dnti el, hogy a flvkzi zrthelyiken hogyan szerepelt. Aki mindkt flvkzi zrthelyit teljestette, az szabadon vlaszthat platformot. Aki egyiket sem, az nem vehet rszt a flvvgi zrthelyin, szmra a flv rvnytelen. Aki csak az egyik platformon rta meg a flvkzit, annak a flvvgit a msi platformon kell teljestenie. Minden gyakorlatvezet elkszti azt a kimutatst (szekvencilis fjl), amely tartalmazza a sajt csoportjba jr hallgatk flvkzi teljestmnyt. Ezek a fjlok hallgati azonost szerint rendezettek. A fjlok egy eleme egy hallgati azonostbl s a teljestmny jelbl (X mindkt platformon teljestett, Q csak Qt platformon, N csak .net platformon, 0 egyik platformon sem) ll. Rendelkezsnkre llnak tovbb a flvvgi zrthelyire bejelentkezett hallgatk azonosti rendezett formban egy szekvencilis fjlban. lltsuk el azt a szekvencilis outputfjlt, amelyik a zrthelyire bejelentkezett hallgatk kzl csak azokat tartalmazza, akik legalbb az egyik flvkzi zrthelyit teljestettk. Az eredmny fjlban minden ilyen hallgat azonostja mellett tntessk fel, hogy milyen

331

10. Feladatok megoldsa

platformon kell a hallgatnak dolgoznia: .Net-en (N), Qt-vel (Q) vagy szabadon vlaszthat (X). Specifikci: A= (g:infile(Hallg)n, r:infile( *), v:infile(Hallg)) Hallg=rec(eha: *, jel: ). Ef = ( g = g' r = r' i [1..n]:g[i] eha r ) A feladat megoldshoz egyrszt szksgnk van egy olyan felsorolra (enor(Hallg)), amely a csoportok sszes hallgatjt azonost szerint rendezett mdon tudja bejrni, azaz sszefuttatni. Feltehetjk, hogy ugyanaz az azonost nem szerepelhet kt klnbz csoportban. A flvvgi zrthelyikre adott jelentkezseket trol fjlt annak nevezetes felsoroljval jrjuk be. A = (x:enor(Hallg), y:enor( *), v:outfile(Hallg)) Ef = ( x = x' y = y' t eha y ) f (a ) ) Uf = ( v
a eha( x ') ( y ')

ha a f(a) ha a g( a ) ha a
a( x' ) g( a ) a( x' )
eha( x' ). jel eha( x' ). jel

eha( x' ) a { y' } eha( x' ) a { y' } eha( x' ) a { y' }


ha a( x' ). jel ' X '
' Q' ' N'

ha a( x' ). jel ' N' ha a( x' ). jel ' Q' ha a( x' ). jel ' 0'

a( x' )

Algoritmus: A feladatot egy sszefuttatsos sszegzs oldja meg. Az r fjl felsoroljt az sr,dr,r:read mvelettel valstjuk meg. Az sszefuttats hallgati azonost szerint trtnik, ezrt a x.Current().eha rtket kell a dr rtkkel sszevetni.

332

9. fejezet feladatainak megoldsa

x.First(); sr,dr,r:read; v := <> x.End() sr=norm x.End() r.End() x.Current().eha=dr

r.End() x.End() ( x.End() ( r.End() x.Current().eha x.Current().eha <dr) >dr) SKIP x.Next(); SKIP sr,dr,r:read

v:write(g(t.Current())) x.Next(); sr,dr,r:read

x.First() i=1..n sg[i],dg[i],g[i]:read l, ind,


n i 1 sg [i ] norm

x.Next() sg[ind],dg[ind],g[ind]:read l, ind,


n i 1 sg [i ] norm

min
dg[i].eha

:=

min
dg[i].eha

:=

min

min

Az x.First() mvelet a csoportokba beosztott legkisebb azonostj hallgatt keresi meg. Ehhez minden csoportnak az els (legkisebb azonostj) hallgatjt kell beolvasni (ha van ilyen), s ezek kztt megkeresni a legkisebbet. Ez egy feltteles minimumkeress, ahol a felttel az, hogy legyen az adott csoportban mg feldolgozatlan hallgat. Az egyes csoportok bejrshoz a szekvencilis inputfjl nevezetes felsorolit hasznljuk. Az x.Next() mvelet abban klnbzik az x.First()-tl, hogy a feltteles minimumkeress eltt csak abbl a csoportbl kell jabb hallgatt olvasni, ahonnan az utoljra feldolgozott azonost szrmazik. Az x.Current() mvelet a legkisebb azonostj hallgatt adja vissza (dg[ind]), de belltja a hallgat jelt is: ha N volt, akkor Q-ra s fordtva, ha X vagy 0, akkor azt helyben hagyja. Az x.End() pedig akkor

333

10. Feladatok megoldsa

lesz igaz, ha a feltteles minimumkeress sikertelen (l=hamis), azaz mr minden csoport sszes hallgatjt megvizsgltuk. 9.10. Az x szekvencilis inputfjlban egsz szmok vannak. Van-e benne pozitv illetve negatv szm, s ha mindkett van, akkor melyik fordul el elbb? Specifikci: A = (x:infile(), poz: , neg: , els:) Ef = ( x=x ) Uf = ( (poz, neg, els) = f( x ) ) A poz akkor lesz igaz, ha tartalmaz a fjl pozitv szmot, a neg akkor lesz igaz, ha tartalmaz a fjl negatv szmot, s ha mindkett igaz, akkor az els-bl kiolvashat a vlasz: ha els>0, akkor a pozitv szm jelent meg elbb, ha els<0, akkor a negatv. A vlasz hrom komponenst egy rekurzv fggvny adja meg. f:[0.. x ] f(0) = (hamis, hamis, 0) i [1.. x ]: (igaz , f 2 (i 1), x'i ) ha f 1 (i 1) f 2 (i 1) x 'i 0 (igaz , f 2 (i 1), f 3 (i 1)) ha f 1 (i 1) f 2 (i 1) x 'i 0 f(i) = ( f 1 (i 1), igaz , x'i ) ha f 1 (i 1) f 2 (i 1) x 'i 0 ( f 2 (i 1), igaz , f 3 (i 1)) ha f 1 (i 1) f 2 (i 1) x 'i 0 f (i 1) klnben Ez a fggvny nem fgg kzvetlenl az i-tl, csak az xi-tl, ezrt a kiszmtst az x szekvencilis inputfjl elemeinek felsorolsra pthetjk. Az i:=1 s az i:=i+1 rtkadst az st,e,x:read utastssal (First() s Next()), az i x felttelt az st=norm felttellel ( End()), az xi helyett az e-t hasznlhatjuk (Current()). St az End() mvelete szigorthat az st=abnorm (poz neg) felttelre, hiszen ha valahol a rekurzv fggvny els kt komponense igazra vlt, a fggvny tovbbiakban felvett rtkei mr nem vltoznak.

334

9. fejezet feladatainak megoldsa

Algoritmus: poz, neg, els:= hamis, hamis, 0 st,e,x:read st=norm poz poz neg e>0 neg e>0 poz, els:= igaz, e poz:= igaz ( poz neg) else

poz poz neg neg e<0 e<0 neg, els:= igaz, e st,e,x:read

neg:= igaz SKIP

335

IRODALOM JEGYZK
1. Dijkstra E.W., A Discipline of Programming,PrenticeHall, Englewood Cliffs, 1973. 2. Dijkstra E.W. and C.S. Scholten, Predicate Calculus and Program Semantics, Springer-Verlag, 1989. 3. Fthi kos: Bevezets a programozshoz ELTE Etvs Kiad. 2005. 4. Fowler M., Analysis Patterns: Reusable Object Models, Addison-Wesley, 1997. 5. Gries D., The Science of Programming, Springer Verlag, Berlin, 1981. 6. Gregorics, T., Sike, S.: Generic algorithm patterns, Proceedings of Formal Methods in Computer Science Education FORMED 2008, Satellite workshop of ETAPS 2008, Budapest March 29, 2008, p. 141-150. 7. Gregorics, T.: Programming theorems on enumerator, Teaching Mathematics and Computer Science, Debrecen, 8/1 (2010), 89-108 8. Hoare C.A., Proof of Correctness of Data Representations}, Acta Informatica (1972), 271-281. 9. Kondorosi K.,Lszl Z.,Szirmay-Kalos L.: Objektum orientlt szoftverfejleszts, ComputerBooks, Budapest, 1997. 10. Sommerville I., Software Engineering, Addison-Wesley, 1983. 11. Workgroup on Relation Models of Programming: Some Concepts of a Relational Model of Programming,Proceedings of the Fourth Symposium on Programming Languages and Software Tools, Ed. prof. Varga, L., Visegrd, Hungary, June 9-10, 1995. 434-44.

336

You might also like