AAO
This presentation is the property of its rightful owner.
Sponsored Links
1 / 147

AAO PowerPoint PPT Presentation


  • 102 Views
  • Uploaded on
  • Presentation posted in: General

AAO. Csink László 2010. ősz. Adminisztráció. Előadók: Csink László [email protected] A tárgy weblapja: http://nik.bmf.hu/csink/aao Login: aao Jelszó: algorithm Az objektumorientált programozás 5 előadásból áll, melyet Miklós Árpád ( [email protected] ) tart. A tárgy célja.

Download Presentation

AAO

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Aao

AAO

Csink László

2010. ősz


Adminisztr ci

Adminisztráció

Előadók:

  • Csink László [email protected] tárgy weblapja:

    http://nik.bmf.hu/csink/aao

    Login: aao Jelszó: algorithm

    Az objektumorientált programozás 5 előadásból áll, melyetMiklós Árpád ([email protected]) tart


A t rgy c lja

A tárgy célja

  • Ismerkedés az algoritmus fogalmával, egyszerű „klasszikus” algoritmusokkal

  • Ismerkedés az algoritmusok implementálásához (megvalósításához) szükséges legalapvetőbb adatstruktúrákkal

  • Bevezetés az objektumorientált programozási paradigma alapjaiba

  • Algoritmuskészítési készség kialakítása

    AAO= Algoritmusok, Adatstruktúrák, Objektumok

  • Mindez az OOP tárggyal való szoros együttműködésben valósul meg


Irodalom

Irodalom

Könyvek, amibikből lehet meríteni:

  • Cormen, Leiserson, Rivest: Algoritmusok (újabb kiadás is, valamint Informatikai algoritmusok)

  • Trahtenbrot: Algoritmusok és absztrakt automaták

  • Kotsis et al: Többnyelvű programozástechnika

  • Lovász L., Gács P.: Algoritmusok

    Referencia linkek:

  • Matematikai háttér http://mathworld.wolfram.com/

  • Lexikon: http://wikipedia.org/

    Ajánlott feladatgyűjtemény (PPKE)(A Kotsis et al könyv mellett): http://digitus.itk.ppke.hu/~lovei/2007-2/feladatok.html


Hogyan k sz ljenek sajnos igen nagy szokott lenni a buk si ar ny

Hogyan készüljenek?Sajnos, igen nagy szokott lenni a bukási arány!

  • A diák csak vázlatot jelentenek, a vetített anyag nem tankönyv!

  • Sokakat megtéveszt, hogy az előadásokon nincs névsor ellenőrzés. Ennek ellenére folyamatosan kell tanulni már a félév elejétől, sok gyakorlatra van szükség, a tudásnak „érlelődnie” is kell

  • Az előadásokon tárgyalt algoritmusokat célszerű C#-ban otthon megírni

  • A Kotsis könyvben található algoritmusokat elolvasni, megérteni, megpróbálni segítség nélkül megírni

  • A feladatgyűjtemény feladataira a programokat megírni

  • Az OOP gyakorlatokon tanultakat hasznosítani


Algoritmus fogalma

Algoritmus fogalma

  • Az algoritmus egy eljárás (jóldefiniált utasítások véges halmaza), amelyet valamely feladat megoldására készítünk. A feladat egy adott kezdeti állapotból egy meghatározott végállapotba jut (szakszóval terminál).

  • Az algoritmus kiszámítási bonyolultsága és hatékony implementációja az alkalmazott adatstruktúrától függ.


Inform lis s form lis defin ci

Informális és formális definíció

  • Az algoritmus tipikusan kisebb-nagyobb alkotórészekből épül fel. Az egyszerű algoritmus egy ételrecepthez hasonlítható.

  • A formális definíció Alan Turing (Turing gép, 1936) és Alonzo Church (lambda kalkulus) matematikusokhoz köthető. (lásd Haladó algoritmusok tárgy a későbbiekben)


Inform lis megk zel t s telrecept

Informális megközelítés: ételrecept

Informálisan – hétköznapi szavakkal – egy egyszerű algoritmus egy receptnek tekinthető.

A recept tartalmazza az adott étel

  • nevét;

  • elkészítésének idejét;

  • a szükséges alkotórészek nevét és mennyiségét;

  • az elkészítéshez szükséges eszközöket illetve környezetet (például mikrosütő);

  • az elkészítéshez szükséges eljárásokat meghatározott sorrendben;

  • az elkészült adagok számát;

  • a kalóriatartalmat egy adagra vetítve;

  • az étel eltarthatóságának idejét.


A m sodfok egyenlet receptje 1

A másodfokú egyenlet „receptje” 1.

  • Készítsünk algoritmust az ax2+bx+c=0 egyenlet megoldására.

  • 1. lépés: az input adatok meghatározása

    Jelen esetben: a, b, cvalós számok

  • 2. lépés: output adat(ok) meghatározása: egy xvalós szám (egy megoldás, illetve ha a két gyök egybeesik), x1 és x2valós számok (két különböző megoldás), illetve a „nincs valós megoldás”szöveg.


A megold s menete

A megoldás menete

  • Úgy fogjuk a megoldás menetét prezentálni, ahogy tervezés közben „eszünkbe jut”

  • Óhatatlan, hogy menet közben lesznek még hibák, mert nem pattan ki a tökéletes megoldás az agyunkból egyszerre

  • Minden lépés után elemezzük, hogy jól működik-e a programunk, és ha nem tökéletes, akkor javítunk rajta


A feladat receptje a hozz val k

