Domanda Matrice rettangolare concentrica

sick_daiana56

Utente Bronze
17 Giugno 2019
18
2
5
21
Salve a tutti, sono nuova di questo linguaggio e avrei bisogno di una mano con un programma.
Sono tre giorni che tento di trovare una soluzione ma non vi riesco, l'esercizio è questo:

Scrivere un metodo statico matriceCornici che, dati due interi m ed n, restituisce una matrice m x n di interi formata da rettangoli concentrici con numeri crescenti a partire da 1 come nel seguente esempio m=6 e n=8;

1 1 1 1 1 1 1 1

1 2 2 2 2 2 2 1

1 2 3 3 3 3 2 1

1 2 3 3 3 3 2 1

1 2 2 2 2 2 2 1

1 1 1 1 1 1 1 1

Si assuma che m ed n siano non negatici e divisibili per 2 (cioè pari)
Scrivere un main di prova per verificare il metodo scritto.

Fino alla cornice esterna composta da tutti 1 ci sono (wow che forte) se qualcuno può darmi una mano con il resto gliene sarei grato.
 
Ciao, potresti riportare il codice del programma che hai scritto finora?
Non è niente di che, non prendermi in giro.
import java.util.Scanner;

public class Esercizio5 {

public static void main(String[] args)
{
Scanner console = new Scanner(System.in);
System.out.println("Inserisci altezza rettangolo: ");
int m = console.nextInt();
System.out.println("Inserisci larghezza rettangolo: ");
int n = console.nextInt();
int val = 0;
int[][] matrix = new int[m][n];
popolaMatrice(m,n,matrix,val);
matriciCornici(m,n,matrix);
}

public static void popolaMatrice(int m,int n,int[][] matrix,int val)
{
if(m > 0 && n > 0) //Controlla se non sono negativi.
{

if((m%2)==0 && (n%2)==0) //Controlla se sono pari.
{
if(m!=n) //Controlla se sono diversi.
{
if(m>=3 && n>=3){
val = 1;
int m2 = m;
int n2 = n;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(i == 0){ matrix[j] = 1; }
else if(i == m2-1){ matrix[j] = val; }
else if(j == 0){ matrix[j] = 1; }
else if(j == n2-1){ matrix[j] = val; }
else {
matrix[j] = 2;
}
}
}
} else { System.out.println("Non puoi creare un rettangolo con altezza e larghezza uguali."); }
} else { System.out.println("Sono dispari, non posso continuare."); }
} else if(m == 0 || n == 0) { System.out.println("Sono uguali a zero, non posso continuare."); }
else { System.out.println("Sono negativi, non posso continuare."); }
}
}
public static void matriciCornici(int m, int n,int matrix[][])
{
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
System.out.println(matrix[j]+" ");
System.out.println();
}
System.out.println("\n");
}
}
}


 
Ultima modifica:
Io personalmente costruirei una funzione ricorsiva per ogni livello di cornice, ma che all'interno abbia dei for per disegnare il livello attuale (per non complicare troppo le cose che eccessive ricorsioni).

In pseudo codice:


Codice:
disegnaCornice(livello_di_partenza, m, n, matrix[][]){
    if(livello_di_partenza>m/2){ //se il livello_di_partenza supera il valore della meta' della lunghezza
                                 //di un lato della matrice, allora vuol dire che l'ho disegnata tutta
        return;
    }
    int i=livello_di_partenza-1; //indica la riga cornice da cui partire
    int j=livello_di_partenza-1; //indica la colonna cornice da cui partire
   
    for(; i<m; i++){    
        matrix[i][j]=livello_di_partenza; //disegno il lato sinistro della cornice
    }
   
    for(i=0; i<m; i++){
        matrix[i][n-livello_di_partenza]=livello_di_partenza; //disegno il lato destro della cornice
    }
   
    for(; j<n; j++){
        matrix[livello_di_partenza-1][j]= livello_di_partenza; //disegno cornice superiore
    }
   
    for(j=0; j<n; j++){
        matrix[n-livello_di_partenza][j]= livello_di_partenza; //disegno cornice inferiore
    }
   
    disegnaCornice(livello_di_partenza++, m, n, matrix);
}

