Dvourozměrné pole - WPF
4. C#
4.8. Transpozice
Pro transpozici prvků matice podle hlavní diagonály je v regionu Operace s polem, která je součástí regionu Pomocné metody, volána soukromá metoda bez návratu s názvem HlavniTranspozice. Metoda přijímá tři parametry: počet řádků, počet sloupců matice a matici. Metoda obsahuje tři lokální proměnné. Proměnná pom reprezentuje pomocnou proměnnou pro přesun osově souměrných prvků matice podle hlavní diagonály. Ostatní dvě lokální proměnné i - index řádku matice aktuálně procházeného prvku a j - index sloupce matice aktuálně procházeného prvku jsou deklarovány 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í v dialogovém oknu. 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 oblast prvků umístěných 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 oblast nad hlavní diagonálou). V těle cyklu provádíme vzájemné prohození prvků pomocí uložení hodnoty prvků z oblasti nad diagonálou 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 oblasti nad diagonálou 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é.
Následující zdrojový kód obsahuje deklaraci metody HlavniTranspozice- viz Kód 1.
/// <summary> /// Metoda pro transpozici 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 </param> private 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í MessageBox.Show("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 metody pro transpozici prvků podle hlavní diagonály (HlavniTranspozice)
Přemístíme se zpět do regionu Události a jeho části Operace s polem. V tomto regionu upravíme metodu obsluhy události stisknutí tlačítka BtnTranspoziceHlavni_Click - viz Kód 2. V rámci těla metody budeme volat předchozí deklarovanou metodu HlavniTranspozice, které předáme tři parametry - počet řádků matice, počet sloupců matice a matici (uložené v datových složkách třídy). Vzhledem k tomu, že v metodě bude upravena matice, je vhodné tuto změněnou matici uživateli zobrazit. Proto matici zobrazíme jak do objektu typu TextBox, tak i do objektu typu ListView umístěných na formuláři.
/// <summary> /// Volání metody pro transpozici prvků matice podle hlavní diagonály /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnTranspoziceHlavni_Click(object sender, RoutedEventArgs e) { // Zavolání metody pro transpozici prvků matice podle hlavní diagonály this.HlavniTranspozice(this.pocetRadku, this.pocetSloupcu, this.pole); // Zavolání metody pro zobrazení matice do objektu (TextBox) na formuláři this.ZobrazitPoleJakoText(this.pocetRadku, this.pocetSloupcu, this.pole); // Zavolání metody pro zobrazení matice v objektu (ListView) na formuláři this.ZobrazitPoleVListView(this.pocetRadku, this.pocetSloupcu, this.pole); }
Kód 2: Deklarace metody pro zavolání metody pro transpozici prvků matice podle hlavní diagonály - výpis na formuláři (BtnTranspoziceHlavni_Click)
Pro transpozici prvků matice podle hlavní diagonály je v regionu Operace s polem, která je součástí regionu Pomocné metody, volána soukromá metoda bez návratu s názvem VedlejsiTranspozice - viz Kód 3. Metoda přijímá tři parametry: počet řádků, počet sloupců matice a matici. Metoda obsahuje tři lokální proměnné. Proměnná pom reprezentuje pomocnou proměnnou pro přesun osově souměrných prvků matice podle hlavní diagonály. Ostatní dvě lokální proměnné i - index řádku matice aktuálně procházeného prvku a j - index sloupce matice aktuálně procházeného prvku jsou deklarovány přímo v cyklu.Stejně jako v předchozím případu transpozice podle hlavní diagonály, první rozhodovací příkaz metody zajišťuje, že pokud počet řádků není roven počtu sloupců, je metoda ukončena včetně výpisu varovného hlášení v dialogovém oknu. 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 o 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 oblast nad vedlejší diagonálou). 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 oblasti nad vedlejší diagonálou do pomocné proměnné. Prvek v oblasti nad diagonálou 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> /// Metoda pro transpozici 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 </param> private 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á) ... if (m != n) { // Výpis varovného upozornění MessageBox.Show("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 3: Deklarace metody pro transpozici prvků podle vedlejší diagonály (VedlejsiTranspozice)
Přemístíme se zpět do regionu Události a jeho části Operace s polem. V tomto regionu upravíme metodu obsluhy události stisknutí tlačítka BtnTranspoziceVedlejsi_Click - viz Kód 4. V rámci těla metody budeme volat předchozí deklarovanou metodu VedlejsiTranspozice, které předáme tři parametry - počet řádků matice, počet sloupců matice a matici (uložené v datových složkách třídy). Vzhledem k tomu, že v metodě bude upravena matice, je vhodné tuto změněnou matici uživateli zobrazit. Proto matici zobrazíme jak do objektu typu TextBox, tak i do objektu typu ListView umístěných na formuláři.
/// <summary> /// Volání metody pro transpozici prvků matice podle vedlejší diagonály /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnTranspoziceVedlejsi_Click(object sender, RoutedEventArgs e) { // Zavolání metody pro transpozici prvků matice podle vedlejsi diagonály this.VedlejsiTranspozice(this.pocetRadku, this.pocetSloupcu, this.pole); // Zavolání metody pro zobrazení matice do objektu (TextBox) na formuláři this.ZobrazitPoleJakoText(this.pocetRadku, this.pocetSloupcu, this.pole); // Zavolání metody pro zobrazení matice v objektu (ListView) na formuláři this.ZobrazitPoleVListView(this.pocetRadku, this.pocetSloupcu, this.pole); }
Kód 4: Deklarace metody pro zavolání metody pro transpozici prvků matice podle vedlejší diagonály - výpis na formuláři (BtnTranspoziceVedlejsi_Click)