A feladat „receptje”: a hozzávalók

  • A „recept” adatai:

  • Név:MASODFOKU

  • elkészítésének ideje (és szerző):2006-07-11. CsL

  • a feltétlenül szükséges adatok neve és típusa:

    • a,b,c,3 valós szám (INPUT)

    • xvalós szám, VAGY x1 és x2valós számok, VAGY”nincs valós megoldás”szöveg (OUTPUT)

  • az elkészítéshez szükséges eszközök illetve környezet:

    • Turbo C++ 3.0 (természetesen más is lehetne, például C#) Windows XP operációs rendszer alatt (ez is lehetne más)

  • az elkészítéshez szükséges eljárások:

    • gyökvonás, abszolút érték (ezek elkészítettnek tekintett programok)

      Megjegyzés: Az OOP gyakorlatokon Visual Studio C# környezetben fogunk dolgozni. (A Turbo C++ előnye, hogy ingyenes)


A feladat pontos t sa

A feladat pontosítása

  • Hasznos dolog egy konkrét példát megnézni: 4x2-12x+8=0

  • A megoldás x1=2; x2=1Erre a feladatra ez a két értékadás tulajdonképpen egy program. Ez a program azonban nem ad megoldást a 3x2+4x-2.11=0 feladatra. Azt szeretnénk, hogy ugyanaz a a program erre a feladatra is megoldást adjon.

  • Mi a helyzet az 12x+8=0 egyenlettel? Ez már elsőfokú. El kell dönteni, hogy eredetileg a másodfokú, vagy a legfeljebb másodfokú egyenlet megoldását tűztük-e ki célul?

  • Megállapítjuk, ezen példa kapcsán, hogy a feladat pontos mibenléte gyakran a megoldás során tisztázódik. A feladat specifikációja tehát finomodhat a megoldás közben.


A specifik ci

A specifikáció

  • Oldjuk meg az ax2+bx+c=0 egyenletet minden a, b, c valós szám esetén.Nevezzük a{ax2+bx+c=0 | a, b, c valós számok}problémaosztálynak, melynek a megoldását keressük.

  • Lehetett volna a problémaosztályt {ax2+bx+c=0 | a, b, c valós számok és a≠0}halmaznak választani, ekkor a megoldási algoritmus kicsit egyszerűbb, de kevésbé általános.


L tezik e megold s

Létezik-e megoldás?

  • Tudjuk (például mert érettségiztünk ), hogy van megoldóképlet:

Ha komplex megoldást nem engedünk meg – azaz a specifikációt úgy finomítjuk tovább, hogy valós x megoldásokat keresünk – akkor nincs megoldás.


Tanuls gok

Tanulságok

  • Hajlamosak vagyunk azt gondolni, hogy mindig létezik valamilyen megoldás, talán azért, mert hozzászoktunk a megoldható feladatokhoz a középiskolában. Vannak azonban algoritmussal nem megoldható problémák. Nem oldható meg például a szögharmadolási probléma: tetszőleges szög harmadának megszerkesztése.

  • Egy probléma algoritmussal való megoldhatóságának kérdése igen mély dolog, lásd incompleteness theorem a wikipedia-ban. (E tételt felállító Kurt Gödelről az az anekdota szól, hogy Einstein csak azért járt be Princetonban az egyetemre, hogy Gödellel sétálhasson haza és beszélgethessenek )


Els nekifut s

Első nekifutás

gy mint egész nem jó, pl. b=1.1., a=1, c=0.2

  • VÁLTOZÓK gy, a,b,c VALÓS SZÁM

  • BEOLVAS(a,b,c)

  • gy ← (b*b-4*a*c)

  • HA gy ≥0 AKKOR gy ← GYOKVONAS(b*b-4*a*c)

  • EGYÉBKÉNTKIIR(nincs valós megoldás)

    Itt folytatódna a megoldás, de csak akkor, ha a gyökvonás lehetséges volt. Mivel a gy<0 esetben a KIIR végrehajtása után nem akarjuk, hogy a program folytatódjon, ezért trükkösen megcseréljük a feltételt a HA mögött.

értékadás


Folytatjuk

Folytatjuk

6., 7., 8. sorok egybetartozásának jelölése (a zárójelek párban vannak!)

  • VÁLTOZÓK gy,a,b,c, x1 VALÓS SZÁM

  • BEOLVAS(a,b,c)

  • gy ← (b*b-4*a*c)

  • HA gy <0 AKKOR KIIR(nincs valós megoldás)

  • EGYÉBKÉNT{

  • gy ← GYOKVONAS(b*b-4*a*c)

  • HA gy=0 AKKORx1= -b/(2*a)

  • EGYÉBKÉNT folytatni kell a dolgot

  • }

    Piros színnel jelezzük a változásokat az előzőekhez képest.


Tov bb folytatjuk ez m g nem v gleges

Tovább folytatjuk (EZ MÉG NEM VÉGLEGES!

  • VÁLTOZÓK gy,a,b,c, x1,x2 VALÓS SZÁM ag EGÉSZ SZÁM

  • BEOLVAS(a,b,c)

  • gy ← (b*b-4*a*c)

  • HA gy <0 AKKOR ag=1

  • EGYÉBKÉNT{ ag=2

  • gy ← GYOKVONAS(b*b-4*a*c)

  • HA gy=0 AKKORx1= -b/(2*a)

  • EGYÉBKÉNT{ag=3

  • x1=-b+gy/(2a)

  • x2=-b-gy/(2a)

  • }

  • }

  • ESETEK ag

  • 1:KIIR(nincs valós megoldás)

  • 2:KIIR(egy megoldás van: , x1)

  • 3:KIIR(két megoldás van:, x1, x2)

  • ESETEK VEGE


Jav t sok megjegyz sek

Javítások, megjegyzések

Kellenek további zárójelek:

  • x1=(-b+gy)/(2a)

  • x2=(-b-gy)/(2a)

    Feltételezzük, hogy a KIIR argumentumában ha magyar mondat van, akkor a szöveg íródik ki, ha változónév van, akkor a változó értéke. Azt is feltesszük, hogy a BEOLVAS a megfelelő változókba a billentyűzetről megadott adatokat elhelyezi. A BEOLVAS és a KIIR megvalósításával nem „bíbelődünk”.

    Mi történik, ha a 7., vagy a 9. vagy a 10. sorban a=0 eset áll elő? Ekkor nullával való osztásra utaló hibaüzenet generálódik. Az ilyen esetek kezelésére a legtöbb nyelvben vannak eszközök (ezzel most nem foglalkozunk), hanem megpróbáljuk „előre látni”, hogy ilyen eset előfordulhat.


A 0 eset

a=0 eset

  • HA a=0 AKKOR

  • Megoldjuk a bx+c=0 egyenletet

  • EGYÉBKÉNT

  • Amit eddig csináltunk (a≠0, b,c tetszőleges)

Kész programblokk

Megírandó programblokk

A lépésenkénti finomítás módszerét alkalmazuk, pszeudokód segítségével.


Aao

A nyilak jelzik a megfelelő színű zárójelpárokat, azaz hogy melyik AKKOR és EGYÉBKÉNT melyik HA-hoz tartozik. Az alapértelmezés pont olyan, hogy ezek a zárójelek elhagyhatók.

  • VÁLTOZÓK gy,a,b,c, x1,x2 VALÓS SZÁM

  • BEOLVAS(a,b,c)

  • HA a=0 AKKOR

  • {

    HA b=0 AKKOR

  • {

  • HA c=0 AKKOR KIIR(minden valós szám megoldás)

  • EGYÉBKÉNT KIIR(nincs megoldás)}

  • }

  • EGYÉBKÉNT x1=-c/b

  • }

  • EGYÉBKÉNT

  • Amit eddig csináltunk (a≠0, b,c tetszőleges)


A program algoritmus sszerak sa

PROGRAM MASODFOKU

VÁLTOZÓK gy,a,b,c, x1,x2 VALÓS SZÁM ag EGÉSZ SZÁM

BEOLVAS(a,b,c)

HA a=0 AKKOR

HA b=0 AKKOR

HA c=0 AKKOR ag=4

EGYÉBKÉNT ag=5

EGYÉBKÉNT{ ag=6; x1=-c/b}

EGYÉBKÉNT{ gy ← (b*b-4*a*c)

HA gy <0 AKKOR ag=1

EGYÉBKÉNT{ag=2

gy ← GYOKVONAS(b*b-4*a*c)

HA gy=0 AKKOR x1= -b/(2*a)

EGYÉBKÉNT{ ag=3

x1=(-b+gy)/(2a)

x2=(-b-gy)/(2a)

}

}

ESETEK ag

1 : KIIR(nincs valós megoldás)

2 : KIIR(egy megoldás van: , x1)

3 : KIIR(két megoldás van:, x1, x2))

4 : KIIR(minden valós szám megoldás)

5 : KIIR(nincs megoldás)

6 : KIIR(elfajulo egyenlet, egy megoldás:, x1)

ESETEK VEGE

PROGRAM VÉGE

A program (algoritmus) összerakása


K zel t gy kvon s newton m dszer

Közelítő gyökvonás (Newton módszer)

Legyen A>0, emelyből gyököt szeretnénk vonni, és gy1 tetszőleges, például 1. Ekkor elég nagy n-re gyn közel van egy számhoz, amely A négyzetgyöke.

Más szóval a gyn sorozat konvergens és határértéke A négyzetgyöke. Ilyenkor elég nagy n-re gyn és gyn+1egy tetszőlegesen előre megadott számnál is közelebb kerülnek egymáshoz. A következőkben gyn helyett gy-t, gyn+1 helyett ujgy-t írunk és iteratíven számolunk.


A gy kvon s programja

A gyökvonás programja

  • // inp adott szám, melyből gyököt akarunk vonni

  • VÁLTOZÓK inp, ujgy, gy, d, eps DUPLAPONTOS

  • BEOLVAS(inp)

  • gy = 1.0

  • d=1.0

  • eps=0.00001

  • ISMETELNI HA( d > eps){

  • ujgy = (1.0/2)*(gy + inp/gy)

  • d = | ujgy – gy |

  • gy = ujgy

  • }

  • KIIR(gy)

Abszolút érték

A piros rész ismétlődik mindaddig, amíg a sárga rész teljesül. Figyeljük meg, hogy dmenetközben változik!


6 n gyzetgy k nek k zel t sz m t sa

6 négyzetgyökének közelítő számítása


Vigy zat

Vigyázat!

A fentiek csak azért működtek jól, mert tudtuk (matematikából), hogy gyn konvergens.

Ha most

akkor ugyan sn+1-sn bármilyen kicsi lehet, sn mégsem konvergens!

Tanulság: egy program használhatóságához szükséges, hogy az elméleti megalapozás korrekt legyen! Anélkül, hogy a gynkonvergenciáját bebizonyítjuk, vagy legalább hivatkozunk a megfelelő szakirodalomra, a fenti program nem ad megoldást, mert nem tudhatjuk, hogy véget ér-e a program, és ha igen, korrekt eredményt ad-e?


P lda hogyan keres nk algoritmust egy feladatra igazi alkalmaz sokn l

Példa: Hogyan keresünk algoritmust egy feladatra igazi alkalmazásoknál?

  • A napi gyakorlatban –ahelyett, hogy magunk készítünk algoritmust – sokszor inkább körülnézünk. Pontosabban: mindig körülnézünk, hogy van-e megoldás a feladatunkra, vagy nekünk kell nekifognunk megcsinálni (kivétel persze a zh vagy vizsga )

  • Nézzünk egy példát: tegyük fel, hogy egy szám prím vagy összetett voltát akarjuk megállapítani.

  • Keresünk egy algoritmus gyűjteményt, például a MathWorld weblapját (ld. referencia linkek): http://mathworld.wolfram.com/

  • Mivel jól tudunk angolul , könnyedén elnavigálunk az adott területre: Number Theory, Prime Numbers, Primality Testing.


Aao

ERATHOSTENESI SZITA

„An algorithm for making tables of primes. Sequentially write down the integers from 2 to the highest number you wish to include in the table. Cross out all numbers which are divisible by 2 (every second number). Find the smallest remaining number . It is 3. So cross out all numbers which are divisible by 3 (every third number). Find the smallest remaining number . It is 5. So cross out all numbers which are divisible by 5 (every fifth number). Continue until you have crossed out all numbers divisible by . The numbers remaining are prime. „ Forrás: MathWorld


Akkor mi rt nem csin ljuk mindig gy

Akkor miért nem csináljuk mindig így?

  • A feladat pontos megértéséhez gyakran el kell kezdeni megoldani a feladatot. Nem mindig van tehát elegendő információnk a feladatmegoldás kezdetén ahhoz, hogy algoritmus adatbázisokat vagy szakirodalmat használjunk.

  • Ahhoz, hogy a megfelelő megoldási változatot (paraméterek, sebesség, környezet stb.) kiválasszuk, algoritmuselmélet ismeretekre – és implementációs gyakorlatra – van szükségünk, melyet például ez a tárgy is adhat.

  • Lehet, hogy az adott feladatra nem találunk az igényeinket kielégítő megoldást.

  • Lehet, hogy a talált megoldásnál jobb jut eszünkbe (hiszen az irodalomban és a weben publikált megoldásokat is kitalálta valaki valamikor).


Egyszer programoz si t telek

Egyszerű programozási tételek

  • Sorozatszámítás

  • Eldöntés

  • Kiválasztás

  • Keresés

  • Megszámolás

  • Maximumkeresés


Sorozatsz m t s

Sorozatszámítás

  • A múlt évben minden hónapban eltettem a gázszámlát. Szeretném kiszámolni, hogy mennyi pénzbe került az éves gázfogyasztás. A megoldás lépései:

  • Lenullázok egy gyűjtőváltozót.

  • A következő két lépést 12-szer ismételem:

    • Megfogom a soron következő számlát.

    • Hozzáadom az előző összeghez.

  • Megvan az összeg.


Pszeudok d

Pszeudokód

VÁLTOZÓK i, sum EGÉSZ, szamla[i] EGÉSZ)

i ← 0; sum ← 0;

ISMÉTELNI HA( i kisebb mint 12){

sum ← sum + szamla[i]; i ← i+1;

}

