NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

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.

Struktura pole - Kolekce a LINQ ve VB.NET

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:

Struktura dvourozměrného pole - Kolekce a LINQ ve VB.NET

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:

    ' 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()


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 v C# .NET - Kolekce a LINQ ve VB.NET

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):

Pole polí v C# .NET - Kolekce a LINQ ve VB.NET

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

 

Předchozí článek
Spojový seznam ve VB.NET
Všechny články v sekci
Kolekce a LINQ ve VB.NET
Přeskočit článek
(nedoporučujeme)
Kvíz - Genericita, List, N-rozměrné pole ve VB.NET Kolekce
Článek pro vás napsal Přemysl Šíma
Avatar
Uživatelské hodnocení:
1 hlasů
APSima
Aktivity