Korábban már megismertünk olyan összetett adatszerkezeteket, mint a tömb, lista vagy az összetett típusok (struktúra és osztály).
A fentiekkel ellentétben a következő adatszerkezetek bár a C# részei, de nem szerializálhatók automatikusan a Unity-ben. Ez azt jelenti, hogy a játék futása közben bármikor használhatók arra, hogy információkat tároljunk bennük, de arra nem, hogy [SerializeField] mezőként adatokat mentsünk benne.
Mátrix - A több dimenziós tömb
Létre tudsz hozni a következő módon olyan tömböket, amit nem csak 1, de több int számmal tudsz indexelni. Ezeket nevezzük más néven gyakran mátrixoknak.
// Indexelés:
array1 [1] = "alma";
matrix2 [1,0,2] = "banán";
matrix3 [1,0,2] = "citrom";Méret és rang lekérdezése
Egy 2D tömb kezelhető úgy mint egy “táblázat”, ahol a mátrix első dimenziója a sorok száma, a második pedig az oszlopoké. Persze mindez fordítva is elképzelhető. A mátrix értékei valójában nem a fizikai térben lesznek tárolva több dimenzióban, ez csak a vizualizálást tudja segíteni.
Végig-iterálás több dimnenziós mátrix elemein:
string[,] matrix2 = new string[10,10];
for(int i = 0; i < matrix2.GetLength(0); i++)
for(int j = 0; j < matrix2.GetLength(1); j++)
{
matrix2[i, j] = (i*j).ToString();
}
Unity-ben a több dimenziós tömböket használhatjuk például arra, hogy 2D vagy 3D térbeli adatokat tároljunk benne: Procedurálisan generált 2D négyzetrács vagy 3D voxel alapú játékok ideális példák lehetnek.
⚠️ A programozási mátrix fogalom nem összekeverendő a matematikai mátrix fogalommal ⚠️
(A lineáris matematika mátrixai szintén “táblázatok”, de mindig 2 dimenziósak és speciális mátrix műveletek értelmezettek rajtuk. Lásd: Transzformációs mátrixok (Hamarosan) )
Szerializálható mátrixok
TODO: Leírás
Dictionary-k
A Dictionary vagy más néven Hash-Map olyan adatszerkezet, amely kulcs-érték párokat tárol. A kulcsok egyediek és indexálásra használhatók a hozzájuk tartozó értékek lekérdezésére.
A tömbök indexelésével szemben a Dictionary index típusa bármi lehet.
A Dictionary elnevezés találó, hiszen ahogy egy szótár is egy könnyen kereshető kulcshoz (szó neve) tárol el egy extra adatot (szó definíciója) ugyanúgy ezt teszi a Dictionary is.
Egyéb hasznos Dictionary műveletek:
// Dictionary bejárása kulcs-érték párok szerint
foreach (KeyValuePair<string, int> pair in studentGrades)
{
Debug.Log("Name: " + pair.Key + ", Grade: " + pair.Value);
}A Dictionary egyik nagy előnye, hogy a keresés nagyon gyorsan történik bennük.
A C# Dictionary osztály implementációja hash táblát használ a kulcs-érték párok tárolására. Ennek köszönhetően a keresési műveletek nagyon gyorsak lehetnek. A hash táblák hatékonyak a kulcs alapú keresésekben az alábbi okok miatt:
- Hash függvények: A Dictionary használata során
Hashset
A HashSet, egyedi elemek kollekcióját tárolja sorrend nélkül. Használata hasonló a Listához a következő különbségekkel:
- A HashSet-ben egy elem csak egyszer szerepelhet. Ha új elemet tennénk bele, ami már szerepel benne, nem történik semmi.
- A HashSet elemeinek nincs sorrendje.
- Mivel az elemeknek nincs sorrendjük, nem indexelhetők, csak
foreachciklussal lehet végig iterálni rajta. - Az elemek hozzáadása, és kivétele, valamint annak vizsgálata, hogy a set tartalmaz-e egy elemet nagy mennyiségű adathalmazon is igen gyorsan történik. (Ideális esetben O(1) a keresés sebessége a kollekció méretére nézve: )
Használata:
Tehát a HashSet akkor hasznos, ha egyedi elemeket kell tárolnunk, és gyorsan szeretnénk ellenőrizni, hogy egy adott elem már benne van-e a halmazban.
Stack
A Stack azaz verem egyik beépített adatszerkezet a C# nyelvben, és LIFO - Last-In, First-Out működést valósítja meg: A legutóbb hozzáadott elem mindig az első, amelyet eltávolíthatunk.
Fontos speciális műveletei:
Push: Az elem hozzáadása a veremhez. Az új elem mindig a legfelső pozícióra kerül.Pop: Az elem eltávolítása a veremből. A legfelső elem kerül eltávolításra, és visszaadja azt.Peek: A verem legfelső elemének lekérdezése anélkül, hogy az eltávolításra kerülne. Csak az elemet adja vissza.
A Stack működés szempontjából egy listához hasonló, csupán más interface-szel (függvényekkel) férünk hozzá az elemeihez.
A call stack egy verem, amelyben a program futása során minden függvényhívás nyomot hagy. Amikor egy függvényt meghívunk, a hívás helye, paraméterei és más releváns információk a verem tetejére kerülnek. Amikor a függvény végrehajtása befejeződik, a hívás a veremből eltávolításra kerül, és a program folytatja a következő függvény vagy utasítás végrehajtását.
Ennek a mechanizmusnak a segítségével a programok nyomon követhetik a függvényhívások sorrendjét és az aktuális visszatérési pontokat. Ez lehetővé teszi a programnak, hogy a helyes sorrendben és helyen térjen vissza a függvényekből, és tudja, a memóriában hova kell ugrani a folytatáshoz.
A call stack mérete általában véges lenni. Ez azt jelenti, hogy a call stack csak bizonyos számú függvényhívást tud tárolni, mielőtt megtelik.
Amikor egy függvény meghívódik, a szükséges hely a call stack-en a függvényhívás adatainak (visszatérési cím, paraméterek, lokális változók stb.) tárolására kerül. Ha egy program túl sok függvényt hív egymásba ágyazottan, vagy ha egy függvény túl mélyen rekurzív hívást végez, akkor a call stack megtelhet.
Amikor a call stack megtelik, akkor az újabb függvényhívások nem tudnak megtörténni, és a program futása a "StackOverflowException” hibával elszáll.
Erről kapta a nevét a népszerű programozói fórum, a stackoverflow.com
Queue
A Queue, azaz sor, egy másik beépített adatszerkezet a C# nyelvben, a Stack párja. Míg a Stack a LIFO (Last-In, First-Out) elvet követi, addig a Queue az FIFO (First-In, First-Out) elvet alkalmazza. Ez azt jelenti, hogy a Queue-ba az elemeket az egyik végén helyezzük el, és a másik végéntávolítjuk el.
Elképzelhetjük a Queue-t úgy, mint emberek sorbanállását egy pénztárnál. Aki korábban állt be, az korábban kerül kiszolgálásra
Fontos műveletei:
Enqueue: Az elem hozzáadása a sorhoz. Az új elem mindig a legutolsó pozícióra kerül.Dequeue: Az elem eltávolítása a sorból. A legelső elem kerül eltávolításra, és visszaadja azt.Peek: A legelső (következőre sorra kerülő) elem lekérdezése anélkül, hogy az eltávolításra kerülne.
Használata:
Miért használnék Stack-et vagy Queue-t egy feladatra, mikor a List tud mindent és még többet is?
Előnyük, hogy mivel a Queue és a Stack specifikus működést valósítanak meg, azaz egyfajta adott műveletekre fókuszálnak kifejezőbb, olvashatóbb lehet a kód.