[JAVA] Problém s nečtvercovou maticí

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod Iban 16. 7. 2012 12:13

Zdravím,

mám menší problém, který souvisí s tím, že mě nenapadá řešení, jak naprogramovat, aby nečtvercová matice šla transponovat. Moje současné řešení v úseku kódu na transponování matice platí pouze pro čtvercové a pro zbylé jsem zatím problém ošetřil hodnotou null, jenže to tak nechci. Nevíte někdo o nějakém elegantním řešení?

Kód: Vybrat vše
    public int[][] transponovanaMatice() {
        int[][] transponovanaMatice = new int[radky][sloupce];
        if (radky == sloupce) {
            for (int i = 0; i < radky; i++) {
                for (int j = 0; j < sloupce; j++) {
                    transponovanaMatice[j][i] = matice[i][j];
                }
            }
        } else {
            System.out.println("Transponovanou čtvercovou matici nelze sestrojit.");
            transponovanaMatice = null;
        }
        return matice = transponovanaMatice;
    }


Děkuji
Iban
Junior

Odeslat příspěvekod Bari007 16. 7. 2012 12:42

Však to je pořád ten stejný postup, ne? Jen přehodíš řádky a sloupce. A žádný if tam nepotřebuješ, protože ty řádky a sloupce si přehodíš i pro tu čtvercovou matici.
Bari007
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod Iban 16. 7. 2012 12:47

Kód: Vybrat vše
    public int[][] transponovanaMatice() {
        int[][] transponovanaMatice = new int[radky][sloupce];
//        if (radky == sloupce) {
            for (int i = 0; i < radky; i++) {
                for (int j = 0; j < sloupce; j++) {
                    transponovanaMatice[j][i] = matice[i][j];
                }
            }
//        } else {
//            System.out.println("Transponovanou čtvercovou matici nelze sestrojit.");
//            transponovanaMatice = null;
//        }
        return matice = transponovanaMatice;
    }


U této varianty ale nastane tento problém, zadám-li do vstupu třeba matici 5x4:

Kód: Vybrat vše
Transponovaná matice:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
Iban
Junior

Odeslat příspěvekod Bari007 16. 7. 2012 12:53

No jasně, protože jsi jenom vymazal ten if, ale žádnou další úpravu jsi neudělal. Přehoď si řádky a sloupce u té výsledné matice (a všude, kde se to toho týká) a máš hotovo.
Bari007
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod Iban 16. 7. 2012 13:34

Tam je ten problém trochu obsáhlejší. Při testování se to rozhází. Já si k tomu sednu večer a budu promýšlet jak na to a napíšu sem, jak jsem pokročil. Řešení to má, ale nejhorší je ta logika, že prohození řádku za sloupce v tomto případě nestačí. Zkoušel jsem to samozřejmě, ale nanejvýš to zpracuje a vypíše první řádek a sází chyby.
Iban
Junior

Odeslat příspěvekod Bari007 16. 7. 2012 14:14

To se mi nějak nezdá. Nemám sice nástroj, ve kterém bych to mohl zkoušet prakticky přímo v Javě, ale transpozice matice spočívá pouze v prohození řádků a sloupců.

Takže přehodíš rozměry výsledného pole a pak přehazuješ indexy jednotlivých prvků té matice. Nic víc by v tom být nemělo.
Kód: Vybrat vše
public int[][] transponovanaMatice() {
        int[][] transponovanaMatice = new int[sloupce][radky];
            for (int i = 0; i < radky; i++) {
                for (int j = 0; j < sloupce; j++) {
                    transponovanaMatice[j][i] = matice[i][j];
                }
            }
        }
        return matice = transponovanaMatice;
    }

Asi takhle. Ale je to jen z fleku napsaný, nemám to kde vyzkoušet.
Bari007
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod natix 16. 7. 2012 14:30

Netuším, odkud taháš proměnné radky a sloupce, ale pokud výchozí matici předáš metodě jako vstupní parametr, tak z ní její počet řádků a sloupců zjistíš velmi jednoduše.

Kód: Vybrat vše
static int[][] transpose(int[][] matrix) {
   int rows = matrix[0].length;
   int columns = matrix.length;
   int[][] transposedMatrix = new int[rows][columns];

   for (int i = 0; i < rows; i++) {
      for (int j = 0; j < columns; j++) {
         transposedMatrix[i][j] = matrix[j][i];
      }
   }
   return transposedMatrix;
}


Mimochodem, tenhle tvůj return s přiřazením do globální proměnné:
Kód: Vybrat vše
return matice = transponovanaMatice;

... je zlo, nikdy už nic takového nepiš. Prostě vrať výslednou hodnotu a v místě volání metody tuhle navrácenou hodnotu přiřaď do nové proměnné, nějak takhle:
Kód: Vybrat vše
int[][] matrix = {
   { 1, 2, 3 },
   { 4, 5, 6 }
};

int[][] transposedMatrix = transpose(matrix);


Samozřejmě pro úplnou korektnost by bylo potřeba ještě provést na začátku kontrolu, že to 2-rozměrné pole na vstupu je opravdu obdélníková matice a ne nějaký patvar, který nejde transponovat:
Kód: Vybrat vše
***
*****
**

...ale to už je detail.
natix
Junior

Odeslat příspěvekod Iban 16. 7. 2012 22:21

Proměnné radky a sloupce jsou globalní a plním je v přetíženém konstruktoru.

Kód: Vybrat vše
public Matice(int vyskaMatice, int sirkaMatice) {
        this.radky = vyskaMatice;
        this.sloupce = sirkaMatice;
        matice = new int[radky][sloupce];
        for (int i = 0; i < radky; i++) {
            for (int j = 0; j < sloupce; j++) {
                matice[i][j] = (int) ((101) * Math.random());
            }
        }
    }


Nakonec jsem to vyřešil. A vzhledem k tomu, že mi nevadí použít blok kódu i jako výstup, tak jsem využil tohoto:

Kód: Vybrat vše
    public void transponovanaMatice() {
        int[][] transponovanaMatice = new int[sloupce][radky];
        for (int i = 0; i < radky; i++) {
            for (int j = 0; j < sloupce; j++) {
                transponovanaMatice[j][i] = matice[i][j];
            }
        }
        for (int i = 0; i < sloupce; i++) {
            for (int j = 0; j < radky; j++) {
                System.out.format("%5d", transponovanaMatice[i][j]);
            }
            System.out.println("");
        }
        System.out.println("");
    }


Děkuji za rady. Ještě jsem pohledal po anglicky psaných webech a tam jsem našel obdobné metody.
Iban
Junior


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 3 návštevníků