6. Elemi algoritmusok

Rendezési reláció

Egy olyan bináris rendezésről van szó, amely

  • reflexív,

  • tranzitív,

  • antiszimmetrikus.

Jellemzően teljes rendezést szoktunk vizsgálni, melyre teljesül a linearitás is.

A sorozatokról megköveteljük, hogy bármely két eleme összehasonlítható legyen.

Figyelem

Az, hogy egy sorozat elemein értelmezve van egy rendezési reláció, hogy vagy a sorozat rendezett, az két külön fogalom.

T tulajdonság

Jelölje A egy sorozat elemeinek a halmazát. T tulajdonság alatt egy olyan függvényt értünk, amely az A minden eleméhez hozzárendel egy logikai értéket.

T:A{igaz,hamis}
T(a)={igaz,ha aA egy T tulajdonságú elem,hamis,egyébként.

Általános bináris művelet jelölése

Az algoritmusok egy részében egy konkrét bináris művelet helyett egy általánosat adunk meg, amelyet egy jellel jelölünk, például xy.

Null elem

Főként inicializálásnál hasznos, hogy ha az adott művelethez meg tudjuk adni a null elemet, amelyre teljesül, hogy aNull=a, bármilyen aA esetén.

Például:

  • A=R,=+ esetén Null=0.

  • A=R,= esetén Null=1.

  • A=S,= esetében Null= (üres sztring, ε).

Elemi algoritmusok

Sorozatszámítás

  • A sorozat értékeit egy értékben „összesíti”.

  • Szokás még aggregációnak, redukciónak is nevezni.

REDUCE(@X,@s)//Input:Xsorozat,xiA//Output:sAsNullFOR i1 TO Hossz[X] DOssxiRETURN(s)

Adjuk meg a szumma, produktum és a szövegek összefűzésének esetét!

Eldöntés

  • Egy sorozat elemeit vizsgáljuk meg, hogy teljesül-e rájuk valamilyen T tulajdonság.

  • Tulajdonképpen 2 algoritmusról van szó, amelyeket együtt érdemes említeni.

Létezik a sorozatban T tulajdonságú elem?

EXISTS(@X,@van)//Input:Xsorozat,xiA//Output:Van{igaz,hamis}i1WHILE iHossz[X] AND T(xi) DOINC(i)van(iHossz[X])RETURN(van)

A sorozat minden eleme T tulajdonságú?

ALL(@X,@mind)//Input:Xsorozat,xiA//Output:mind{igaz,hamis}i1WHILE iHossz[X] AND T(xi) DOINC(i)mind(i>Hossz[X])RETURN(mind)

Kiválasztás

  • Egy T tulajdonságú elemet keres meg a sorozatban.

  • Az elem értékét, vagy indexét is visszaadhatja. (Az index esetünkben informatívabb, ezért itt most azt fogjuk visszaadni.)

  • Feltételezzük, hogy biztosan van T tulajdonságú elem a sorozatban.

FIND(@X,@index)//Input:Xsorozat,xiA//Output:indexNi1WHILE T(xi) DOINC(i)indexiRETURN(index)

Lineáris keresés

  • Az elem létezésének vizsgálatát és indexének a keresését kombinálja.

LINEAR_SEARCH(@X,@van,@index)//Input:Xsorozat,xiA//Output:van{igaz,hamis}//indexNi1WHILE iHossz[X] AND T(xi) DOINC(i)van(iHossz[X])IF vanTHEN indexiRETURN(van,index)

Megszámlálás

  • A sorozatban a T tulajdonságú elemek számát adja vissza.

COUNT(@X,@count)//Input:Xsorozat,xiA//Output:countZcount0FOR i1 TO Hossz[X] DOIF T(xi)THEN INC(count)RETURN(count)

Maximum kiválasztás

  • Feltételezzük, hogy a sorozat elemein értelmezve van egy teljes rendezés.

  • A maximális értékű elem indexével térünk vissza.

  • Feltételezzük, hogy a sorozatnak legalább egy eleme van.

MAX(@X,@index)//Input:Xsorozat,xiA//Output:indexN, a maximális elem indexeindex1FOR i2 TO Hossz[X] DOIF xi>xindexTHEN indexiRETURN(index)

Hogy ha több maximális értékű elem is van, akkor melyik indexe kerül visszaadásra?

Hogyan kezelhető az üres sorozatok esete?

Hasonlóképpen adjuk meg a minimum számítását is!

Másolás

  • A bemeneti sorozatot transzformálást követően egy kimeneti sorozatba másolja át.

  • A transzformációt egy f:AB függvény formájában adhatjuk meg.

MAP(@X,@Y)//Input:Xsorozat,xiA//Output:Ysorozat,yiBHossz[Y]Hossz[X]FOR i1 TO Hossz[X] DOyif(xi)RETURN(Y)

Kiválogatás

  • A bemeneti sorozatból kigyűjtjük a T tulajdonságú elemeket a kimeneti sorozatba.

COLLECT(@X,@Y)//Input:Xsorozat,xiA//Output:Ysorozat,yiAHossz[Y]0FOR i1 TO Hossz[X] DOIF T(xi)THEN INC(Hossz[Y])yHossz[Y]xiRETURN(Y)

Hasonlóképpen adható algoritmus az indexek kigyűjtésére is.

Szétválogatás

  • A T és nem T tulajdonságú elemeket külön sorozatokba gyűjti.

ASSORT(@X,@Y,@Z)//Input:Xsorozat,xiA//Output:Ysorozat,yiA//Zsorozat,yiAHossz[Y]0Hossz[Z]0FOR i1 TO Hossz[X] DOIF T(xi)THEN INC(Hossz[Y])yHossz[Y]xiELSE INC(Hossz[Z])zHossz[Z]xiRETURN(Y,Z)

Metszet

  • A két bemeneti sorozatról feltételezzük, hogy azokban csak különböző elemek vannak.

  • Tulajdonképpen a halmaz sorozat implementációját használjuk.

  • A bemenetként adott halmazok metszetét adjuk meg kimenetként.

INTERSECTION(@X,@Y,@Z)//Input:Xsorozat,xiA//Ysorozat,yiA//Output:Zsorozat,ziAHossz[Z]0FOR i1 TO Hossz[X] DOj1WHILE (jHossz[Y]) AND (xiyj) DOINC(j)IF jHossz[Y]THEN INC(Hossz[Z])zHossz[Z]xiRETURN(Z)

Egyesítés

  • A két bemeneti sorozatról feltételezzük, hogy azokban csak különböző elemek vannak.

  • Tulajdonképpen a halmaz sorozat implementációját használjuk.

  • A bemenetként adott halmazok unióját adjuk meg kimenetként.

UNION(@X,@Y,@Z)//Input:Xsorozat,xiA//Ysorozat,yiA//Output:Zsorozat,ziAHossz[Z]Hossz[X]FOR i1 TO Hossz[X] DOzixiFOR j1 TO Hossz[Y] DOi1WHILE (iHossz[X]) AND (xiyj) DOINC(i)IF i>Hossz[X]THEN INC(Hossz[Z])zHossz[Z]yjRETURN(Z)

Összefuttatás

  • Két szigorúan monoton növekvő sorozatot egy harmadik rendezett sorozatba futtatunk/fűzünk össze.

MERGE(@X,@Y,@Z)//Input:Xsorozat,xiA//Ysorozat,yiA//Output:Zsorozat,ziAHossz[Z]0i1j1WHILE iHossz[X] AND jHossz[Y] DOINC(Hossz[Z])CASExi<yj:zHossz[Z]xiINC(i)xi=yj:zHossz[Z]xiINC(i)INC(j)xi>yj:zHossz[Z]yiINC(j)WHILE iHossz[X] DOINC(Hossz[Z])zHossz[Z]xiINC(i)WHILE jHossz[Y] DOINC(Hossz[Z])zHossz[Z]yjINC(j)RETURN(Z)

Iteráció és rekurzió

Amennyiben egy problémát vissza tudunk vezetni egy azonos jellegű, de kisebb méretű problémára, akkor használhatunk rekurziót.

Faktoriális számítása

f(n)={nf(n1),ha n>1,1,ha n=1.

Rekurzív változat:

FACTORIAL(n,@result)//Input:nN//Output:resultNIF n>1THEN CALL FACTORIAL(n1,result)resultnresultELSE result1RETURN(result)

Fibonacci számsorozat

  • A Fibonacci sorozat n-edik elemét szeretnénk kiszámolni.

F0=0F1=1Fn=Fn2+Fn1

Rekurzív változat:

FIBONACCI(n,@result)//Input:nN//Output:resultNIF n2THEN CALL FIBONACCI(n2,a)CALL FIBONACCI(n1,b)resulta+bELSE resultnRETURN(result)

Bináris keresés

  • Feltételezzük, hogy van egy rendezett sorozatunk.

  • A lineáris kereséshez hasonlóan egy elemet szeretnénk megkeresni a sorozatban.

BINARY_SEARCH(@A,p,r,x,@index)//Input:A,rendezett sorozat//p,rN//x, a keresett elem//Output:indexN0,a keresett elem indexeIF p+1<rTHEN qp+r2IF aq=xTHEN indexqELSE IF x<aqTHEN CALL BINARY_SEARCH(A,p,q,x,index)ELSE CALL BINARY_SEARCH(A,q,r,x,index)ELSE index0RETURN(index)

Kérdések

  • Hogyan írható fel a halmaz különbség, mint algoritmus?

  • Hogyan írható fel a szimmetrikus differencia képzés, mint algoritmus?

  • Hogyan írható fel a faktoriális számítása iteratív alakban?

  • Hogyan írható fel az n. Fibonacci szám kiszámítása iteratív alakban?

  • Hogyan írható fel a bináris keresés iteratív alakban?

Feladatok

Pszeudókód, folyamatábra

A következő feladatokat oldjuk meg a pszeudókód felírásával és a folyamatábra felrajzolásával! (Minden esetben egy-egy procedúrát adjunk meg!)

  • Cseréljük ki két változó értékét!

  • Számoljuk meg egy sorozatban a páros számok darabszámát!

  • Számoljuk ki egy sorozatban a páratlan számok összegét!

  • Határozzuk meg a negatív számok maximumát!

  • Vizsgáljuk meg, hogy egy sorozat tartalmaz-e egy bizonyos elemet!

  • Vizsgáljuk meg, hogy egy sorozat rendezett-e!

  • Ellenőrizzük, hogy egy sorozat minden eleme egyedi!

  • Egy sorozatból gyűjtsük ki azon elemeket, amelyek megegyeznek az indexükkel!

  • Számoljuk meg, hogy egy bináris vektorban mennyi 0 és 1 érték van!

  • Két azonos hosszúságú bemeneti sorozatot fűzzünk össze úgy, hogy az első sorozat elemei a páratlan, a második sorozat elemei a páros indexekre kerüljenek.

Rekurzív függvények, procedúrák

  • Adottak a következő függvények!

f(n)={2f(n3),ha n>20,5,egyébként. 
g(n)={g(n1)+4g(n2),n>0,8,egyébként. 

Számítsuk ki az f(30) és g(5) értékeket!

  • Számítsuk ki az (53) értékét!

Használjuk fel hozzá a következő rekurzív összefüggést!

(nk)=(n1k1)+(n1k)

Adjuk meg a procedúra pszeudó kódját, folyamatábráját! Ábrázoljuk a rekurzív hívási fát!