KIIR(sum)

Január a 0.-dik, február az 1., …, december a 11. hónap a jelölés szerint


Eld nt s

Eldöntés

Egy tanuló érdemjegyei alapján szeretném eldönteni, hogy kitűnő-e, vagy sem. Kétféle ötlet is lehet:

  • Ha a jegyei közt van olyan, ami nem ötös, akkor nem kitűnő.

  • Ha minden jegye ötös, akkor kitűnő.

    Vizsgáljuk meg először az első ötletet közelebbről!

    Nézzük végig a jegyeket, először az elsőt, majd sorra a többit, és ellenőrizzűk, hogy ötös-e.

    Ha találtunk olyat, ami nem ötös, akkor nem kell megnézni a további jegyeket, mert van nem ötös osztályzat, azaz nem kitűnő.


Az 1 sz m pszeudok d

Az 1. számú pszeudokód

VÁLTOZÓK tantárgy_szám, i, jegyek[i] EGÉSZ,

van_nemotos LOGIKAI

i ← 1    

ISMÉTELD HA(i ≤ tantárgy_szám) és (jegyek[i] egyenlő 5-tel){

i ← i+1

}

van_nemotos ←(i ≤ tantárgy_szám)

HA (van_nemotos) AKKOR KIIR(nem kitűnő)

EGYÉBKÉNT KIIR(kitűnő)

Végignézem a jegyeket. Az elsővel kezdem.

ellenőrizzük a többit is, hogy ötös-e.


M sodik tlet

Második ötlet

Nézzük végig a jegyeket, először az elsőt,majd sorra a többit, és ellenőrizzük, hogy ötös-e. Ha a tömb minden elemét megvizsgáltuk, akkor minden érdemjegy ötös, azaz kitűnő.

VÁLTOZÓK tantárgy_szám, i, jegyek[i] EGÉSZ, mind_otos LOGIKAI

i ← 1    

ISMÉTELD HA(i ≤ tantárgy_szám) és (jegyek[i] egyenlő 5){ i ← i+1 }

mind_otos ←(i > tantárgy_szám)  

HA(mind_otos) AKKOR KIIR(kitűnő) EGYÉBKÉNT KIIR(nem kitűnő)


Kiv laszt s

Kiválasztás

Egy tankör zárthelyi dolgozatai közül válasszuk ki az egyik elégséges dolgozatot. Megoldás: nézzük végig a dolgozatokat,

először az elsőt, majd sorra a többit, amíg nem találunk elégséges dolgozatot.

Amikor megtaláltunk egy elégségest, akkor ő lesz a kiválasztott.


Pszeudok d1

Pszeudokód

VÁLTOZÓK i, sorsz, dolg_szama, dolgozatok[i] EGÉSZ

i ← 1    

ISMÉTELD HA ( (i ≤ dolg_szama) és (dolgozatok[i] ≠ 2) ) {

i ← i + 1

}

sorsz ← i    // Ha találtunk elégségest, az lesz a megoldás.

HA(i <= dolg_szama) AKKOR KIIR(sorsz);

EGYÉBKÉNT KIIR ("nincs elégséges")

  • Hasonlít az eldöntéshez, de más a konklúzió!


Keres s

Keresés

  • Ismerjük egy üzlet januári napi bevételeit. Adjunk meg egy olyan napot -ha van-, amikor a bevétel több volt, mint 20,000 Ft. Megoldás:

  • Nézzük végig a bevételeket,

    • először az elsőt,

    • majd sorra a többit,

  • amíg nem találunk 20,000 Ft-nál nagyobbat.

  • Ha találtunk ilyet,

    • akkor van megoldás, és a megoldás a megtalált bevétel sorszáma

    • különben nincs megoldás


Input adatok gener l sa

Input adatok generálása

Töltsük fel véletlen egészekkel a január tömb elemeit.

(Ezt most még nem kell megérteni, a félév végére világos lesz.)

int[] januar = new int [32];// 0-tól indul, a 32. lesz jan. 31 !

Random RandomClass = new Random();

for(int i = 1;i <=31; i++) januar[i]=RandomClass.Next(10,30);

  • 18 26 28 12 …. Január 1, 2, 3, 4, 5, …. Bevételei rendre ezer forintban, akkor január 3.-át kell megtalálnunk.

  • Persze az is lehet, hogy a bevétel egyetlen napon sem haladja meg a 20 ezer forintot.

  • A for ciklust fogjuk részletesen taglalni


A k d a while ciklust fogjuk r szletesen taglalni

A kód (a while ciklust fogjuk részletesen taglalni)

int i = 1;

while (januar[i] < 20) i++;Console.Write(januar[i] + " ");

Ez akkor nem jó, ha nincs megoldás, azaz jan. 31.-én (i=32)

Is a bevétel kisebb, mint 20. Mitől állna meg a ciklus?

Ha a napokszama == 31, akkor:

i = 1;

while ( (i<=napokszama) && (januar[i] <= 20)) i++;

if (i > napokszama) Console.WriteLine("NINCS megoldas");

else Console.Write(i + "dik nap! ");


Megsz mol s

Megszámolás

  • Az előző feladatot kicsit módosítjuk. Számoljuk meg, hány napon (ha egyáltalán) volt az üzlet bevétele 20 ezer forintnál nagyobb?


Megsz mol s k dja

Megszámolás kódja

int darab = 0;

for (i = 1; i <= napokszama; i++)

if (januar[i] > 20) darab++;

Console.WriteLine("a nagyobb bevételek száma: "+darab);


Maximum kiv laszt s

Maximum-kiválasztás

  • Tegnap este a térképet nézegettem. Kiírtam magamnak 20 magas hegy tengerszint feletti magasságát. Adjuk meg az egyik legmagasabb csúcsot! Megoldás:

  • Megjegyzem az első hegy magasságát. Ezt tekintem a legmagasabbnak.

  • A többi hegyet sorra végignézem:

    • Ha valamelyik magasabb, mint az eddigi legmagasabb, akkor az eddigi legmagasabbat elfelejtem, és az újat jegyzem meg.

  • A végén pont az első legmagasabb hegyet jegyeztük meg.


Maximum kiv laszt s pszeudok dja 1

Maximum-kiválasztás pszeudokódja 1

int hegyekszama = 10;

int[] magas = new int [hegyekszama+1];

// mert 1-től indexelünk

int i;

Random RandomClass = new Random();

for (i = 1; i <= hegyekszama; i++){

magas[i] = RandomClass.Next(10, 26);

Console.Write(magas[i]+" ");

}


Maximum kiv laszt s pszeudok dja 2

Maximum-kiválasztás pszeudokódja 2

int max = magas[1]; int eddigi = 1;

for (i = 1; i <= hegyekszama; i++)

if (magas[i] > max) { max = magas[i]; eddigi = i; }

Console.WriteLine("az (egyik) legmagasabb sorszáma: "+eddigi+" magassag "+max);

// magas[] tartalmát 1-től kezeljük

// Ha mondjuk a 2. hegy és a 7. hegy ugyanolyan magas,

// és a többi mind kisebb, az eredmény 2 lesz vagy 7?

// 2 lesz. Azonban ha > helyett >= kerül be, akkor 7.


Aao

Egyszerű változók (OOP gyakorlatokon részletezzük)


P ld k

Példák

  • int x = 10; // deklarálás kezdeti értékadássalint y = x;y = 20; // x értéke 10 és y értéke 20

  • float v=2.34; double w;


Adatkonverzi k

Adatkonverziók

A konverzió C# -ban lehet implicit vagy explicit. Ha az átalakítás automatikus, akkor implicit konverzióról beszélünk, ilyenkor nincs adatvesztés. Az explicit konverzió kikényszerített, ilyenkor előfordulhat adatvesztés.

Konverzió leggyakrabban függvényhívás paraméter-átadásakor történik (később látunk majd példákat), vagy kevert típusú adatokkal való numerikus számítások esetén.


A nyilak mutatj k az implicit konverzi s lehet s geket referencia t bl zat

A nyilak mutatják az implicit konverziós lehetőségeket (referencia táblázat)


Implicit numerikus konverzi

Implicit numerikus konverzió

long x1;

int y1 = 25;

x1 = y1; //implicit numerikuskonverzióint ->long

Console.WriteLine(x1);

int x1;

long y1 = 25;

x1 = y1;// long -> int nyíl nincs, mi lesz ?

// HIBAÜZENET: NEM LÉTEZŐ implicit konverzió!

// OK: mert esetleges adatvesztés lehetséges!


Megold s kasztol ssal explicit

Megoldás kasztolással (explicit)

int x1, x2;

long y1 = 2147483647, y2 = 21474836470;

//y1 „belefér” int-be, y2 „nem fér bele”

x1 = (int)y1; x2 = (int)y2; // (int) kasztolás

Console.WriteLine(x1+" "+x2);

// x1 = 2147483647, x2 = -10

// x2 esetében adatvesztés történt


Eg sz oszt s vagy val s oszt s

Egész-osztás vagy valós osztás?

int i = 13, j = 7; // mindkét argumentum eredetileg egész

int k = i / j; Console.WriteLine(k);// KIIR: 1

float k1 = i / j; Console.WriteLine(k1); // KIIR: 1

float k2 = (float) i / j; Console.WriteLine(k2); // 1.857143

// (float) i / (float) j vagy i / (float) j is jó!

Console.WriteLine( 55 / 7); // 7

Console.WriteLine(55.0 / 7); // 7.8571...


Oszt s folytat sa

Osztás folytatása

int j = 7; float i2 = 13,0f; f = i2 / j;

Console.WriteLine(f); // f == 1.85..

double i1 = 13.15; int j = 7;// i1 duplapontos, nem egészértékű

Console.WriteLine(i1/j); // 1.87...

float i2 = 13.15; // 13.15 double, nem tud floattá alakulni, HIBA!