Non e' il codice migliore del mondo, ma secondo me e' adeguato per svolgere questo esercizio e mettere un minimo di ricorsione per stimolare di piu' questo tipo di programmazione.
Questo esercizio puo' essere svolto in modi diversi: completamente iterativo o completamente ricorsivo o ibrido come ho scritto io. Scegli tu! Se qualcosa non e' chiaro dimmi pure
(Ho usato uno pseudo codice, ma in realta'la sintassi del corpo della funzione e' identica a Java.)
Ps. ovviamente fai qualche prova perche' non vorrei mi fosse sfuggito qualcosa, concettualmente pero' funziona :D
 
Io personalmente costruirei una funzione ricorsiva per ogni livello di cornice, ma che all'interno abbia dei for per disegnare il livello attuale (per non complicare troppo le cose che eccessive ricorsioni).

In pseudo codice:


Codice:
disegnaCornice(livello_di_partenza, m, n, matrix[][]){
    if(livello_di_partenza>m/2){ //se il livello_di_partenza supera il valore della meta' della lunghezza
                                 //di un lato della matrice, allora vuol dire che l'ho disegnata tutta
        return;
    }
    int i=livello_di_partenza-1; //indica la riga cornice da cui partire
    int j=livello_di_partenza-1; //indica la colonna cornice da cui partire
   
    for(i; i<m; i++){    
        matrix[i][j]=livello_di_partenza; //disegno il lato sinistro della cornice
    }
   
    for(i=0; i<m; i++){
        matrix[i][n-livello_di_partenza]=livello_di_partenza; //disegno il lato destro della cornice
    }
   
    for(; j<n; j++){
        matrix[livello_di_partenza-1][j]= livello_di_partenza; //disegno cornice superiore
    }
   
    for(j=0; j<n; j++){
        matrix[n-livello_di_partenza][j]= livello_di_partenza; //disegno cornice inferiore
    }
   
    disegnaCornice(livello_di_partenza++, m, n, matrix[][]);
}

