Dvourozměrné pole - konzole
3. C#
3.9. Transpozice
Pokud je matice symetrická , označujeme úhlopříčnou spojnici protilehlých míst (počátečního prvku a posledního prvku matice) jako hlavní diagonálu. Pro prvky na hlavní diagonále platí, že jejich index řádku je roven indexu sloupce , tj. Pro případ matice o rozměru např. 3 x 3 jsou prvky umístěné na hlavní diagonále označeny zeleně - viz Obrázek 1.

Obrázek 1: Prvky na hlavní diagonále ve dvourozměrném poli
Transpozice prvků podle hlavní diagonály znamená prohození osově souměrných prvků, kde osu otáčení představuje hlavní diagonála - viz Obrázek 2.

Obrázek 2: Transpozice prvků podle hlavní diagonály ve dvourozměrném poli
Abychom prohodili jednotlivé prvky podle hlavní diagonály, stačí nám pouze procházet jednotlivé prvky v oranžové oblasti, které jsou umístěny nad hlavní diagonálou (pokud bychom také procházeli i prvky pod hlavní diagonálou, znovu bychom prohazovali nazpátek již jednou prohozené prvky a matice by zůstala nezměněna) - viz Obrázek 3. Prvky na hlavní diagonále není zapotřebí prohazovat.

Obrázek 3: Průchod prvky nad hlavní diagonálou ve dvourozměrném poli při transpozici prvků podle hlavní diagonály
V následující metodě bez výstupu s názvem HlavniTranspozice, která je také umístěna v regionu Operace s polem, je zachycena podstata transpozice prvků podle hlavní diagonály. Metoda přijímá tři parametry: počet řádků, počet sloupců matice a matici, jejíž prvky chceme transponovat podle hlavní diagonály. Dále metoda obsahuje tři proměnné:
- pom - pomocná proměnná pro přesun osově souměrných prvků matice podle hlavní diagonály
- i - index řádku matice aktuálně procházeného prvku (deklarace přímo v cyklu)
- j - index sloupce matice aktuálně procházeného prvku (deklarace přímo v cyklu)
První rozhodovací příkaz zajišťuje, že pokud počet řádků není roven počtu sloupců (nejedná se o symetrickou matici), je metoda ukončena včetně výpisu varovného hlášení. Pokud je matice symetrická, využijeme pro procházení jednotlivých prvků nad hlavní diagonálou dva cykly s krokem. První vnější cyklus bude probíhat od prvního do předposledního řádku matice. Jedná se totiž o oranžovou oblast prvků nad hlavní diagonálou. Pro procházení sloupců v jednotlivých řádcích matice slouží další vnitřní cyklus s krokem. Jak si můžeme všimnout, je zapotřebí procházet pouze ty prvky, jejichž index sloupce je o 1 vyšší, než index řádku aktuálně procházeného prvku (do průchodu chceme zahrnout pouze oranžovou oblast). V těle cyklu provádíme vzájemné prohození prvků pomocí uložení hodnoty prvků z oranžové oblasti do pomocné proměnné. Tento princip jsme již využili dříve, např. při vzestupném řazení prvků v řádcích pomocí metody Bubble Sort. Prvek v oranžové oblasti je přepsán osově souměrným prvkem podle hlavní diagonály umístěným pod hlavní diagonálou pomocí příkazu pole[i, j] = pole[j, i];. Do osově souměrného prvku pod hlavní diagonálou je následně uložena hodnota z pomocné proměnné.
/// <summary> /// Transpozice prvků matice podle hlavní diagonály /// </summary> /// <param name="m"> počet řádků matice </param> /// <param name="n"> počet sloupců matice </param> /// <param name="pole"> matice, kde jsou prvky otočeny podle hlavní diagonály </param> static void HlavniTranspozice(int m, int n, int[,] pole) { /* Deklarace: 'pom' ... pomocná proměnná pro přesun osově souměrných prvků matice podle * hlavní diagonály; 'i' ... index řádku matice; 'j' ... index sloupce matice */ int pom; // Pokud počet řádek není roven počtu sloupců (matice není symetrická), pak... if (m != n) { // Výpis varovného upozornění Console.WriteLine("Nelze transponovat obdélníkovou matici"); // Ukončení metody return; } // Jinak ... else { // Od počátečního až předposledního řádku matice for (int i = 0; i < m - 1; i++) { // Od i + 1-tého sloupce do posledního sloupce matice for (int j = i + 1; j < m; j++) { // Uložení aktuálního prvku matice na pozici [i,j] do pomocné proměnné pom = pole[i, j]; /* Přepsání aktuálního prvku matice na pozici [i,j] osově souměrným prvkem * podle hlavní diagonály, tj. na pozici [j,i] */ pole[i, j] = pole[j, i]; /* Přepsání osově souměrného prvku na pozici [j,i] prvkem uloženým * v pomocné proměnné */ pole[j, i] = pom; } } } }
Kód 1: Deklarace statické metody bez návratu s názvem HlavniTranspozice
Pokud je matice symetrická označujeme protilehlou úhlopříčnou spojnici protilehlých míst (posledního prvku prvního řádku a prvního prvku posledního řádku) jako vedlejší diagonálu. Pro prvky na vedlejší diagonále platí, že jejich index řádku i je roven indexu sloupce pokud . Pro případ matice o rozměru 3 x 3 jsou prvky umístěné na vedlejší diagonále označeny modře - viz Obrázek 4.

