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