Jednorozměrné pole - konzole
3. C#
3.3. Plnění pole
Následující zdrojový kód obsahuje deklaraci metody bez návratu PlnitPole - viz Kód 1. Tato metoda umožňuje uživateli zvolit typ plnění celočíselného vektoru. Oproti kaskádovému členění rozhodování ve vývojovém diagramu je ve zdrojovém kódu metody použito vícenásobné větvení pomocí příkazu switch. Pokud je hodnota uložená v proměnné zpusobPlneni rovna:
- 0 - vektor pole je plněn náhodnými čísly pomocí metody bez návratu NahodnePole
- 1 - vektor pole je plněn celočíselnými hodnotami specifikovanými uživatelem. Uživatel zároveň definuje, kterému prvku vektoru patří tato jím zadaná hodnota. Plnění je prováděno pomocí metody bez návratu s názvem PlnitJednotlive. Oproti vývojovém diagramu ve Flowgorithm již není zapotřebí volat metodu NulovatPole, protože v C# pole představuje referenční datový typ, tzn. pokud není nastavena hodnota prvku pole, prvek je inicializován počáteční hodnotou v závislosti na příslušném datovém typu (např. u datového typu int je to 0)
- 2 - vektor pole je plněn nulami pomocí metody bez návratu NulovatPole
/// <summary> /// Metoda bez návratu - výběr metody plnění vektoru /// </summary> /// <param name="n"> aktuální rozměr (počet prvků) vektoru </param> /// <param name="minHodnota"> dolní mez prvků vektoru </param> /// <param name="maxHodnota"> horní mez prvků vektoru </param> /// <param name="pole"> vektor, který má být naplněn </param> static void PlnitPole(int n, int minHodnota, int maxHodnota, int[] pole) { /* Deklarace: 'zpusobPlneni' ... způsob plnění vektoru('0'...Náhodně, '1'...Jednotlivě, * '2'...Nulovat) */ int zpusobPlneni; do { // Výzva k zadání způsobu plnění vektoru Console.Write("Zvolte způsob plnění vektoru (0...Náhodně, 1...Jednotlivě, 2...Nulovat): "); // Načtení způsobu plnění int.TryParse(Console.ReadLine(), out zpusobPlneni); } // Načtení způsobu plnění proběhne znovu, pokud nebyl zadán validní celočíselný kód způsobu plnění while ((zpusobPlneni != 0) && (zpusobPlneni != 1) && (zpusobPlneni != 2)); switch (zpusobPlneni) { // Plnění vektoru náhodnými čísly case 0: // Zavolání metody pro plnění vektoru náhodnými čísly NahodnePole(n, minHodnota, maxHodnota, pole); break; // Plnění vektoru jednotlivými zadanými hodnotami uživatelem case 1: // Plnění vektoru jednotlivými uživatelem zadanými čísly PlnitJednotlive(n, minHodnota, maxHodnota, pole); break; case 2: // Všem prvkům vektoru přiřadíme hodnotu '0' NulovatPole(n, pole); break; } }
Kód 1: Deklarace statické metody bez návratu s názvem PlnitJednotlive
Detailní popisy podstaty následujících metod byly provedeny již v rámci analýzy ve stejnojmenné podkapitole a proto jej není nutné znovu uvádět. Uvedeme si pouze rozdíly oproti vývojovému diagramu jednotlivých podprogramů.
Následující zdrojový kód obsahuje deklaraci metody bez návratu NahodnePole, která je volána z metody PlnitPole, pokud uživatel zadal do proměnné zpusobPlneni hodnotu 0 - viz Kód 2. V metodě je generováno náhodné číslo na základě rovnoměrného rozdělení, tj. objekt rnd odvozený od třídy Random (instance třídy Random). Abychom mohli vytvořit objekt rnd, je zapotřebí zavolat konstruktor objektu pomocí klíčového slova new. Pro generování náhodného čísla využijeme metodu Next přidruženou k objektu rnd (přístup k metodám je pomocí tečkové notace). Tato metoda je k dispozici ve třech přetížených verzích:
- Next() - metoda bez parametru navrací náhodné číslo v celém rozsahu datového typu int
- Next(maxHodnota) - metoda navrací nezáporná čísla menší než hodnota v parametru maxHodnota, např. rnd.Next(100); vrátí číslo od 0 do 99
- Next(minHodnota, maxHodnota) - metoda vrátí náhodné číslo náležící zleva uzavřenému intervalu <minHodnota, maxHodnota) ... dolní mez intervalu patří a horní mez již ne. Pokud potřebujeme pomocí objektu rnd generovat náhodné číslo např. od 1 do 100, uvedeme příkaz rnd.Next(1, 101);
V C# není při generování náhodného čísla zapotřebí definovat délku intervalu delkaIntervalu = maxHodnota - minHodnota + 1, kterou jsme využívali ve vývojových diagramech. Ve zdrojovém kódu jsme využili při generování náhodného čísla volání metody Next se dvěma parametry. Návrat této metody ve formě náhodného celého čísla přiřadíme i-tému aktuálnímu prvku pole, tj. pole[i] = rnd.Next(minHodnota, maxHodnota + 1);
V tomto i v dalších cyklech určených k procházení prvků vektoru je nahrazena podmínka dosažení horní meze u řídící proměnné, kterou jsme používali ve vývojových diagramech ve formě i <= n - 1 za jinak formulovanou, ale principiálně stejnou podmínku i < n (použití v metodách ZobrazitPole, PoleJakoText, MinimumVPoli, atd). Inkrementace řídící proměnné i je prováděna pomocí operátoru ++, tj. i++, namísto zdlouhavého zápisu příkazu i = i +1;
/// <summary> /// Metoda bez návratu - plnění vektoru náhodnými čísly /// </summary> /// <param name="n"> počet prvků vektoru </param> /// <param name="minHodnota"> dolní mez prvků vektoru </param> /// <param name="maxHodnota"> horní mez prvků vektoru </param> /// <param name="pole"> vektor, který má být naplněn </param> static void NahodnePole(int n, int minHodnota, int maxHodnota, int[] pole) { /* Deklarace: 'rnd' ... náhodné číslo (generované na základě rovnoměrného rozdělení); * 'i' ... index (pozice) prvku vektoru */ // Deklarace náhodného čísla (objektu) včetně inicializace Random rnd = new Random(); // Pro všechny prvky od '0' (počátečního) do 'n-1'-tého (posledního) prvku for (int i = 0; i < n; i++) { /* Vygenerování náhodného čísla uloženého do 'rnd' v rozsahu 'minHodnota' až 'maxHodnota' * Přiřazení náhodného čísla do 'i'-tého prvku */ pole[i] = rnd.Next(minHodnota, maxHodnota + 1); } }
Kód 2: Deklarace statické metody bez návratu s názvem NahodnePole
Další možností plnění pole, je pomocí uvedení pořadí prvku a specifikace jeho hodnoty. Pro tuto metodu plnění je volána metoda bez návratu PlnitJednotlive. Je důležité upozornit, že uživatel zadává index prvku (index pozice začíná od 0) - viz Kód 3.
/// <summary> /// Metoda bez návratu - plnění jednotlivých prvků vektoru uživatelem /// </summary> /// <param name="n"> počet prvků </param> /// <param name="minHodnota"> stávající dolní mez prvků vektoru </param> /// <param name="maxHodnota"> stávající horní mez prvků vektoru </param> /// <param name="pole"> vektor, který má být naplněn </param> static void PlnitJednotlive(int n, int minHodnota, int maxHodnota, int[] pole) { /* Deklarace: 'index' ... index prvku, který má být naplněn; 'hodnota' ... hodnota * prvku, který má být naplněn; 'plnit' ... informace, zda má zadán (naplněn) * další prvek ('0'...Ano, '1'...Ne) */ int index, hodnota, plnit; // Cyklus s podmínkou na konci pro plnění prvků do { // Cyklus s podmínkou na konci pro načtení indexu plněného prvku do { // Výzva k zadání indexu prvku, včetně vypsání mezí Console.Write("Zadejte pořadové číslo prvku, který chcete naplnit (0 - {0}): ", pole.Length-1); // Načtení indexu int.TryParse(Console.ReadLine(), out index); // Test, zda načtený index je mimo meze ... if ((index < 0) || (index > n-1)) { // Výpis o chybě Console.WriteLine("Zadaná hodnota je mimo meze"); } } /* Podmínka cyklu, zda načtený index je mimo meze. Pokud ano, opakovaní * načtení indexu */ while ((index < 0) || (index > n-1)); // Cyklus s podmínkou na konci - validace zadané hodnoty zda je hodnota v rozsahu mezí do { // Výzva k zadání hodnoty prvku, včetně vypsání dolní a horní meze pro všechny prvky Console.Write("Zadejte hodnotu prvku ({0} - {1}): ", minHodnota.ToString(), maxHodnota.ToString()); // Načtení hodnoty int.TryParse(Console.ReadLine(), out hodnota); // Test, zda načtená hodnota prvku je mimo meze ... if ((hodnota < minHodnota) || (hodnota > maxHodnota)) { // Výpis o chybě Console.WriteLine("Zadaná hodnota je mimo meze"); } } /* Podmínka cyklu, zda načtená hodnota prvku je mimo meze. Pokud ano, opakovaní * načtení hodnoty */ while ((hodnota < minHodnota) || (hodnota > maxHodnota)); // Přiřazení hodnoty z lokální proměnné do prvku vektoru na pozici 'index' pole[index] = hodnota; // Zavolání metody pro zobrazení vektoru jako prvky v řádku oddělené čárkou Console.WriteLine(PoleJakoText(n, pole)); // Zavolání metody pro zobrazení vektoru jako prvky pod sebou Console.WriteLine(ZobrazitPole(n, pole)); // Cyklus s podmínkou na konci - validace informace o tom, zda dále plnit do { // Výzva, zda mají být plněny další prvky Console.Write("Chcete plnit další prvek (0...Ne, 1...Ano): "); // Načtení informace o dalším plnění int.TryParse(Console.ReadLine(), out plnit); // Test, zda načtená hodnota (informace o plnění) je mimo meze ... if ((plnit < 0) || (plnit > 1)) { // Výpis chyby Console.WriteLine("Zadaná hodnota je mimo meze"); } } /* Podmínka cyklu, zda načtená hodnota je mimo meze. Pokud ano, * opakovaní načtení hodnoty */ while ((plnit < 0) || (plnit > 1)); } /* Podmínka cyklu, zda má být provedeno další načtení prvku. Pokud ano (hodnota '1'), * opakovaní načtení hodnoty */ while (plnit == 1); }
Kód 3: Deklarace statické metody bez návratu s názvem PlnitJednotlive
Poslední možností, jak plnit pole, je do něj umístit samé nuly. Následující metodě NulovatPole proto pouze postačí jednoduchý cyklus s krokem, kde každému prvku pole je přiřazena hodnota 0 - viz Kód 4.
/// <summary> /// Metoda bez návratu - plnění prvků pole hodnotou nula /// </summary> /// <param name="n"> počet prvků vektoru </param> /// <param name="pole"> vektor, který má být naplněn </param> static void NulovatPole(int n, int[] pole) { /* Pro všechny prvky od '0' (počátečního) do 'n-1'-tého (posledního) prvku; * 'i' ... index (pozice) prvku vektoru */ for (int i = 0; i < n; i++) { // Přiřazení nuly 'i'-tému (aktuálně procházenému) prvku pole[i] = 0; } }
Kód 4: Deklarace statické metody bez návratu s názvem NulovatPole