int j = 7;Console.WriteLine((int) i2 / j);

float i2 = 13.15F; // 13.15F valós konstans

int j = 7;Console.WriteLine((int) i2 / j);// 1-t fog kiírni


Duplapontos v ltoz konvert l sa eg szre adatveszt ssel

Duplapontos változó konvertálása egészre adatvesztéssel

double i2 = 13.83;

Console.WriteLine( (int) i2 ); // 13

Példa logikai kifejezésre

int a = 7; bool log;

log = a % 2 == 0;// log = (a % 2 == 0);

if (log) Console.WriteLine(" paros");

else Console.WriteLine("paratlan");


String numerikus eg sz rt k

String -> numerikus (egész) érték

string sz = "123";

int sz1 = Int32.Parse(sz); // így is lehet

int sz2 = Convert.ToInt32(sz);// vagy akár így is lehet


String numerikus val s rt k

String -> numerikus (valós) érték

string myDoubleStr = "-12,2";

double x = Double.Parse(myDoubleStr) + 5.3;

double y = Convert.ToDouble(myDoubleStr) +1.1;

Console.WriteLine(x); // -6,9

Console.WriteLine(y); // -11,1

Érdemes a tizedespont illetve a vessző használatára figyelni.

A stringek részletes tárgyalása az IMOP gyakorlatokon történik!!


El ltesztel s h tultesztel ciklus 1

Elöltesztelő és hátultesztelő ciklus 1.

Vissza

int a = 0;

while (a < 3) { Console.WriteLine(a);

a++;

}

// a=0 indulással kiírja a 0, 1, 2 számokat

int a = 0;

do{

Console.WriteLine(a);

a++;

} while(a < 3);

// a=0 indulással ugyanúgy, mint a zöld kód, kiírja a 0,1,2-t

Nem olyan, mint a repeat Delphiben!


El ltesztel s h tultesztel ciklus 2

Elöltesztelő és hátultesztelő ciklus 2.

int a = 5;

while (a < 3) { Console.WriteLine(a);

a++;

}

// ha a=5 induláskor, akkor egyszer sem hajtódik végre

int a = 5;

do{

Console.WriteLine(a);

a++;

} while(a < 3);

// ha induláskor a=5; akkor kiírja az 5-t, egyszer végrehajtódik, többször nem

Nem olyan, mint a repeat Delphiben!


For ciklus

For ciklus

for (int a = 0; a < 5; a++)// 0, 1, 2, 3, 4 kiírása

Console.WriteLine(a);

// Nem hajtódik végre a ciklusmag a következő esetben:

for (int a = 6; a < 5; a++)

Console.WriteLine(a);

// 0, 2, 4 íródik ki a következő esetben (ámbár nem ajánlott

// ciklusváltozót egyszerre két helyen változtatni!):

for (int a = 0; a < 5; a++)

Console.WriteLine(a++);


F ggv nyek haszn lata rt k visszaad sa n lk l

Függvények használata érték visszaadása nélkül

  • public static void change(int b)// void szerepe !!

  • {

  • b = 5;

  • }

  • static void Main()

  • {

  • int a = 0;

  • change(a);

  • Console.WriteLine(a);// hívás után is a==0marad

  • }


Egy rt k visszaad sa a met dus nev ben

Egy érték visszaadása a metódus nevében

  • public static int change(int b)// int szerepe !!

  • {

  • b = 5;

  • return b;

  • }

  • static void Main()

  • {

  • int a = 0; int c;

  • c = change(a);

  • Console.WriteLine(c);// c==5 lesz

  • }


Param ter tad s ref seg ts g vel

Paraméterátadás ref segítségével

  • public static void change(ref int b)

  • {

  • b = 5;

  • }

  • static void Main()

  • {

  • int a = 0;// ha hívás előtt ‘a’ nem kapna értéket, az hiba!

  • change(ref a);

  • Console.WriteLine(a);// a==5

  • }


Param ter tad s out seg ts g vel

Paraméterátadás out segítségével

  • public static void change(out int b)

  • {

  • b = 5;

  • }

  • static void Main()

  • {

  • int a; // = 0; nem muszáj, hogy ‘a’ értéket kapjon!

  • change(outa);

  • // a==5, még akkor is, ha az előző sorban a értéket kapna

  • Console.WriteLine(a);

  • }


Egydimenzi s t mb

Egydimenziós tömb

  • int[] itomb;// deklarálás

  • itomb = new int[3] { 0, 1, 2 };// inicializálás

  • for (int i = 0; i < itomb.Length; i++) Console.WriteLine(itomb[i]);

  • int[] itomb= new int[3] { 0, 1, 2 };

  • // a deklarálás és az inicializálás össze is vonható


Egydimenzi s t mb tlaga

Egydimenziós tömb átlaga

  • public static double atlag(double[] vektor) {

  • double s = 0.0;

  • for (int i = 0; i < vektor.Length; i++) s += vektor[i];

  • return s/vektor.Length;

  • }

  • public static void Main(){

  • double[] tomb = new double[] { -4.11, 1.23, 2.14 };

  • Console.WriteLine(atlag(tomb)); // - 0,246..

  • Console.ReadKey(); // várakozás

  • }


Aao

Írjunk egy függvényt, amely nullára cseréli egy tömb ama elemeit, melyek abszolút értéke egy paraméternél nagyobb

  • public static double atl_csere(ref double[] vektor, double eps) {

  • double s = 0.0;

  • for (int i = 0; i < vektor.Length; i++) s += vektor[i];

  • s = s/vektor.Length;// átlagszámítás

  • for (int i = 0; i < vektor.Length; i++) // csere, ha kell

  • if ((vektor[i] >eps) || (vektor[i] < -eps)) vektor[i] = 0;

  • return s;// a „régi átlag” visszaadása

  • }


S a f program

…és a főprogram

  • public static void Main() {

  • double[] tomb;double eps = 5.1;

  • tomb = new double[] { -4.11, 1.23, 20.14 };

  • Console.WriteLine(atl_csere(ref tomb,5));

  • for (int i = 0; i < tomb.Length; i++) Console.WriteLine( tomb[i]);// „új” tömb

  • Console.ReadKey(); // várakozás

  • }

  • // a ref ebben az esetben mellőzhető!

A tömbök tárgyalására visszatérünk!


Nem egydimenzi s t mb k

Nem-egydimenziós tömbök

  • A nem-egydimenziós tömbökkel a későbbiekben részletesen fogunk foglalkozni!


Egy n elem sorozat csupa 0 b l s 1 b l ll rendezz k n 1 sszehasonl t ssal

Egy n elemű sorozat csupa 0-ból és 1-ből áll. Rendezzük n-1 összehasonlítással!

int i; int[] b = { 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0 };

for (i = 0; i < b.Length; i++) Console.Write(b[i] + " ");

Console.WriteLine();

int n = b.Length; int[] b1 = new int[n]; // b1 segédtömb

for (i = 0; i < b.Length; i++) b1[i] = 0; // kinullázzuk a segédtömböt

for (i = 0; i <= b.Length - 1; i++)

if (b[i] == 1) b1[--n] = 1;// fontos, hogy --n és nem n--

for (i = 0; i < b.Length; i++) Console.Write(b1[i] + " ");

Console.ReadLine();


Egy n elem sorozat csupa 0 b l s 1 b l ll rendezz k sszehasonl t s n lk l

Egy n elemű sorozat csupa 0-ból és 1-ből áll. Rendezzük összehasonlítás nélkül!

int szum = 0, i = 0;

int[] b = { 0,0,1,0,1,1,0,0,1,0,1,0,0,1,1,0 };

// megszámoljuk, hány 1-es van

for (i = 0; i < b.Length; i++) szum += b[i];

// b „elejét” kellő számú nullával feltöltjük

for (i = 0; i < b.Length - szum; i++) b[i]=0;

// b „végét” feltöltjük annyi 1-essel, amennyivel kell

for (int j= i; j < b.Length; j++) b[j] = 1;


A k t megold s sszehasonl t sa

A két megoldás összehasonlítása

  • Az első változatban kellett egy n hosszú ciklus és n-1 összehasonlítás, valamint még egy tömb

  • A második változatban nem kellett összehasonlítás és extra tömb


Geometriai feladat

Geometriai feladat

Legyen adott egy konvex sokszög a síkban, csúcsainak koordinátáival, melyek óramutató járása szerinti bejárási tömbben adottak egy tömbben:

x0 y0 x1 y1 x2 y2 …..

Számítsuk ki a sokszög kerületét és területét!


A ker letsz m t s eleje

A kerületszámítás eleje

Az egyik pont (x,y), a másik (xx,yy)

koordinátájú

A távolságot számító függvény:

public static double tav(double x, double y, double xx, double yy)

{

return Math.Sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));

};


K zepe a main belseje

Közepe (a Main() belseje)

// példaadatok

double[] tomb = new double[] { 1.0, 0.0, 0.0, 2.0, -1.0, 0.0, 0.0, -3.0 };

double x, y, xx, yy, d = 0.0; int i, n=tomb.Length;

// a kód

for (i = 0; i+3 < n; i=i+2)

{ // végig a pontokon

x = tomb[i]; y = tomb[i+1];

xx = tomb[i+2]; yy = tomb[i+3];

d += tav(x, y, xx, yy);

}

d += tav(tomb[0], tomb[1], tomb[n - 2], tomb[n - 1]);


H romsz g ter lete heron k plettel

Háromszög területe Heron képlettel

A 3szög pontjai (x1,y1), (x2,y2), (x3,y3)

public static doubleheron(double x1, double y1, double x2,

double y2, double x3, double y3){

double s, d1, d2, d3 ;

d1 = Math.Sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));

d2 = Math.Sqrt((x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3));

d3 = Math.Sqrt((x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3));

s = (d1 + d2 + d3) / 2.0;

return Math.Sqrt(s * (s - d1) * (s - d2) * (s - d3));

}


