Algoritmusok és készítésük
Algoritmus fogalma Az algoritmus szó Muhammad Ibn Músza Al-Hvázimi (IX. század) csillagász és matematikus nevéből származik A hindu számokról írt jelentős munkájának pontatlan latinra fordításakor változott a szerző neve Algoritmusra Az algoritmus egy probléma véges számú elemi lépésben történő egyértelmű és teljes megadása.
A problémamegoldás lépései A feladat megfogalmazása A feladat leírása legyen mindig pontos és egyértelmű. Ezt elhanyagolva sok idő és pénz veszhet kárba. Elemzés, tervezés, szervezés Számos módszertant, szoftvert fejlesztettek ki erre a célra. Ezek tartalmazzák a probléma megoldását támogató és leíró matematikai modelleket, valamint a be- és kimenő adatokkal szembeni igényeket
A problémamegoldás lépései (folyt.) Programtervezés, algoritmuskészítés Ebben a szakaszban kell megtervezni és dokumentálni a különböző modelleket megvalósító algoritmusokat. Az algoritmus nem egyenlő a programmal, ugyanis még általános, programnyelv-független A programterv kidolgozása többlépcsős, egyre finomabb részletezettségű
A problémamegoldás lépései (folyt.) Programozás, kódolás Az algoritmusok kódolása konkrét programozási nyelvre Ebben az esetben a számítógép számára értelmezhető, futtatható programokról van szó A program tesztelése, hangolása A tesztelés bonyolult, aprólékos munka, megfelelő időt kell rá fordítani (hibák kiküszöbölése, finomhangolás)
A problémamegoldás lépései (folyt.) Dokumentálás Az egész folyamatot végigkíséri, de ebben a fázisban kell a felhasználók és üzemeltetők számára leírni a rendszer használatát Ez a leírás tartalmazza a rendszer működési feltételeit, paramétereit, valamint az adminisztrátori és felhasználói kézikönyveket A rendszer bevezetése, üzemszerű használata A megtervezett, elkészített, letesztelt és dokumentált rendszer használatának megkezdése, folyamatos ellenőrzés mellett A bevezetés után megfogalmazódó igények alapján további verziók készíthetők
Algoritmus-leíró eszközök Ezekkel az eszközökkel jeleníthetőek meg az algoritmusok: Folyamatábra (blokkdiagram) Mondatszerű leírás (leírónyelv) Struktogram Jackson módszer Mindegyik leíró eszköznek megvannak a maga külön jelölési módszerei
Folyamatábra (blokkdiagram) A folyamatábra az algoritmus képi reprezentációja A mindennapi életben is találkozhatunk algoritmusokkal (bank- vagy italautomata) A szimbólumok különbözőek, de mindegyikre igaz, hogy elemi vagy összetett lépések végrehajtási sorrendjét adják meg
Folyamatábra jelölései Kezdőpont jele: minden algoritmusban csak 1 van belőle, pontosan 1 él indul ki belőle és egy sem csatlakozik bele Végpont jele: minden algoritmusban csak 1 van belőle, pontosan 1 él csatlakozik bele és egy sem indul ki belőle Beolvasás és kiíratás szimbóluma: legalább 1 él csatlakozik bele és pontosan 1 él indul ki belőle Értékadás szimbóluma: a kifejezés értéke a változóban lesz tárolva. Legalább 1 él csat-lakozik bele és pontosan 1 indul ki belőle START STOP be: vált1, vált2 ki: kif1, kif2 változó:=kifejezés
Folyamatábra jelölései (folyt.) Döntés (elágazás) szimbóluma: ha a feltétel igaz, akkor az igaz ágon, ellenkező esetben a hamis ágon folytatódik az algoritmus. Legalább 1 él csatlakozik bele, és legalább 1 indul ki belőle Beágyazás szimbóluma: egy máshol leírt (rész)algoritmust helyettesít. Legalább 1 él csatlakozik bele és pontosan 1 indul ki belőle Ciklikus végrehajtás szimbóluma: három műveletet tartalmaz (számláló beállítása, vizsgálata és léptetése). Pontosan 2 él indul ki belőle és pontosan 2 él érkezik bele feltétel részalgoritmus beállít, vizsgál, léptet
Folyamatábra jelölései (folyt.) Folyamatvonal: a végrehajtás irányát, a lépések egymásutániságát mutatja. Csak a döntési és a ciklikus végrehaj-tás szimbólumában ágazhat el.
Adatok, adattípusok, változók
Változó A változó egy névvel ellátott tárolóhely a számítógép memóriájában értéke mindig a tárolóhely aktuális tartalma A változókat jellemezhetjük a nevével típusával memóriabeli kezdőcímével értékével
Név A változó neve az azonosításra szolgál ezzel tudunk a változóra hivatkozni, pl.: valamilyen képletben célszerű a változónak beszédes nevet adni (a nevéből rá lehessen jönni, mi a tartalma) mivel általában többször használjuk egy programban, így a hossza is fontos programnyelvfüggőek a névre vonatkozó szabályok (hány karakter, milyen karakterek, kis- és nagybetű számít-e)
Típus Nagyon fontos tulajdonsága egy változónak a típus, hiszen meghatározza: a változó értékkészletét a változóval elvégezhető műveletek körét a helyfoglalás nagyságát a memóriában A típusok konkrét megvalósítása az adott programnyelvtől függ, de általánosan elmondható, hogy 2 nagy csoportra oszthatóak: elemi típusok összetett típusok
Elemi típusok Az elemi típusoknak nincs szerkezetük, nem lehet egyes részeiket külön kezelni Egész szám: egész számok tárolására, melyek lehetnek előjelesek vagy előjel nélküliek; többféle létezik belőle Valós számok: véges tizedes törtek ábrázolására, a számokat normál alakban tárolják; többféle létezik belőle Karakter: egyetlen karakter tárolására
Elemi típusok (folyt.) Logikai: kétféle értéket vehet fel (igaz, hamis) Mutató: a változó értéke egy memóriacím, amivel gyakorlatilag „rámutatunk” az adott memóriabeli helyre (dinamikus memóriakezelés megvalósításához szükséges)
Összetett típusok Elemi vagy összetett típusokat tartalmaznak valamilyen szerkezeti összefüggés szerint (adatszerkezeteknek is nevezzük őket) tömb: homogén adatszerkezet, azaz több azonos típusú elemet tartalmaz Jellemzői: név, típus, indexhatár A típus azt adja meg, hogy a tömbben szereplő elemek milyen típusúak Az indexhatár a tömb elemszámát határozza meg, azaz a tömb méretét (a memóriabeli mérete függ a típustól is) A tömb elemeire a tömb nevével, és mögötte szögletes zárójelben az indexszámmal hivatkozunk. Lehet egydimenziós (vektor) és többdimenziós is. A kétdimenziós tömböt mártixnak hívjuk.
Összetett típusok (folyt.) Karakterlánc (string, szöveg): egy karakter típusú egydimenziós tömbnek fogható fel kezelés szempontjából meghatározhatjuk a nevét és a méretét a string egyes elemeire a nevével és az adott karakter indexszámával (szögletes zárójelben) hivatkozhatunk Rekord: heterogén adatszerkezet, melynek valamennyi komponensére és magára a rekordra is külön névvel hivatkozunk különböző típusú adatokat lehet benne tárolni a komponenseket mezőknek hívjuk állománykezelésnél, ill. adatbázis-kezelésnél használják
Összetett típusok (folyt.) Állomány (fájl): típusai: szöveges állomány típusos állomány nem típusos állomány
Érték A legtöbb programozási nyelvben a változót deklarálni kell azaz, mielőtt használnánk, meg kell adni a nevét és a típusát (ezt általában a program vagy algoritmus elején található deklarációs részben lehet megtenni) A változó deklarálásakor a változó típusának megfelelő hely lefoglalódik a memóriában A deklarálás pillanatában a változó értékét definiálatlannak nevezzük Ekkor is lehet értéke, a memóriában lefoglalt hely korábbi tartalmától függően mivel ezt a korábbi értéket biztosan nem akarjuk használni, a változónak érdemes kezdőértéket adni
Kifejezés Kifejezés lehet: egy konkrét érték (pl.: 10, hamis, „A”) egy változó (pl.: a, x, min, nev) változók vagy konkrét értékek és műveleti jelek kombinációja (pl.: 2*x, 3+2, N<=5) A műveleti jeleket operátoroknak, a változókat és konkrét értékeket operandusoknak hívjuk A kifejezéseket kiértékelve konkrét értéket kapunk (aminek lesz valamilyen típusa) a kifejezés típusa a kifejezésben szereplő operandusok és operátorok típusától függ
Konstans Lényege: egy konkrét értéket valamilyen beszédes névvel látunk el, hogy a későbbiekben a névvel tudjunk rá hivatkozni (pl.: pi) Előnye: az algoritmust átláthatóbbá teszi A konstansokat a program vagy algoritmus elején kell megadni, és csak itt kap értéket Ha az alapértékét meg szeretnénk változtatni, azt elég egyszer megtenni az algoritmus folyamán
Vezérlési szerkezetek A folyamatábrák segítségével csak egyszerűbb algoritmusok írhatóak le Komolyabb algoritmusok készítéséhez vezették be a vezérlési szerkezeteket Az 1960-as években bebizonyították, hogy minden algoritmus leírható 3 vezérlési szerkezettel: szekvenciával szelekcióval iterációval
Vezérlési szerkezetek (folyt.) Szekvencia: utasítások egymás utáni végrehajtása külön nem jelöljük Szelekció (elágazás): egy feltétel kiértékelésének eredményétől függ, hogy milyen utasítások kerülnek végrehajtásra Iteráció (ciklus, ismétlés): egy utasítás egymás után többszöri végrehajtása esetén használjuk
Vezérlési szerkezetek (folyt.) Ezek a vezérlési szerkezetek leírhatóak folyamatábrával, de mivel egymásba ágyazhatóak, egy bizonyos szint után a folyamatábra áttekinthetetlenné és túl bonyolulttá válik.
Mondatszerű leírás (leírónyelv) Ez az algoritmusleíró eszköz a magyar nyelvre épül, így könnyebben tanulható és átlátható. A sok különböző programozási nyelv eszköztáraiból csak a legfontosabbakat tartalmazza A mondatszerű leírással megírt algoritmus nem más, mint utasítások sorozata Létezik hozzá szabálygyűjtemény, ezt szintaxisnak nevezzük.
Leírónyelv - változódeklarálás Az algoritmus kezdésének jelölése után következik az algoritmus kezdése leírónyelvben: algoritmus név változódeklarálás: váltózó váltnév1, váltnév2, … : típus akkor írhatjuk a változóneveket egy sorba, ha azok azonos típusúak különböző típusú változóknál annyi sor lesz, ahány különböző típust akarunk használni
Leírónyelv – változódeklarálás (folyt.) Példák változódeklarálásra: változó darab:egész változó átlag:valós változó l:logikai változó vezetéknév, keresztnév: szöveg Konkrét programozási nyelvek esetén figyelni kell a névadásra, mert léteznek olyan nyelvek, ahol a kis- és nagybetű különbözőnek számít (pl.: Java)
Leírónyelv - értékadás változónév:=kifejezés A := jel jobb oldalán lévő kifejezést kiszámítja, és az eredményt eltárolja a bal oldalon található változóban Ez csak akkor lehetséges, ha a kifejezés eredményének és a változónak a típusa megegyezik Pl.: átlag:=összeg/db l:=(darab<=10) vezetéknév:="Horváth"
Leírónyelv – értékadás (folyt.) Az első példánál látható, hogy az osztásra a / jel szolgál. Ha elosztjuk az összeget a darabszámmal, akkor megkapjuk az átlagot Fontos, hogy az átlag nevű változó valós típusú legyen, mivel egy osztás eredménye általában nem egész szám
Leírónyelv – értékadás (folyt.) A második példát úgy kell értelmezni, hogy ha a darab nevű változó aktuális értéke kisebb, mint 10, akkor az l nevű logikai típusú változó értéke igaz lesz, ellenkező esetben hamis A harmadik sorban szöveges értéket adtunk egy változónak. fontos, hogy ekkor a szöveget " " jelek közé kell tenni, különben a szöveget változónévként próbálja értelmezni a program, és ez hibához vezethet
Leírónyelv – Beolvasás, kiíratás be: vált1, vált2… Kiíratás ki: kif1, kif2… A be utasítás a felhasználótól kapott értékeket eltárolja az adott nevű változókba A ki utasítás pedig kiírja a képernyőre a megadott kifejezést, vagy a változók értékét
Leírónyelv – Beolvasás, kiíratás (folyt.) Példa (név beolvasása, majd üdvözlés kiíratása): algoritmus üdv változó név:szöveg ki: "Írj be egy nevet!" be: név ki: "Üdvözöllek", név algoritmus vége
Leírónyelv – Beolvasás, kiíratás (folyt.) Példa (név beolvasása, majd üdvözlés kiíratása) magyarázata: Először változót deklarálunk: létrehozzuk a név nevű változót, ami szöveg típusú lesz Majd kiíratjuk a képernyőre, hogy mit csináljon a felhasználó (írja be a nevet) Bekérésnél a felhasználó által beírt nevet eltároljuk a név nevű változóban Végül kiírjuk az üdvözlő szöveget, majd mellé a nevet, amit a felhasználó megadott, és a név nevű változóban található
Leírónyelv – Szelekció Szelekciónál egy feltételtől függően hajtunk végre bizonyos utasításokat 3 fajtája van: egyágú elágazás kétágú elágazás többágú elágazás
Leírónyelv – Szelekció (folyt) Egyágú elágazás: ha feltétel akkor utasítás(ok) hvége Ha az adott feltétel igaz, akkor az utasítás(ok) végrehajtódnak
Egyágú szelekció folyamatábrával h i feltétel utasítás(ok)
Leírónyelv – Szelekció (folyt) Kétágú elágazás: ha feltétel akkor utasítás(ok) különben hvége Ha az adott feltétel igaz, akkor az adott utasítás(ok) hajtódnak végre, ha hamis, akkor a különben részbe írt utasítás(ok) hajtódnak végre
Kétágú szelekció folyamatábrával h i feltétel utasítás(ok) utasítás(ok)
Leírónyelv – Szelekció (folyt) Többágú elágazás: elágazás amikor feltétel1: utasítás(ok) amikor feltétel2: … különben evége
Leírónyelv – Szelekció (folyt) Többágú elágazás: A többágú elágazásnak legalább egy amikor ágat kell tartalmaznia, a különben ág elhagyható Ha valamelyik feltétel teljesül, akkor a hozzá tartozó utasítások hajtódnak végre Ha egyik feltétel sem teljesül, akkor a különben ágba írt utasítások hajtódnak végre (ha van különben ág)
Többágú szelekció folyamatábrával h i feltétel h i utasítás(ok) feltétel utasítás(ok) utasítás(ok)
Leírónyelv – Szelekció (folyt) Példa kétágú elágazásra (két szám összehasonlítása): algoritmus nagyobb változó a,b:egész be: a,b ha a>b akkor ki: "A nagyobb mint B" különben ki: "A nem nagyobb mint B" algoritmus vége
A példa folyamatábrával START be: a, b h i a>b ki: "A nagyobb mint B" ki: "A nem nagyobb mint B" STOP
Leírónyelv – Szelekció (folyt) Példa többágú elágazásra (két szám összehasonlítása): algoritmus nagyobb változó a,b:egész be: a,b elágazás amikor a>b: ki: "A nagyobb mint B" amikor a<b: ki: "B nagyobb mint A" különben ki: "A két szám egyenlő" evége algoritmus vége
A példa folyamatábrával START be: a, b h i a>b ki: "A nagyobb mint B" h i a<b ki: "A kisebb mint B" ki: "A két szám egyenlő" STOP
Leírónyelv – iteráció Az iteráció esetében olyan utasításokról van szó, amiket többször ismételünk meg egymás után Alapvetően 3 fajta iterációt (ciklust) különböztetünk meg: növekményes (léptetős) ciklus elöltesztelő ciklus hátultesztelő ciklus
Leírónyelv – iteráció (folyt.) Növekményes (léptetős) ciklus Akkor használjuk, ha pontosan tudjuk, hogy hányszor kell ismételni az adott utasításokat Szükség van a ciklusban egy ún. ciklusváltozóra, amivel számon tarthatjuk, hogy hányadik ismétlésnél tartunk ciklus cv:=ké..vé lépésköz=lk ismétel utasítás(ok) cvége ciklusmag
Leírónyelv – iteráció (folyt.) cv: ciklusváltozó ké: kezdőérték vé: végérték lk: lépésköz (a ciklusváltozót mekkora lépésekkel változtassuk – egyesével, kettesével,… stb.) ciklusmag: az ciklus azon része, amely az ismétlendő utasításokat tartalmazza
Növekményes ciklus folyamatábrával cv:=ké cv<=vé cv:=cv+1 utasítás(ok)
Leírónyelv – iteráció (folyt.) Példa (első 10 négyzetszám kiíratása): algoritmus négyzetszám változó i:egész ciklus i:=1..10 lépésköz=1 ismétel ki: i*i cvége algoritmus vége
A példa folyamatábrával START i:=1 i<=10 i:=i+1 STOP ki: i*i
Leírónyelv – iteráció (folyt.) Példa (első 10 négyzetszám kiíratása) magyarázata: A ciklus 10-szer fog lefutni (a ciklusváltozó 1-től megy 10-ig) Először a ciklusváltozó 1, ekkor a ciklusba lépve kiíródik az 1*1, azaz az 1 Második lépésben a ciklusváltozó 2-re változik (ha a lépésköz 1), ekkor a 2*2, azaz a 4 kerül kiírásra Ez egészen addig megy így, amíg el nem értük az utolsó ismétlést (10.), amikor is a 10*10, azaz a 100 kiíratása után kilépünk a ciklusból
Leírónyelv – iteráció (folyt.) Elöltesztelő ciklus A ciklus végrehajtása egy feltételhez van kötve Ha a feltétel igaz, akkor BELÉPÜNK a ciklusba, és végrehajtódnak a ciklusmagban található utasítások Előfordulhat, hogy a ciklusmag egyszer sem hajtódik végre, amennyiben a feltétel már kezdéskor hamis
Leírónyelv – iteráció (folyt.) Gondoskodni kell arról, hogy olyan feltételünk legyen, ami egyszer mindenképpen hamissá válik, ellenkező esetben soha nem ér véget a ciklus (végtelen ciklus) amíg feltétel ismétel utasítás(ok) avége ciklusmag
Elöltesztelő ciklus folyamatábrával h feltétel i utasítás(ok)
Leírónyelv – iteráció (folyt.) Példa (bekért számok négyzetgyökének kiíratása, amíg nem negatív szám kerül beírásra): algoritmus négyzetszám változó a:egész be: a amíg a>=0 ismétel ki: gyök(a) avége algoritmus vége
A példa folyamatábrával START be: a a>=0 STOP ki: gyök(a) be: a
Leírónyelv – iteráció (folyt.) Példa magyarázata: Először bekérünk egy számot a felhasználótól, amit az a nevű változóban eltárolunk Ha ez a szám nem negatív, akkor belépünk a ciklusba, és kiíratjuk a négyzetgyökét Bekérünk egy újabb számot, és az a nevű változó értékét felülírjuk vele Ha ez az új szám nem negatív, akkor újra végrehajtjuk a ciklusmagot (gyök kiíratása, újabb bekérés), ha negatív, akkor kilépünk a ciklusból
Leírónyelv – iteráció (folyt.) Hátultesztelő ciklus A ciklus egyszer mindenképpen végrehajtódik, a ciklusból történő KILÉPÉS van feltételhez kötve Miután végrehajtódnak a ciklusmag utasításai, a ciklus végén ellenőrizzük, teljesül-e a feltétel. Ha igen, kilépünk a ciklusból, ha nem, visszaugrunk az elejére
Leírónyelv – iteráció (folyt.) Gondoskodni kell arról, hogy olyan feltételünk legyen, ami egyszer mindenképpen igazzá válik, ellenkező esetben soha nem ér véget a ciklus (végtelen ciklus) ismétel utasítás(ok) ivége feltétel esetén ciklusmag
Hátultesztelő ciklus folyamatábrával utasítás(ok) i feltétel h
Leírónyelv – iteráció (folyt.) Példa (bekért számok négyzetgyökének kiíratása, amíg nem negatív szám kerül beírásra): algoritmus négyzetszám változó a:egész be: a ismétel ki: gyök(a) ivége a<0 esetén algoritmus vége
A példa folyamatábrával START be: a ki: gyök(a) be: a a<0 STOP
Leírónyelv – iteráció (folyt.) Példa magyarázata: Először bekérünk egy számot a felhasználótól, amit az a nevű változóban eltárolunk Kiíratjuk a szám négyzetgyökét, majd bekérünk egy újabb számot, és az a nevű változó értékét felülírjuk vele Ha ez az újonnan bekért szám negatív, akkor kilépünk a ciklusból, ha nem negatív, akkor visszaugrunk a ciklus elejére (kiíratjuk a négyzetgyököt, bekérünk egy új számot) VIGYÁZAT! Ebben az esetben, ha először negatív számot írunk be, akkor hibát kapunk (gyökvonásnál), mert egyszer mindenképpen lefut a ciklus!