Non e' il codice migliore del mondo, ma secondo me e' adeguato per svolgere questo esercizio e mettere un minimo di ricorsione per stimolare di piu' questo tipo di programmazione.
Questo esercizio puo' essere svolto in modi diversi: completamente iterativo o completamente ricorsivo o ibrido come ho scritto io. Scegli tu! Se qualcosa non e' chiaro dimmi pure
(Ho usato uno pseudo codice, ma in realta'la sintassi del corpo della funzione e' identica a Java.)
Ps. ovviamente fai qualche prova perche' non vorrei mi fosse sfuggito qualcosa, concettualmente pero' funziona :D
Ti dico gli errori che mi da, faccio prima:
  1. Nel primo ciclo for mi dice che i è sbagliata, ovvero non può stare da sola cosi. O ci si assegna un valore o niente..
  2. livello_di_partenza parte da 0 o da un numero specifico?
  3. ho visto che sotto inserisci nel metodo disegnaCornice "livello_di_partenza++", a cosa punti di preciso usando ciò? (Non posso chiamare disegnaCornice dentro il metodo disegnaCornice :asd: di solito lo si inserisce nel main.
Ho fatto delle piccole modifiche al codice se vuoi vederle:

public static void main(String[] args)
{
int livello_di_partenza = 0;
Scanner console = new Scanner(System.in);
System.out.println("Inserisci altezza rettangolo: ");
int m = console.nextInt();
System.out.println("Inserisci larghezza rettangolo: ");
int n = console.nextInt();
int[][] matrix = new int[m][n];
disegnaCornice(livello_di_partenza++,m,n,matrix);
}

public static void disegnaCornice(int livello_di_partenza,int m,int n,int matrix[][]){
if(livello_di_partenza>m/2){ //se il livello_di_partenza supera il valore della meta' della lunghezza
//di un lato della matrice, allora vuol dire che l'ho disegnata tutta
return;
}
int i=livello_di_partenza-1; //indica la riga cornice da cui partire
int j=livello_di_partenza-1; //indica la colonna cornice da cui partire
for(i=livello_di_partenza-1; i<m; i++){
matrix[j]=livello_di_partenza; //disegno il lato sinistro della cornice
}

for(i; i<m; i++){
matrix[n-livello_di_partenza]=livello_di_partenza; //disegno il lato destro della cornice
}

for(; j<n; j++){
matrix[livello_di_partenza-1][j]= livello_di_partenza; //disegno cornice superiore
}

for(j=0; j<n; j++){
matrix[n-livello_di_partenza][j]= livello_di_partenza; //disegno cornice inferiore
}
}
 
Si presuppone che tu chiami disegnaCornice dal mail passando i parametri richiesti, ovvero, nel tuo caso di esempio:
disegnaCornice(1, 6, 8, matrix[][])

Cosa intendi inoltre con "Non posso chiamare disegnaCornice dentro disegnaCornice"? Non vi hanno spiegato la ricorsione?
 
Si presuppone che tu chiami disegnaCornice dal mail passando i parametri richiesti, ovvero, nel tuo caso di esempio:
disegnaCornice(1, 6, 8, matrix[][])

Cosa intendi inoltre con "Non posso chiamare disegnaCornice dentro disegnaCornice"? Non vi hanno spiegato la ricorsione?
Guarda grazie per avermi informata a riguardo, no sto studiando da autodidatta e sono arrivata al for giusto per farti capire, non sono tanto skillata :asd: Però se vado a metterlo non mi funziona uguale, sarà che non l'ho mai usato e non sometterci mano.

Per questo invece riesci a darmi una mano? a che valore corrisponde i in quel momento? A quello scritto poco sopra : int i=livello_di_partenza-1; ?

for(i; i<m; i++){
matrix[n-livello_di_partenza]=livello_di_partenza; //disegno il lato destro della cornice
}
 
Da quel che posso intuire sei alle prime armi, e avendo studiato fino al for mi chiedo per quale motivo tu stia facendo un esercizio che implica l'utilizzo di array bidimensionali.
 
Da quel che posso intuire sei alle prime armi, e avendo studiato fino al for mi chiedo per quale motivo tu stia facendo un esercizio che implica l'utilizzo di array bidimensionali.
Da quanto ho capito le matrici non sono altro che due for messe insieme gestite per riga e per colonna, il punto è che non riesco a livello di logica ad arrivare alla soluzione, il codice lo so (o almeno penso di saperlo) mi manca la logica purtroppo.
Sembra che vi stia dicendo di essere ritardata. Però ok.
In ogni caso mi è stato assegnato insieme ad altri esercizi di logica da un mio amico esperto di programmazione.. gli altri sono riuscita a farli ma questo proprio zero.
 
Esattamente, viene generata prima la riga e poi la colonna, però secondo me ti stai complicando la vita con un esercizio non semplice.

Esempio di stampa di una matrice:
Java:
 public class tema39
 {
     public static void visualizzaMatrice (int[][] M)
     {
         for (int i = 0; i < M.length; i++)
         {
             for (int j = 0; j < M[i].length; j++)
                 System.out.print(M[i][j] + " ");
             System.out.println();
         }
     }  /* Applicazione di prova */ 
    
     public static void main(String[] args)
     {
         int[][] Q = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};  /*il metodo  * visualizzerà la matrice per quello che realmente è, cioè una struttura bidimensionale 3x3*/
         visualizzaMatrice ( Q );
     }
 }
 
  • Mi piace
Reazioni: sick_daiana56
Esattamente, viene generata prima la riga e poi la colonna, però secondo me ti stai complicando la vita con un esercizio non semplice.

Esempio di stampa di una matrice:
Java:
 public class tema39
{
     public static void visualizzaMatrice (int[][] M)
     {
         for (int i = 0; i < M.length; i++)
         {
             for (int j = 0; j < M[i].length; j++)
                 System.out.print(M[i][j] + " ");
             System.out.println();
         }
     }  /* Applicazione di prova */
   
     public static void main(String[] args)
     {
         int[][] Q = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};  /*il metodo  * visualizzerà la matrice per quello che realmente è, cioè una struttura bidimensionale 3x3*/
         visualizzaMatrice ( Q );
     }
}
Si ma cosi è stupidino come esercizio, poi ormai ho il pallino in testa e voglio finire questo.. Se riuscite ad aiutarmi sarebbe il top.
 
Lasciando perdere la soluzione di prima dato che ancora non hai studiato la ricorsione, trasformiamo la soluzione in iterativa:
Concettualmente io ho ragionato cosi': prendo ogni cornice come un livello (la prima sara' livello 1). Gli estremi di tale cornice sono i punti (0,0), (0,n-1), (0,m-1).
Il "percorso" che posso seguire quindi e' disegnare da (0,0) a (0,m-1) con un due for (lato sinistro) , poi da (0,0) a (0, n-1) ( lato orizzontale superiore), poi da (0, n-1) a (m-1, n-1)(lato destro) ed infine da (m-1, 0) a (m-1, n-1) lato inferiore.