Konvex soksz g ter letsz m t sa

Konvex sokszög területszámítása

double[] tomb = new double[] { 1.0, 0.0, 0.0, 2.0, -1.0, 0.0, 0.0, -3.0 };

double x, y, x1, y1, x2,y2, h = 0.0;

int n = tomb.Length;

x = tomb[0]; y = tomb[1];

for (int i = 2; i +3 < n; i = i+2)

{

x1 = tomb[i]; y1 = tomb[i+1];

x2 = tomb[i+2]; y2 = tomb[i+3];

h += heron(x, y, x1, y1, x2,y2);

}

Console.WriteLine("terulet: " + h);

Koordinátatömbbeli indexek


Mi rt kell a konvexit s

Miért kell a konvexitás?

Amit számítunk:

T=(sárga+lila+kék)+(lila+kék)

+(lila+barna)

Helyesen:

T=(sárga+lila+kék)-(lila+kék)

+(lila+barna)=sárga+lila+barna

A konvexitás biztosítja, hogy a

területek összeadhatók!


Legnagyobb k z s oszt 1

Legnagyobb közös osztó 1.

  • public static int euklidesz(int a, int b)

  • {

  • int t,a1,b1;

  • a1 = Math.Max(a, b);// kell-e ez a sor ?!

  • b1 = Math.Min(a, b); // kell-e ez a sor ?!

  • while (a1 != b1)

  • {

  • if (a1 > b1) a1 = a1 - b1;

  • else { t = a1; a1 = b1; b1 = t; }

  • }

  • return a1;

  • }


Legnagyobb k z s oszt 2

Legnagyobb közös osztó 2.

public static int gcd(int a, int b) {

int t=0;

while (b != 0) {

  • Console.WriteLine("t= " + t +" a= " + a + " b= " + b);

    t = b; b = a % b; a = t;

    }

    Console.WriteLine("t= " + t + " a= " + a + " b= " + b);

    return a;

    }

Hívás gcd(6,10)


Legnagyobb k z s oszt 3

Legnagyobb közös osztó 3.

functiongcd(a, b)

ha b = 0 return a

egyébkéntreturngcd(b, a mod b)

Pszeudokódban

public static int gcd(int a, int b)

{

return ( b == 0 ? a : gcd(b, a % b) );

}

Rekurzív C# algoritmus


Horner s ma egy polinom adott x helyen vett rt k nek gyors kisz m t s ra

Horner séma egy polinom adott x helyen vett értékének gyors kiszámítására

Példa egy harmadfokú polinomra:

P(x)=7x3 – 2x2 + 5 x - 8 =

(7x2 – 2x + 5) x - 8=

((7x-2) x +5) x - 8

Az együtthatókat jelöljük:

a[3] = 7 a[2]= - 2 a[1]= 5 a[0]= - 8

n=3;

POL= a[n];

for(i=n-1; i>=0; i--) POL = POL*x + a[i];

A szorzások száma 3+2+1, ált esetben O(n*n)

A szorzások száma 3, ált esetben O(n)


A fibonacci sorozat

A Fibonacci sorozat

  • A Fibonacci számsorozatban minden szám az első kettő után - az azt megelőző kettő összege. Így tehát a számsorozat: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233 stb. Minél későbbi tagjait vesszük a sorozatnak, két egymást követő szám aránya annál inkább az aranymetszéshez fog közelíteni (ami megközelítőleg 1:1,618 vagy – ami ezzel közelítőleg egyenlő -0,618:1)


Kisz m t s rekurz van

Kiszámítás rekurzívan

public static int fibo(int i){

if (i == 0) return 0;

else if (i == 1) return 1;

else return fibo(--i) + fibo(--i);

}

Beugrató kérdés:

Ez ugyanaz-e, mint

return 2*fibo(--i) ?

return fibo(i-1) + fibo(i-2);

A Fibonacci számok gyorsan nőnek, a long indokolt lehet


Fibonacci t mbbel

Fibonacci tömbbel

int i, n;

Console.Write("n= ");

n = int.Parse(Console.ReadLine());

long[] f = new long[n];// Fibonacci számok gyorsan nőnek

f[0]=0; f[1]=1;

for( i=2;i<n; i++) f[i]= f[i-1]+f[i-2];


Fibonacci arraylist tel

Fibonacci ArrayList-tel

int i=0, value=0;

