Lekce 4 - Vícerozměrné pole ve VB.NET
V minulé lekci, Spojový seznam ve VB.NET, jsme se věnovali spojovým seznamům.
Dnešní díl VB .NET tutoriálu pojednává o tzv. vícerozměrných polích.
Jednorozměrné pole
Již umíme pracovat s jednorozměrným polem, které si můžeme představit jako řádku přihrádek v paměti počítače.
Dvourozměrné pole
Ačkoli to není tak časté, v programování se občas setkáváme i s vícerozměrnými poli a to zejména pokud programujeme nějakou simulaci (např. hru).
Dvourozměrné pole si můžeme v paměti představit jako tabulku a mohli bychom takto reprezentovat např. rozehranou partii piškvorek. Pokud bychom se chtěli držet reálných aplikací, které budete později v zaměstnání tvořit, můžeme si představit, že do 2D pole budeme ukládat informace o obsazenostech sedadel v kinosálu. Situaci bychom si mohli graficky znázornit např. takto:
Kinosál by byl v praxi samozřejmě větší, ale jako ukázka nám toto
pole postačí. 0
znamená volno, 1
obsazeno. Později
bychom mohli doplnit i 2
- rezervováno a podobně. Pro tyto stavy
by bylo správnější vytvořit si vlastní datový typ, tzv.
výčet, ale s ním se setkáme až později, takže si teď
musíme vystačit pouze s čísly.
2D pole deklarujeme v VB .NET následujícími způsoby:
Dim kinosal(,) As Integer = New Integer(4, 4) {}
První číslice udává počet sloupců, druhá počet řádků (samozřejmě si to můžeme určit i obráceně, např. matice v matematice se zapisují opačně).
Všechna číselná pole v VB .NET jsou po deklaraci automaticky inicializována samými nulami, můžeme se na to spolehnout. Vytvořili jsme si tedy v paměti tabulku plnou nul.
Naplnění daty
Nyní kinosál naplníme jedničkami tak, jak je vidět na obrázku výše.
Protože budeme jako správní programátoři líní, využijeme k vytvoření
řádku jedniček for
cykly. Pro přístup k prvku 2D pole
musíme samozřejmě zadat dvě souřadnice:
Dim i As Integer = Integer.MinValue kinosal(2, 2) = 1 Prostřední řádek i = 1 While i < 4 kinosal(i, 3) = 1 4. řádek i += 1 End While i = 0 While i < 5 kinosal(i, 4) = 1 Poslední řádek i += 1 End While
Výpis
Výpis pole opět provedeme pomocí cyklu, na 2D pole budeme
potřebovat cykly dva (jeden nám pro-iteruje sloupce a druhý řádky). Jako
správní programátoři nevložíme počet řádků a sloupců do cyklů
napevno, jelikož se může změnit. .NET poskytuje na 2D poli vlastnost
Length
, jako tomu bylo u 1D pole, ale ta vrací celkový
počet prvků v poli, v našem případě tedy 25
. Nás
bude zajímat metoda GetLength()
, která přijímá jako parametr
dimenzi (0
pro sloupce, 1
pro řádky) a vrátí nám
počet prvků v této dimenzi. První dimenzí je počet sloupců, druhou počet
řádků.
Cykly zanoříme do sebe tak, aby nám vnější cyklus projížděl řádky a vnitřní sloupce v aktuálním řádku. Po výpisu řádku je nutné odřádkovat. Oba cykly musí mít samozřejmě jinou řídící proměnnou:
{VBNET_CONSOLE}
' deklarace
Dim i As Integer = Integer.MinValue
Dim kinosal(,) As Integer = New Integer(4, 4) {}
' naplnění daty
kinosal(2, 2) = 1 ' Prostřední řádek
i = 1
While i < 4
kinosal(i, 3) = 1 ' 4. řádek
i += 1
End While
i = 0
While i < 5
kinosal(i, 4) = 1 ' Poslední řádek
i += 1
End While
' Výpis 2D pole
Dim j As Integer = 0
While j < kinosal.GetLength(1) ' řádky
i = 0
While i < kinosal.GetLength(0) ' sloupce
Console.Write(kinosal(i, j))
i += 1
End While
Console.WriteLine()
j += 1
End While
Console.WriteLine()
{/VBNET_CONSOLE}
Výsledek:
Konzolová aplikace
00000
00000
00100
01110
11111
N-rozměrná pole
Někdy může být příhodné vytvořit si pole o ještě více dimenzích. My všichni si jistě dokážeme představit minimálně 3D pole. S příkladem s kinosálem se nabízí případ užití, kdy má budova více pater (nebo obecně více kinosálů). Vizualizace by vypadala asi nějak takto:
3D pole můžeme vytvořit tím samým způsobem, jako 2D pole:
Dim kinosal3D(,,) As Integer = New Integer(4, 4, 3) {}
Kód výše vytvoří 3D pole jako na obrázku. Přistupovat k němu budeme opět přes indexer (kulaté závorky) jako předtím, jen již musíme zadat tři souřadnice:
kinosal3D(3, 2, 1) = 1 ' Druhý kinosál, třetí řada, čtvrtý sloupec
Pokud metodě GetLength()
zadáme parametr s
hodnotou 2
, získáváme počet "pater" (kinosálů).
Pole polí
Mnoho programovacích jazyků vlastně vícerozměrná pole nepodporuje, VB je spíše výjimkou. Můžeme si v nich ale stejně vytvořit kolika-rozměrné pole chceme, jelikož 2D pole není vnitřně nic jiného, než pole polí. Situaci si můžeme představit tak, že si vytvoříme pole o pěti prvcích (1. řádek) a každá buňka v tomto řádku v sobě bude obsahovat další pole, reprezentující sloupeček.
Takové 2D pole deklarujeme následujícím způsobem:
Dim kinosalJag As Integer()() = New Integer(4)() {}
Výhodou takto deklarovaného 2D pole je fakt, že si do každého řádku/sloupce můžeme uložit jak velké pole chceme. V některých případech tedy nemusíme "plýtvat" pamětí na celou tabulku a můžeme pole vytvořit zubaté (anglicky jagged):
Nevýhodou tohoto přístupu je, že musíme pole nepříjemně inicializovat sami. Původní řádek s pěti buňkami sice existuje, ale jednotlivé sloupečky si do něj musíme navkládat sami (zatím si vložme všechny sloupečky o 5ti prvcích):
Dim i As Integer = 0 While i < kinosalJag.Length kinosalJag(i) = New Integer(4) {} i += 1 End While
VB rovněž dále neposkytuje žádný komfort ve formě získání počtu sloupců a řádků polí polí. Velikost pole musíme získat takto:
Dim sloupcu As Integer = kinosalJag.Length Dim radku As Integer = 0 If sloupcu <> 0 Then radku = kinosalJag(0).Length End If
Všimněte si, že je nutné ptát se na počet sloupců, pokud
je totiž 0
, nemůžeme se dostat k 1. sloupci, abychom zjistili
jeho délku (počet řádků ve sloupci).
K hodnotám v poli poté přistupujeme pomocí dvou indexerů:
kinosal(4)(2) = 1 ' Obsazujeme sedadlo v 5. sloupci a 3. řadě
Použití jediného indexeru nám vrátí celý sloupeček na daném indexu.
Zkrácená inicializace vícerozměrných polí
Ještě si ukážeme, že i vícerozměrná pole je možné rovnou inicializovat hodnotami (kód vytvoří rovnou zaplněný kinosál jako na obrázku):
Dim kinosal(,) As Integer = {{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 1, 0, 0}, {0, 1, 1, 1, 0}, {1, 1, 1, 1, 1} }
Sloupce, zde zapisujeme jako obsah jednotlivých řádků.
Podobnou inicializaci můžeme použít dokonce i u polí zubatých (kód níže vytvoří zubaté pole jako na obrázku):
Dim zubatePole As Integer()() = New Integer()() {New Integer() {15, 2, 8, 5, 3}, New Integer() {3, 3, 7}, New Integer() {9, 1, 16, 13}, New Integer() {}, New Integer() {5} }
Na závěr bych rád dodal, že někteří lidé, kteří neumí správně
používat objekty, využívají 2D polí k ukládání více údajů o jediné
entitě. Např. budeme chtít uložit výšku, šířku a délku pěti
mobilních telefonů. Ačkoli se vám nyní může zdát, že se jedná o úlohu
na 3D pole, ve skutečnosti se jedná o úlohu na obyčejné 1D pole (přesněji
seznam) objektů typu Telefon
. Pole si určitě ještě
vyzkoušejte ještě v cvičení v tomto kurzu.
V následujícím kvízu, Kvíz - Genericita, List, N-rozměrné pole ve VB.NET Kolekce, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 6x (295.32 kB)
Aplikace je včetně zdrojových kódů v jazyce VB