Questa operazione va rifatta per ogni livello di cornice.

Per farti arrivare alla soluzione:
riscrivi il ragionamento per la seconda cornice e vedi che trovi un modo per "accorpare" i livelli e ridurre il codice
Se ti va scrivi il ragionamento della cornice due qui, cosi' possiamo analizzarlo insieme
 
  • Mi piace
Reazioni: ArrackHack
È molto facile e molto corto, devi solo capire bene cosa fare. Ti abbozzo uno pseudocodice:
Codice:
matrix = nuova matrice nxm (hint: array bidimensionale)
per ogni cella della matrice (hint: due for concatenati che scorrono righe e colonne)
    valore = min { riga_cella, colonna_cella, riga_cella - riga_massima - 1, collonna_cella - colonna_massima - 1 } (hint: il -1 è relativo all'indicizzazione che parte da 0)
    cella = valore + 1 (hint: cella è matrix[qualcosa][qualcos'altro] e li hai usati nella riga precedente)
return matrix

Mi è difficile spiegarti l'algoritmo in modo più vago, così come mi è difficile essere più preciso senza scriverti praticamente tutto il codice (sono 4-5 righe).
 
valore = min { riga_cella, colonna_cella, riga_cella - riga_massima - 1, collonna_cella - colonna_massima - 1 } (hint: il -1 è relativo all'indicizzazione che parte da 0)
Scusa se ti chiedo di più a riguardo ma questa riga in particolare non mi funziona ne mi sembra niente che io abbia studiato recentemente..
È normale che dopo min ci siano delle parentesi graffe con dentro delle variabili cosi o hanno un senso particolare? Devo cambiare il codice in un altro?
O per caso devo inizializzarla in qualche modo? Se cosi, se potresti mostrarmi come mi saresti ancora più di aiuto.
Grazie in anticipo. :ruloz:
 
Scusa se ti chiedo di più a riguardo ma questa riga in particolare non mi funziona ne mi sembra niente che io abbia studiato recentemente..
È normale che dopo min ci siano delle parentesi graffe con dentro delle variabili cosi o hanno un senso particolare? Devo cambiare il codice in un altro?
O per caso devo inizializzarla in qualche modo? Se cosi, se potresti mostrarmi come mi saresti ancora più di aiuto.
Grazie in anticipo. :ruloz:
È pseudocodice per dire "prendi il minimo dell'insieme che contiene...". Ho volutamente evitato di scrivere codice Java per lasciarti risolvere l'esercizio in modo relativamente autonomo. Hai detto che era la logica il problema e mi sono limitato a darti quella. Se non riesci comunque a risolverlo, a me non costa niente scriverti direttamente la soluzione in Java.
 
  • Mi piace
Reazioni: sick_daiana56
Risolto. Lascio il codice sotto spoiler se qualcuno volesse la soluzione oltre a me in futuro:

public class matriciCornici {

public static void main(String[] args) {

int[][] cornici = matriceCornici(6, 8);

for (int i = 0; i < cornici.length; i++) {
for (int j = 0; j < cornici.length; j++)
System.out.print(cornici[j] + " ");
System.out.println();
}
}

public static int[][] matriceCornici(int righe, int colonne) {

int[][] matrice = new int[righe][colonne];
int dimensioneMinore = Math.min(righe, colonne);
for (int i = 0; i < righe; i++)
matrice = new int[colonne];

for (int i = 0; i < dimensioneMinore / 2 + 1; i++)
for (int r = i; r < righe - i; r++)
for (int c = i; c < colonne - i; c++)
if (r == i || r == righe - i - 1 || c == i || c == colonne - i - 1)
matrice[r][c] = i + 1;

return matrice;

}
}



Grazie a tutti per l'aiuto!
 
Io l'avevo pensata così
Java:
public static int[][] draw(int n, int m) {
    int[][] matrix = new int[m][n];
                                                                                   
    for (int i = 0; i < m; ++i)
        for (int j = 0; j < n; ++j)
            matrix[i][j] = Collections.min(Arrays.asList(i, j, m-i-1, n-j-1)) + 1;
                                                                                   
    return matrix;
}