Obrázek 4: Prvky na vedlejší diagonále ve dvourozměrném poli
Transpozice prvků podle vedlejší diagonály znamená prohození osově souměrných prvků, kde osu otáčení představuje vedlejší diagonála - viz Obrázek 5.

Obrázek 2: Transpozice prvků podle vedlejší diagonály ve dvourozměrném poli
V následující metodě bez výstupu s názvem VedlejšíTranspozice je zachycena podstata transpozice prvků podle vedlejší diagonály - viz Kód 2. Metoda přijímá tři parametry: počet řádku, počet sloupců matice a matici, jejíž prvky chceme transponovat. Dále metoda obsahuje tři proměnné:
- pom - pomocná proměnná pro přesun osově souměrných prvků matice podle vedlejší diagonály
- i - index řádku matice aktuálně procházeného prvku (deklarace přímo v cyklu)
- j - index sloupce matice aktuálně procházeného prvku (deklarace přímo v cyklu)
První rozhodovací příkaz zajišťuje, že pokud počet řádků není roven počtu sloupců (nejedná se o symetrickou matici), je metoda ukončena včetně výpisu varovného hlášení. Pokud je matice symetrická, využijeme pro procházení jednotlivých prvků nad vedlejší diagonálou dva cykly s krokem. První vnější cyklus bude probíhat od prvního do předposledního řádku matice. Jedná se totiž o oranžovou oblast prvků nad vedlejší diagonálou. Pro procházení sloupců v jednotlivých řádcích matice slouží další vnitřní cyklus s krokem. Jak si můžeme všimnout, je zapotřebí procházet pouze ty prvky, jejichž index sloupce je menší než rozdíl počtu řádků a indexu řádku aktuálně procházeného prvku (do průchodu chceme zahrnout pouze oranžovou oblast). Matice je symetrická m = n, takže nezáleží zda menšenec představuje počet řádků, nebo počet sloupců. V těle cyklu provádíme vzájemné prohození prvků pomocí uložení hodnoty prvků z oranžové oblasti do pomocné proměnné. Prvek v oranžové oblasti na pozici [i, j] je přepsán osově souměrným prvkem podle vedlejší diagonály umístěným pod vedlejší diagonálou na pozici [m - j - 1, m - i - 1]. Do osově souměrného prvku pod vedlejší diagonálou je následně uložena hodnota z pomocné proměnné.
/// <summary> /// Transpozice prvků matice podle vedlejší diagonály /// </summary> /// <param name="m"> počet řádků matice </param> /// <param name="n"> počet sloupců matice </param> /// <param name="pole"> matice, kde jsou prvky otočeny podle vedlejší diagonály </param> static void VedlejsiTranspozice(int m, int n, int[,] pole) { /* Deklarace: 'pom' ... pomocná proměnná pro přesun osově souměrných prvků matice podle * vedlejší diagonály; 'i' ... index řádku matice; 'j' ... index sloupce matice */ int pom; // Pokud počet řádek není roven počtu sloupců (matice není symetrická), pak... if (m != n) { // Výpis varovného upozornění Console.WriteLine("Nelze transponovat obdélníkovou matici"); // Ukončení metody return; } // Jinak ... else { // Od počátečního až předposledního řádku matice for (int i = 0; i < m - 1; i++) { // Od i + 1-tého sloupce do posledního sloupce matice for (int j = 0; j < m - i; j++) { // Uložení aktuálního prvku matice na pozici [i,j] do pomocné proměnné pom = pole[i, j]; /* Přepsání aktuálního prvku matice na pozici [i,j] osově souměrným prvkem * podle vedlejší diagonály, tj. na pozici [m-j-1,m-i-1] */ pole[i, j] = pole[m - j - 1, m - i - 1]; /* Přepsání osově souměrného prvku na pozici [m-j-1, m-i-1] prvkem uloženým * v pomocné proměnné */ pole[m - j - 1, m - i - 1] = pom; } } } }
Kód 2: Deklarace statické metody bez návratu s názvem VedlejsiTranspozice