IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: spirálová matice

Aktivity
Avatar
Zuzana K
Člen
Avatar
Zuzana K:12.12.2018 10:22

Zdravím, potřebovala bych pomoc s úkolem. Pomocí dvojrozměrného pole mám vytvořit spirálovou matici. Začátek bude v levém horním rohu, půjde směrem ke středu po spirále, ve směru hodinových ručiček. Vstupem je počet sloupců a počet řádku matice.

Výstup např.

1 2 3

10 11 4

9 12 5

8 7 6

 
Odpovědět
12.12.2018 10:22
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Zuzana K
DarkCoder:12.12.2018 13:51

Vytvoř si cyklickou proměnnou nabývající hodnot 1-4. Proměnná představuje směr ve kterém se budeš přesouvat na následující prvek ve 2D poli. 1 - posun vpravo, 2 - posun dolů, 3 - posun vlevo, 4 - posun nahoru. Dále si vytvoř dvě proměnné X a Y představující souřadnice testovaného prvků 2D pole. X a Y inicializuj na nulu, tím nastavit levý horní roh 2D pole. Cyklickou proměnnou inicializuj na 1. Tedy budeš postupovat doprava. Cyklická proměnná se bude měnit o +1 pokaždé když se dostaneš mimo rozsah pole nebo na prvek který už byl testován resp ohodnocen. Celý cyklus testování končí když nemůžes otestovat hodnotu nebo když počet prvků dosáhl součinu velikostí 2D pole. Tím zajistís vždy postup po okraji 2D pole ve směru vpravo, tedy ve tvaru šroubovice.

Nahoru Odpovědět
12.12.2018 13:51
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Alesh
Tvůrce
Avatar
Alesh:17.3.2019 1:07

Velmi zajímavá úloha. Učím se OOP ta jsem si to zkusil naprogramovat a zdá se, že se to povedlo. ;-)

main je jen takhle jednoduchý:

public static void main(String[] args) {
Matice matice = new Matice(4, 3); //vytvoří matici o 4 řádcích a 3 sloupcích
matice.naplnMa­tici(); //naplní matici do spirály
matice.vypisMa­ticiDoKonzole(); //vypíše matici do konzole
}

třída Matice vypadá takto:

public class Matice {
private int pocetRadku; //pocet radku matice
private int pocetSloupcu; //pocet sloupku matice
private int[][] matice; //matice
private int smer = 0; //0 = doprava, 1 = dolu, 2 = doleva, 3 = nahoru
private int r = 0; //svisla souradnice shora dolu
private int c = 0; //vodorovna souradnice zleva doprava

/**
* vytvori 2D matici se zvolenym poctem radku a sloupcu
* @param pocetRadku pocet radku matice
* @param pocetSloupcu pocet sloupcu matice
*/
public Matice(int pocetRadku, int pocetSloupcu){
this.pocetRadku = pocetRadku;
this.pocetSloupcu = pocetSloupcu;
matice = new int[pocetRadku][po­cetSloupcu];
}

/**
* vypise spiralovou matici do konzole
*/
public void vypisMaticiDo­Konzole(){
for(int i = 0; i < matice.length; i++){
for(int j = 0; j < matice[i].length; j++){
System.out.prin­t(matice[i][j] + " ");
}
System.out.prin­tln();
}
}

/**
* naplni spiralovou matici cisly od 1 do m*n
*/
public void naplnMatici(){
for(int i = 0; i < pocetPrvku(); i++){
matice[r][c] = i + 1;
nastavSmerPlneni();
nastavSouradni­ceDalsihoPrvku();
}
}

//nastavi smer plneni pro dalsi prvek
private void nastavSmerPlneni(){
switch(smer){
case 0:
if(c == matice[0].length - 1){
zmenSmer();
break;
}
else if (matice[r][c + 1]!=0)
zmenSmer();
break;
case 1:
if(r == matice.length - 1){
zmenSmer();
break;
}
else if (matice[r + 1][c]!=0)
zmenSmer();
break;
case 2:
if(c == 0){
zmenSmer();
break;
}
else if (matice[r][c - 1]!=0)
zmenSmer();
break;
case 3:
if(r == 0){
zmenSmer();
break;
}
else if (matice[r - 1][c]!=0)
zmenSmer();
break;
}
}

//upravi souradnice
private void nastavSouradni­ceDalsihoPrvku(){
switch(smer){
case 0:
c++;
break;
case 1:
r++;
break;
case 2:
c--;
break;
case 3:
r--;
break;
}
}

//zjisti pocet prvku matice (soucin poctu radku a sloupcu)
private int pocetPrvku(){
return (matice[0].length * matice.length);
}

//meni smer plneni matice doprava -> dolu -> doleva -> nahoru atd.
private void zmenSmer(){
if(smer == 3) //3 = smer nahoru, nutno nastavit zpatky na 0 = doprava
smer = 0;
else
smer++;
}
}