Console.Write(„Keressük az első Fibonacci számot, amely nagyobb mint: ");

int n = int.Parse(Console.ReadLine());

ArrayList fiblist = new ArrayList();

fiblist.Add(0); fiblist.Add(1);

for (i = 2; value <= n; i++) {

int[] tomb = new int[fiblist.Count];

fiblist.CopyTo(tomb);

value = tomb[i - 1] + tomb[i - 2];

fiblist.Add(value);

}

Console.WriteLine(n+" . fibo= " + fiblist[--i]);


Volt e sz ks g menetk zben mindegyik fibonacci sz mra

Volt-e szükség menetközben mindegyik Fibonacci számra?

  • Ha a feladat úgy szól, hogy olvassunk be egy n számot, és ha az első n-nél nagyobb Fibonacci szám 5-tel osztható, akkor írjuk ki az eddigi Fibonacci számok számtani közepét, egyéb esetben pedig a mértani közepét, akkor szükség van az összes korábbi Fibonacci számra (avagy mégsem??)

  • De ha csak az aktuális Fibonacci szám kell, akkor van a tömbhasználatnál egyszerűbb megoldás. A rekurzió, vagy…


Fibonacci seg dv ltoz kkal

Fibonacci segédváltozókkal

  • int i = 0, seged0 = 0, seged1 = 1, f=0;

  • Console.Write("Keressük az n-dikFibonacci számot, ahol n= ");

  • int n = int.Parse(Console.ReadLine());

  • if (n == 0) Console.WriteLine("A válasz 0");

  • else if (n==1) Console.WriteLine("A válasz 1");

  • else{

  • for (i = 2; i <= n; i++) {

  • f =seged0 + seged1;

  • seged0 = seged1;

  • seged1 = f;

  • }

  • Console.WriteLine("f= "+f);

  • }

Gyors és memóriatakarékos!

Csak a legutolsó Fibonacci számot adja meg.


Fibonacci z rt alakban a k plet

Fibonacci zárt alakban – a képlet

Ekkor c0=0, c1=1, és n >=1 esetén

(teljes indukcióval belátható)

Fentiekből következik, hogy cn a Fibonacci sorozat!!!


Fibonacci z rt alakban a program

Fibonacci zárt alakban – a program

int fib;

Console.Write("Hanyadik Fibonacci számot számítsuk: ");

double n = double.Parse(Console.ReadLine());

double gyot =Math.Sqrt(5.0);

fib = (int)Math.Truncate(

(1.0/gyot)*(Math.Pow(((1.0+gyot)/2.0),n)-

Math.Pow(((1.0-gyot)/2.0),n)

)

);

Console.WriteLine("Az eredmény:"+fib);

Duplapontos szám egész részét számolja (kihagyható)


Rendez sek

Rendezések

  • A rendezési algoritmus olyan algoritmus, amely egy lista vagy egy tömb elemeit egy meghatározott (növekvő vagy csökkenő) sorrendbe helyezi el.

  • A rendezés lehet numerikus és lehet lexikografikus.

  • A rendezés legtöbbször azért szükséges, hogy utána könnyebben lehessen keresni.

  • Ezentúl, szűkebb értelemben vett rendezés alatt egy olyan algoritmust fogunk érteni, melynek inputja egy egészeket tartalmazó számsorozat, outputja a számsorozat növekvő sorrendben.

  • Az output mindig egy permutációja az inputnak.


A rendez si algoritmusok oszt lyoz sa

A rendezési algoritmusok osztályozása

  • Egy n elemű tömb esetében a szükséges összehasonlítások száma szerint

  • Általános esetben (mi is az általános eset ?!) O(n*log n)összehasonlításnál kevesebb nem elég

  • Számos ismert esetben (példák jönni fognak) O(n*n) összehasonlítás szükséges

  • Néhány igen speciális esetben (legutóbb tárgyalt eset, ahol csak 0 és 1 szerepelt) O(n) is elég

  • Az O (ordó) jelölés magyarázatát ld. az Analízis tárgyban, vagy a következő dián:


Ord ord

Ordó, ordó

  • Legyen f és g két, természetes számokon értelmezett, nem-negatív, valós értékű függvény. Vezessük be a következő jelöléseket:

  • f=O(g), (f=nagy Ordó g) ha van olyan c>0 konstans, hogy minden elég nagy n-re f(n) ≤ c*g(n)

  • f=o(g), (f=kis ordó g) ha g(n) csak véges sok ehlyen nulla, és f(n)/g(n)→0, ha n →∞

  • f=Ω(g), ha g=O(f). (ritkán használatos)

  • f=Θ (g), ha f=O(g) és g=O(f), azaz vannak olyan c1,c2 konstansok, hogy minden elég nagy n-re

  • c1g(n) ≤ f(n) ≤c2g(n)

  • Az egyenlőség nem szimmetrikus, pl. O(n)=O(n2), ez ugyanis azt jelenti, hogy f=O(n) esetén f=O(n2) is fennáll, defordítva ez nem igaz: O(n2) ≠O(n)


Tov bbi szempontok

További szempontok

  • Szokás vizsgálni a cserék (swap) számát is.

  • Legyen a és b egészek. Cseréljük ki az értéküket!

  • { int kesztyu = a; a = b; b = kesztyu; }

  • Vizsgálható a memória takarékosság, vannak „helyben” rendező algoritmusok, és vannak olyanok, amelyek segéd tárterületeket igényelnek.

  • Vannak rekurzív és nem rekurzív rendezések.


Stabilit s

Stabilitás

  • Stabil rendezésnél az azonos kulcsú rekordok relatív sorrendje megmarad, nem stabil rendezésnél változhat.

  • Tekintsünk egész koordinátájú pontokat a síkban, és bocsássunk merőlegeseket az x-tengelyre. Legyen az a feladat, hogy az így keletkezett szakaszokat rendezni kell az x-tengelyen vett koordinátájuk szerint. Nevezzük az x-koordinátákat kulcsnak. Eszerint történnek az összehasonlítások, de csere esetén a teljes szakaszt (azaz pontpárt) kell cserélni.

  • Legyen a pontsorozat (4, 2) (3, 7) (3, 1) (5, 6)

  • Két sorrend is létrejöhet, ha vannak azonos x-koordinátájú (x=3) pontok:

  • (3, 7) (3, 1) (4, 2) (5, 6) (eredeti sorrend marad, ez a stabil)

  • (3, 1) (3, 7) (4, 2) (5, 6) (eredeti sorrend változik)


Bubor krendez s

Buborékrendezés

  • A buborék rendezés a legrosszabb esetben (amikor az elemek csökkenő sorrendben vannak) valamint az átlagos esetben (amikor az elemek véletlenszerűen helyezkednek el) is O(n*n) komplexitású. Mivel sok O(n*log n) komplexitású rendezés van, nagy n esetén a buborék nem előnyös, kivéve, ha az elemek nagyjából eleve növekvően rendezettek.


Bubor k 1 a legnagyobb elem felsz ll

Buborék 1. (a legnagyobb elem „felszáll”)

public static void bubbleSort(int[] A) {

bool csereltunk; int i, kesztyu;

do {

csereltunk = false;

for (i = 0; i < A.Length - 1; i++) {

if (A[i] > A[i + 1]) {

kesztyu = A[i]; A[i] = A[i + 1]; A[i + 1] = kesztyu;

csereltunk = true;

}

}

} while (csereltunk);

} // nem ad visszajelzést, ha a tömb 0 vagy 1 hosszú


Bubor k 1 f program

Buborék 1. főprogram

// példának okáért rendezzünk 10 véletlen generált egész számot

static void Main() {

int[] A = new int[10]; int i;

Random RandomClass = new Random();

for (i = 0; i < A.Length; i++) {

A[i] = RandomClass.Next(10, 30);

Console.Write(A[i] + " ");

}

Console.WriteLine();

bubbleSort( A );

for (i = 0; i < A.Length; i++) Console.Write(A[i] + " ");

Console.ReadLine();

}


Bubor k 2 a lgkisebb elem lesz ll

Buborék 2. (a lgkisebb elem „leszáll”)

public static void bubbleSort(int[] A) {

if (A.Length == 0) Console.WriteLine("A tömb üres!");

else if (A.Length == 1) Console.WriteLine("A tömb 1 elemű!");

else

{

int i, j, kesztyu;

for (i = 0; i < A.Length - 1; i++)

for (j = A.Length - 1; j > i; j--)

if (A[j – 1] > A[j])

{ kesztyu = A[j]; A[j] = A[j - 1]; A[j - 1] = kesztyu; }

}

}


K tir ny bubor k cocktail sort

Kétirányú buborék – cocktail sort

bottom = 0; top = n-1; bool csere_volt = true;

while (csere_volt == true){

csere_volt = false;

for (i = bottom; i < top; i++)

if (a[i] > a[i + 1]) { csere_volt= true;

kesztyu = a[i]; a[i]=a[i+1]; a[i+1]=kesztyu; }

top = top - 1;

for (i = top; i > bottom; i--)

if (a[i] < a[i - 1]){ csere_volt = true;

kesztyu = a[i]; a[i] = a[i-1]; a[i-1] = kesztyu; }

bottom = bottom + 1;

}


Aao

  • 2, 3, 4, 5, 1 sorozatnál „felszálló buborék” 4 menetet csinál, a „leszálló buborék” egyet

  • 5, 1, 2, 3, 4 sorozatnál fordítva

  • A kétirányú buborék mindkét esetben egy menetet csinál, igaz; egy menet két ciklust igényel

  • Nagyságrendileg a cocktail is O(n*n)


Kerti t rpe rendez s c

Kerti törpe rendezés (C#)

i = 1;

while (i < n) {

if (a[i - 1] <= a[i]) i++;// ha jó a sorrend, előre!

else {

int kesztyu = a[i - 1]; a[i - 1] = a[i]; a[i] = kesztyu;

i--;

if (i == 0) i = 1;

}// else vége

} // while vége


Hogyan m k dik

Hogyan működik?

  • Az algoritmus megkeresi az első olyan helyet, ahol két egymást követő elem rossz sorrendben van, és megcseréli őket. Ha egy ilyen csere után rossz sorrend keletkezik, az csak közvetlenül a legutolsó csere előtt lehet, így ezt is ellenőrizzük.

  • Talán ez az elképzelhető legegyszerűbb rendezés.


A bubor k l nyeges jav t sa f s s rendez s

A buborék lényeges javítása: fésűs rendezés

  • A fésűs rendezést (combsort) eredetileg 1980-ban tervezték, majd újra felfedezték és 1991-ben publikálták a Byte magazinban. A buborék rendezés módosítása, sebességében közelít a híres quicksorthoz. Az alapötlet az, hogy a sorozat végén levő kicsi értékekre találjunk rá minél hamarabb, mert ezek lassítják jelentősen a buborékot. (A sorozat elején levő nagy értékek nem annyira lassítóak, mert ezekre hamar rátalálunk).


A f s k dja

A fésű kódja

public static void combSort(int[] A) {

int i;

if (A.Length == 0) Console.WriteLine("A tömb üres!");

else if (A.Length == 1) Console.WriteLine("A tömb egyelemű!");

else {

int gap = A.Length, cserevolt = 0, kesztyu;

while ((gap >1) || (cserevolt !=0)) {

if (gap > 1) // gap /1.3 lefelé kerekítve

gap = (int)Math.Truncate((double)gap / 1.3);

if ((gap == 10) || (gap == 9)) gap = 11;

i = 0; cserevolt = 0;

while (i + gap < A.Length) {

if (A[i] > A[i+gap]){

kesztyu = A[i]; A[i]=A[i+gap]; A[i+gap] = kesztyu;

cserevolt = 1;

}

i++;

}

}

}

}


Megjegyz sek

Megjegyzések

  • 10 ezer elemű tömbön végzett kísérletek szerint a fésűs rendezés alig rosszabb a quicksortnál (10 %-kal); a változtatás a buborékhoz képest nem nagy.

  • Ugyanakkor nem kell gondoskodni az eleve rendezett esetről, ami a quicksortot nagyon lelassítja (látni fogjuk).

  • A gap beállításával először a távollevő elemeket rendezzük. Ezután a gap csökken, míg végül egy lesz. Ez esetben azonos a program a buborékkal; következésképpen korrekt.

  • Lacey és Richard Box megmutatták, hogy a gap minden lépésben 1.3-mal osztandó. Továbbá felfedezték, hogy 9 és 10 nem alkalmas gap-nek, és 11-gyel helyettesítendő.


Combsort versus quicksort

Combsort versus quicksort

10 ezer egész szám rendezési kísérletének időeredményei

Forrás:http://www.yagni.com/combsort/index.php [2008. nov. 16.]


Quicksort rekurz van

Quicksort -rekurzívan

static void csere( ref int x, ref int y) { int t= x; x = y; y = t; }

// a baloldali elemet a helyére teszi és visszaadja a hely indexét

static int partition(int[] a, int first, int last) {

int pivot = a[first], lastS1 = first, firstUnknown = first + 1;

while (firstUnknown <= last) {

if (a[firstUnknown] < pivot) { lastS1++; csere( ref a[firstUnknown], refa[lastS1]); }

firstUnknown++;

}

csere( ref a[first], ref a[lastS1]);

return lastS1;

}

static void quicksort(int[] a) { quicksort(a, 0, a.Length - 1); }

static void quicksort(int[] a, int first, int last) {

if (first < last) {

int pivotIndex = partition(a, first, last);

quicksort(a, first, pivotIndex - 1);

quicksort(a, pivotIndex + 1, last);

}

}


Minimum kiv laszt sos rendez s

Minimum kiválasztásos rendezés

static void csere(ref int x, ref int y) { int cs =x; x=y; y=cs; }

static void Main()

{ int i,min, n = 10;

int[] a = new int[n];

Random RandomClass = new Random();

for (i = 0; i < n; i++) a[i] = RandomClass.Next(10, 26);

for (i = 0; i < n; i++) {

min = i;

for (int j = i + 1; j < n; j++)

if (a[j] < a[min]) min = j;

csere(ref a[i], ref a[min]);

}

}


Besz r sos rendez s

Beszúrásos rendezés

static void csere(ref int x, ref int y) { int cs =x; x=y; y=cs; }

static void Main()

{ int i,j, n = 10;

int[] a = new int[n];

Random RandomClass = new Random();

for (i = 0; i < n; i++) a[i] = RandomClass.Next(10, 26);

for (i = 1; i < n; i++) {

j = i - 1;

while ((j> -1) && (a[j] > a[j+1])) {

csere(ref a[j], ref a[j+1]);

j--;

}

}

}


Sorting demo

Sorting demo

  • http://www.cs.ubc.ca/~harrison/Java/sorting-demo.html


V d rrendez s

Vödörrendezés

// a 0 és M intervallumba eső elemek rendezése

const int darab = 60; // rendezendő elemek száma

const int M = 100; // maximum érték

const int vödörszám = 10;

int vödör_range = M / vödörszám;

// a rendezendő sorozat véletlen generálása és kiíratása

int i,j;

int[] a = new int[darab];

Random r = new Random();

for (i = 0; i < a.Length; i++) a[i] = r.Next(M);

for (i = 0; i < a.Length; i++)Console.Write(" " + a[i]);

Console.WriteLine();


A t mb t sz tszedj k v dr kre

A tömböt szétszedjük vödrökre

// listatömb deklarációja

ArrayList[] array = new ArrayList[vödörszám];

for (i = 0; i < array.Length; i++)

array[i] = new ArrayList();

// a tömböt szétszedjük vödrökre (=listákra)

for (i = 0; i < a.Length; i++)

{

j = a[i] / vödör_range;// a[i] a j-dik vödörbe esik

array[j].Add(a[i]);// a[i]-t betesszük a j-dik vödörbe

}


A list k rendez se egyenk nt

A listák rendezése egyenként

for (i = 0; i < array.Length; i++)

{

Console.WriteLine(i + " . lista= ");

// a listákat egyenként rendezzük

for (j = 0; j < array[i].Count; j++) array[i].Sort();

// és kiírjuk a demo kedvéért

for (j = 0; j < array[i].Count; j++)

Console.Write(" " + array[i][j]);

Console.WriteLine();

}


Befejez s

Befejezés

// átmásoljuk a vödröket egyetlen listába

ArrayList egylista = new ArrayList();

for (i = 0; i < array.Length; i++)

for (j = 0; j < array[i].Count; j++)

egylista.Add(array[i][j]);

// az egyesített listát visszaírjuk a tömbbe

egylista.CopyTo(a);

// és kiírjuk a rendezett tömböt

for (i = 0; i < a.Length; i++)

Console.Write(" " + a[i]);


Halmazm veletek metszet

Halmazműveletek: metszet

A feladat most két tömb a[0..n-1] és b [0..m-1] azonos elemeinek kiválogatása c tömbbe. A feladat csak úgy értelmezhető pontosan, ha az egyes tömbökben egy elem nem szerepel kétszer. (Mivel most a matematikai halmazokat tömbként ábrázoljuk.) Az algoritmus lényege: menjünk végig az a tömb elemein, és válogassuk ki azokat (kiválogatás), melyek szerepelnek b-ben (eldöntés). Így a feladat a korábbi tételekre visszavezethetõ. cmaximális elemszáma n és m közül a kisebbik.

Feltételeztük, hogy egyik halmaz sem üres.


Deklar ci k a metszethez c

Deklarációk a metszethez C#

int n = 10, m=6, db =Math.Min(n,m); // tömbméretek

int i,j,k; // ciklusváltozók

int[] a = new int [n]; // a halmaz elemei 0..n-1

int[] b = new int [m]; //b halmaz elemei 0..m-1

int[] c = new int [db]; // a metszet elemei

// db csak a maximális lehetséges tömbméret. Ha a metszet

// üres, akkor nyilván nincs elem a metszetben.


Metszet c k d

Metszet C# kód

Az if NINCS a ciklusban, mert a for törzse üres!

k = 0;

for (i=0; i<n;i++)

{

for(j=0; (j<m) && (b[j] != a[i]); j++); // amíg j<m és b[j]<>a[i]

if (j<m) c[k++]=a[i]; // ha j=m, akkor a[i] nem szerepelt b-ben

// ha j<m, akkor a[i] előfordult b-ben

}

for (i = 0; i < k; i++) Console.WriteLine(c[i]); // kiíratás


Halmazm veletek uni

Halmazműveletek: unió

A feladat most két tömb a[0..n-1] és b [0..m-1] elemeinek egyesítése c tömbbe. Az egyes tömbökben egy elem nem szerepel kétszer. (mint az előbb)

A legkézenfekvőbb megoldás: tegyük be c-be a összes elemét, majd b-ből azokat, melyek nem szerepelnek a-ban. c elemszáma legfeljebbn+m.

Feltételeztük, hogy egyik halmaz sem üres.


Uni c k d

Unió C# kód

for (i = 0; i < n; i++) c[i] = a[i];//a-t áttöltjük c-be

k = n;

for (j = 0; j < m; j++){

// keressükazt a b-belit, ami nincs a-ban

for (i = 0; (i< n) && (b[j] != a[i]); i++) ;

if (i >= n) c[k++] = b[j];// ha volt ilyen, c-be teszzük

}

for (i = 0; i < k; i++) Console.WriteLine(c[i]);

// Futásidő n*m nagyságrendű!


Uni speci lis esetben c az a s b halmazokat reprezent l t mb k rendezettek sszefuttat s

Unió speciális esetben (C#): az a és b (halmazokat reprezentáló) tömbök rendezettek (összefuttatás)

Csak az egyik fut!

  • i = 0; j = 0; k = 0;

  • while(( i < n) && ( j < m))

  • if (a[i]<b[j]) c[k++] = a[i++];

  • else if (a[i]==b[j]) {c[k++]= a[i++]; j++;}

  • else c[k++] = b[j++];

  • for (x=i; x<n; x++) c[k++] =a[x];

  • for (x=j; x<m; x++) c[k++] =b[x];

  • for (i = 0; i < k; i++) Console.WriteLine(c[i]);

  • // Futásidő n+m nagyságrendű, n*m helyett (előző)!


Rekurz v bin ris keres s rendezett t mbben

Rekurzív bináris keresés (rendezett tömbben)

public static int binker(int[] tomb, int value, int low, int high)

{

if (high < low) return -1;

int mid = (low + high) / 2;

if (tomb[mid] > value) {

mid--;

return binker(tomb, value, low, mid);

}

else if (tomb[mid] < value) {

mid++;

return binker(tomb, value, mid, high);

}

else return mid;

}


Iterat v bin ris keres s rendezett t mbben

Iteratív bináris keresés (rendezett tömbben)

public static int binker(int[] tomb, int value) {

int mid, low = 0, high = tomb.Length-1;

while (low <= high) {

mid = (low + high) / 2;

if (tomb[mid] > value) high = --mid;

else if (tomb[mid] < value) low = ++mid;

else return mid; // megtalálva

}

return -1; // nincs meg

}


D inamikus program oz s

Dinamikus Programozás


M trix ok l ncszorz sa

A dinamikus programozás egy általános eljárás bizonyos problémák megoldására

Példa:

Mátrixok láncszorzása

Hogyan szorzunk mátrixokat.

C = AB

Aisd × e,Bise × f

O(d*e*f)időben

f

B

j

e

e

A

C

d

i

i,j

d

f

Mátrixok láncszorzása


M trixok l ncszorz sa

Kiszámítandó A = A0A1…An-1

Aimérete di ×di+1

Probléma: Hogyan zárójelezzünk? Az eredménynek mindegy, mert a szorzás asszociatív, de a műveleti sebesség nagyon eltérhet!

Example

B mérete 3 × 100

C mérete 100 × 7

D mérete 7 × 5

(BC)D3×100×7 + 3×7×5 = 2305szorzás

B(CD)3×100×5 + 100×7×5 = 5000 szorzás

Mátrixok láncszorzása


A brut lis m dszer

Mátrix láncszorzás:

Próbáljuk megkeresni az összes zárójelezését A=A0A1…An-1-nak

Mindegyikre számítsuk ki a műveletek számát

Válasszuk ki a legjobbat

Futásidő:

Zárójeléezések száma = n-csúcsú bináris fák száma

Exponenciális!

Ez az n-dik Catalan szám – nagyságrendileg 4n.

Kiszámíthatatlan !

A „brutális” módszer


A moh megk zel t s

Ötlet #1: mindig azt a szorzatot válasszuk, amelyik a legkevesebb műveletet igényli

Ellenpélda arra, hogy a fenti ötlet optimális lehetne:

A mérete 101 × 11

B mérete 11 × 9

C mérete9 × 100

D mérete100 × 99

Az ötlet szerint legjobb A((BC)D)

109989+9900+108900=228789 szorzás

Ennél jobb: (AB)(CD)

9999+89991+89100=189090 szorzás

A mohó megközelítés

AB 101*11*9=9999

BC 11*9*100=9900

CD 9*100*99=89100

A(BC) 101*11*100=111100

(BC)D 11*100*99=108900


A r e k ur z v megk zel t s

A “rekurzív” megközelítés

  • Definiálunkalproblémákat:

    • Keressük meg a legjobb zárójelezését ennek: AiAi+1…Aj.

    • Legyen Ni,j = ezen részprobléma műveleti igénye.

    • A teljes probléma optimális megoldása N0,n-1.

  • Részprobléma optimalitás: Az optimális megoldás az optimális részprblémák függvényében lesz definiálva

    • Kell, hogy legyen egy utoljára végrehajtott szorzás az optimális megoldásban (ez a bináris fa gyökere)

    • Mondjuk, hogy ez az i indexnél volt: (A0…Ai)(Ai+1…An-1).

    • Ekkor az optimális megoldás N0,n-1 ia két optimális részmegoldás, N0,iés Ni+1,n-1 összege, valamint az utolsó szorzás


A karakterisztikus egyenlet

A karakterisztikus egyenlet

  • A globális optimum az optimális részproblémáktól, valamint az utolsó szorzás helyétől függ

  • Vizsgáljunk meg minden lehetséges helyet az utolsó szorzásra:

    • Tudjuk, hogy Aimérete di× di+1

    • Így a karakterisztikus egyenlet Ni,j–re a következő alakú:

  • Az alproblémák nem függetlenek, azalproblémák átfedik egymást.


A dinamikus programoz si algoritmus

A dinamikus programozási algoritmus

  • Nem használunk rekurziót, mivel az alproblémák átfedik egymást

  • helyette “bottom-up” módon alproblémákkal foglalkozunk

  • Ni,iszámítása könnyű, ezért ezzel kezdünk

  • Ezután 2,3,… hosszú alproblémákkal foglalkozunk

  • A futási idő: O(n3)

AlgorithmmatrixChain(S):

Input:ndb összeszorzandó mátrix

Output:a szorzások optimális száma

fori 1 to n-1 do

Ni,i  0

forb 1 to n-1 do

fori 0 to n-b-1 do

j  i+b

Ni,j  +

fork i to j-1 do

Ni,j  min{Ni,j , Ni,k +Nk+1,j +di dk+1 dj+1}


Aao

A válasz

Az algoritmus magyarázata

  • A bottom-up konstrukció feltölti az N tömböt az átlók mentén

  • Ni,jaz i-dik sor és a j-dik oszlop korábban kiszámított értékeiből számítódik

  • A táblázat egy eleme O(n) idő alatt tölthető ki

  • A teljes idő O(n3)

  • A zárójelezéshez az kell, hogy „k” értékére „emlékezzünk” mindegyik esetben

N

n-1

0

1

2

j

0

1

i

n-1


A l ncszorz si algoritmus

Példa: ABCD

A mérete 10 × 5

B mérete 5 × 10

C mérete 10 × 5

D mérete 5 × 10

A láncszorzási algoritmus

AlgorithmmatrixChain(S):

Input:ndb összeszorzandó mátrixOutput:# szorzások optimális száma

fori0to n-1 do

Ni,i0

forb 1 to n-1 do // b is # of ops in Sfori 0 to n-b-1 do

ji+b

Ni,j+infinity

forkito j-1 do

sum =Ni,k +Nk+1,j +di dk+1 dj+1

if (sum < Ni,j) then

Ni,j sum

Oi,j  k

return N0,n-1

N

0 1 2 3

0

500

500

1000

0

0

0

2

A

AB

A(BC)

(A(BC))D

0

250

500

1

0

1

B

BC

(BC)D

500

2

0

0

C

CD

3

0

D


Aao

static void Main(string[] args) {

int[] d = { 10, 5, 10, 5, 10 }; int i, j, k, b, n = d.Length-1;

double sum = 0.0; const double v = 1.0 / 0; // végtelen

double[,] N = new double[n, n];

for(i=0;i<n;i++) N[i,i] = 0;

for(b=1;b<n;b++)

for (i = 0; i < n - b ; i++) {

j = i + b;

N[i,j] = v; // végtelen

for (k = i; k < j ; k++) {

sum = N[i, k] + N[k + 1, j] + d[i] * d[k + 1] * d[j + 1];

if (sum < N[i, j]) N[i, j] = sum;

}

}

for (i = 0; i < n; i++) {

for (j = 0; j < n; j++) Console.Write(N[i, j].ToString().PadLeft(6) );

Console.WriteLine();

}

Console.WriteLine("Az eredmény= " + N[0, n - 1]);

Console.ReadLine();

} // Main vége


Recovering operations

Example: ABCD

A is 10 × 5

B is 5 × 10

C is 10 × 5

D is 5 × 10

Recovering operations

// a zárójelezéshez

// mátrixlánc Ai-től Aj-ig

exp(i,j)

if (i=j) then// alapeset, 1 mátrix

return ‘Ai’

else

k = O[i,j]// piros értékek

S1 = exp(i,k)// 2 rekurzív hívás S2 = exp(k+1,j)

return ‘(‘ S1 S2 ‘)’

N

0 1 2 3

0

500

500

1000

0

0

0

2

A

AB

A(BC)

(A(BC))D

0

250

500

1

0

1

B

BC

(BC)D

500

2

0

0

C

CD

3

0

D


Aao

static string EXP(int i, int j, int[,] O) {

int k; string s1, s2;

if (i == j) return "A" + i.ToString();

else {

k = O[i, j]; s1 = EXP(i, k, O); s2 = EXP(k+1,j,O);

return "("+s1 + s2+")";

static void Main(string[] args) {

int[,] O = new int[n, n];

for(i=0;i<n;i++) N[i,i] = 0;

for(b=1;b<n;b++)

for (i = 0; i < n - b ; i++) {

j = i + b;

N[i,j] = v;

for (k = i; k < j ; k++) {

sum = N[i, k] + N[k + 1, j] + d[i] * d[k + 1] * d[j + 1];

if (sum < N[i, j]) { N[i, j] = sum; O[i, j] = k; }

}

Console.WriteLine("Az eredmény= " + N[0, n - 1]);

Console.WriteLine("A zárójelezés = " + EXP(0,n-1,O));

Console.ReadLine();

} // Main vége


Optimaliz l si probl m k

Egy optimalizálási problémában nemcsak egy megoldást, hanem a legjobb megoldást keressük

A mohó algoritmusfázisokban dolgozik. Minden egyes fázisban:

Tegyük azt, ami most a legjobb, nem törődve a jövővel.

Abban bízik a mohó, hogy a lokális optimumok sorozata globális optimumhoz vezet. (Néha ez a helyzet, lásd Kruskal algoritmus, PPT, jövő félév).

Optimalizálási problémák


Moh algoritmusok

Maximalizáljuk életünk örömeit:

Első algoritmus:élvezzük az életet naponta

Második algoritmus:dolgozz keményen, tanulj, szerezz diplomát, legyen jó fizetésű állásod, keress pénzt, és legyen jó nyugdíjad

Melyik algoritmus maximalizál a teljes életre?

Mohó algoritmusok


Ritka m trixok

Ritka mátrixok


Aao

Jelölje a fenti 10x8 –as mátrixot A. Összesen 7 nem nulla eleme van.


Aao

Sorok száma az eredeti A mátrixban

Oszlopok száma az eredeti A mátrixban

Jelölje RA a baloldali mátrixot. Tárigénye 8*3*4=96 byte.

Az előző dia A mátrixának tárigénye 10*8*4= 320 byte.

A két mátrix ugyanazt az információt hordozza!

Figyeljük meg, hogy RA sorai (a fejlécet nem beszámítva) rendezettek a sorok első mezői szerint, és azonos első mező esetén (5) a második mező szerint rendezettek.


Mi ennek a jelent s ge

Mi ennek a jelentősége?

  • Ha az A mátrix nagyon nagy (pl. 1000*1000 méretű), akkor tárolása gondot okozhat. Ha azonban a nem nulla elemek száma relatíve kicsi (mondjuk 100), és A-t átírjuk RA ritka mátrixos formába, akkor RA tárigénye 101*3*4 byte, szemben A tárigényével, ami 1000*1000*4 byte.

  • A „spórolást” úgy kaptuk, hogy a nullákat nem tároltuk, azaz megállapodtunk abban, hogy amit nem tárolunk, az nulla.


Norm l m trix a talak t sa ritka form tum v

normál mátrix (A) átalakítása ritka formátumúvá

static int[,] normal2ritka(int[,] A)

{

int i, j, t=0; int k=1; // a nulladikba a fejléc kerül

for (i = 0; i < A.GetLength(0); i++)

for (j = 0; j < A.GetLength(1); j++) if (A[i, j] != 0) t++;

int[,] R = new int[t + 1, 3];

R[0, 0] = A.GetLength(0); R[0, 1] = A.GetLength(1); R[0, 2] = t;

for (i = 0; i < A.GetLength(0); i++) {

for (j = 0; j < A.GetLength(1); j++)

if (A[i, j] != 0) {

R[k, 0] = i; R[k, 1] = j; R[k, 2] = A[i,j]; k++;

}

}

return R;

}

Figyeljük meg, hogy ebben az algoritmusban A elemein sorfolytonosan kell végigmenni, tehát ha A túl nagy és nem fér el a tárban, lehet szekvenciálisan eljárni!


Transzpon l s

Transzponálás

Egy mátrix transzponálása a főátlóra való tükrözést jelenti (komplex esetben konjugálni is szoktunk, de most vegyük csak a valós esetet). Jelölje B az A transzponáltját.

int[,] B = new int [A.GetLength(1),A.GetLength(0)];

for (i = 0; i < A.GetLength(0); i++)

{

for (j = 0; j < A.GetLength(1); j++)

B[j,i] = A[i, j];

}

Ha A nagyon nagy méretű, akkor ez az egyszerű algoritmus nem használható, mert például A nem fog elférni a tárban. Itt i és j „messze” lehet egymástól, a szekvenciális feldolgozás nem megy.


Aao

RA (A ritka mátrixos alakja)

Ez leírja A transzponáltját, de sajnos nem ritka mátrixos forma, mert hiányzik a rendezettség!


Aao

R ritka mátrix transzponáltjának (TR) előállítása: első módszer

int n = normal2ritka(A).GetLength(0); //A nem nulla elemeinek száma +1

int m = normal2ritka(A).GetLength(1); // m== 3

int[,] R = new int[n, m];

R = normal2ritka(A);

int[,] TR = new int[n, m];

TR[0, 0] = R[0,1]; TR[0, 1] = R[0,0];

TR[0, 2] = R[0, 2]; // TR[0,2]==n – 1== A nem nulla elemeinek száma

int q = 1;

for(j=1; j< R[0,1]; j++) // j A oszlopain megy végig

for (i = 1; i <= R[0, 2]; i++) // R sorain megy végig

if (R[i,1] == j) {

TR[q,0]=R[i,1];

TR[q,1]=R[i,0];

TR[q,2]=R[i,2];

q++;

}


Egy gyorsabb m dszer

Egy gyorsabb módszer

int[,] TR = new int[n, m];

TR[0, 0] = R[0,1]; TR[0, 1] = R[0,0]; TR[0, 2] = R[0, 2];

int darab = R[0,2]+1;

int[] s = new int[darab];

int[] t = new int[darab];

for (i = 0; i < darab; i++) s[i] = 0;

// összeszámoljuk, hogy melyik oszlopból mennyi van

for (j = 1; j <darab; j++) s[R[j, 1]]++;


Aao

int sum = 0; t[0] = 1;

// pozíciók előkészítése

for (j = 1; j < darab; j++) {

sum = sum + s[j - 1];

t[j] = sum + 1;

}

for (j=1;j<= R[0,2]; j++) {

TR[t[R[j, 1]], 0] = R[j, 1];

TR[t[R[j, 1]], 1] = R[j, 0];

TR[t[R[j, 1]], 2] = R[j, 2];

t[R[j, 1]]++;

}


  • Login