Budu rád, když k mému kódu dá někdo zkušenější konstruktivní připomínky.

 
Nahoru Odpovědět
17.3.2019 1:07
Avatar
Jurajs
Člen
Avatar
Odpovídá na Alesh
Jurajs:17.3.2019 9:56

Ahoj, jeste nez ti da na to nekdo kritiku, tak si dej kod mezi znacky </> protoze tohle nikdo lustit nebude....Diky ;)

 
Nahoru Odpovědět
17.3.2019 9:56
Avatar
Alesh
Tvůrce
Avatar
Odpovídá na Jurajs
Alesh:17.3.2019 10:22

Člověk se furt učí, tuto možnost jsem nepostřehl, moje chyba, dík za upozornění!

Main:

public static void main(String[] args) {
        Matice matice = new Matice(4, 3);       //vytvoří matici o 4 řádcích a 3 sloupcích
        matice.naplnMatici();   //naplní matici do spirály
        matice.vypisMaticiDoKonzole();  //vypíše matici do konzole
    }

Matice:

public class Matice {
    private int pocetRadku; //pocet radku matice
    private int pocetSloupcu;   //pocet sloupku matice
    private int[][] matice; //matice
    private int smer = 0; //0 = doprava, 1 = dolu, 2 = doleva, 3 = nahoru
    private int r = 0;  //svisla souradnice shora dolu
    private int c = 0;  //vodorovna souradnice zleva doprava

    /**
     * vytvori 2D matici se zvolenym poctem radku a sloupcu
     * @param pocetRadku pocet radku matice
     * @param pocetSloupcu pocet sloupcu matice
     */
    public Matice(int pocetRadku, int pocetSloupcu){
        this.pocetRadku = pocetRadku;
        this.pocetSloupcu = pocetSloupcu;
        matice = new int[pocetRadku][pocetSloupcu];
    }

    /**
     * vypise spiralovou matici do konzole
     */
    public void vypisMaticiDoKonzole(){
        for(int i = 0; i < matice.length; i++){
            for(int j = 0; j < matice[i].length; j++){
                System.out.print(matice[i][j] + " ");
            }
            System.out.println();
        }
    }

    /**
     * naplni spiralovou matici cisly od 1 do m*n
     */
    public void naplnMatici(){
        for(int i = 0; i < pocetPrvku(); i++){
            matice[r][c] = i + 1;
            nastavSmerPlneni();
            nastavSouradniceDalsihoPrvku();
        }
    }

    //nastavi smer plneni pro dalsi prvek
    private void nastavSmerPlneni(){
        switch(smer){
            case 0:
                if(c == matice[0].length - 1){
                    zmenSmer();
                    break;
                }
                else if (matice[r][c + 1]!=0)
                    zmenSmer();
                break;
            case 1:
                if(r == matice.length - 1){
                    zmenSmer();
                    break;
                }
                else if (matice[r + 1][c]!=0)
                    zmenSmer();
                break;
            case 2:
                if(c == 0){
                    zmenSmer();
                    break;
                }
                else if (matice[r][c - 1]!=0)
                    zmenSmer();
                break;
            case 3:
                if(r == 0){
                    zmenSmer();
                    break;
                }
                else if (matice[r - 1][c]!=0)
                    zmenSmer();
                break;
        }
    }

    //upravi souradnice
    private void nastavSouradniceDalsihoPrvku(){
        switch(smer){
            case 0:
                c++;
                break;
            case 1:
                r++;
                break;
            case 2:
                c--;
                break;
            case 3:
                r--;
                break;
        }
    }

    //zjisti pocet prvku matice (soucin poctu radku a sloupcu)
    private int pocetPrvku(){
        return (matice[0].length * matice.length);
    }

    //meni smer plneni matice doprava -> dolu -> doleva -> nahoru atd.
    private void zmenSmer(){
        if(smer == 3)   //3 = smer nahoru, nutno nastavit zpatky na 0 = doprava
            smer = 0;
        else
            smer++;
    }
}
 
Nahoru Odpovědět
17.3.2019 10:22
Avatar
Jurajs
Člen
Avatar
Odpovídá na Alesh
Jurajs:17.3.2019 11:54

V pohodě....jen jsem upozorňoval ;)

 
Nahoru Odpovědět
17.3.2019 11:54
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.