Stampa matrice con ordinamento a spirale

di il
5 risposte

Stampa matrice con ordinamento a spirale

Buongiorno ragazzi, sto provando a fare il seguente esercizio. 

Stampare gli elementi di una matrice NxN secondo un ordinamento a spirale, partendo dalla cornice più esterna e procedendo verso l'interno. 

Ho cercato in rete ed ho visto diversi video ed esercizi già fatti ma purtroppo non riesco ancora a capire, spero che qualcuno di voi possa aiutarmi. 

Vi posto il mio codice. Ho provato a risolvere l'esercizio con 4 cicli for all'interno di una condizione while. 

#include<stdio.h>
#include<stdlib.h>

int main()
{
    const int NMAX=3;
    int matrice[NMAX][NMAX];
    int i, j;
    int l, n, m, p;
    l=0, m=0;
    p=NMAX; n=NMAX;


    for (i=0; i<NMAX; i++)
    {
         for (j=0; j<NMAX; j++)
         {
            scanf("%d", &matrice[i][j]);
         }
    }

    for (i=0; i<NMAX; i++)
    {
         for (j=0; j<NMAX; j++)
         {
            printf ("%d\t", matrice[i][j]);
         }
         printf("\n");
    }


    while(n>l && p>m)
    {
    for (i=m; i<=p; i++) /*prima riga*/
        printf("%d", matrice[l][i]);
        l++;

    for (i=l; l<=n;i++) /*ultima colonna di destra*/
        printf("%d", matrice[i][p]);
        p--;

    for (i=p; i>=m; i-- ) /*ultima riga in basso*/
        printf("%d%d", matrice[n][i]);
        n--;

    for (i=n; i>=l; i--)/*prima colonna a sinistra*/
        printf ("%d%d", matrice[i][m]);
        m++;
    }
}

5 Risposte

  • Re: Stampa matrice con ordinamento a spirale

    Ciao, domani se ho tempo mi guardo con calma il codice che hai scritto, nel frattempo se ti può essere utile ti propongo una mia soluzione che, a scanso di errori, dovrebbe funzionare per una generica matrice di ordine N:

    for(int i = 0, j = -1, I = 0, J = 1, temp, n = N; n; temp = I, I = J, J = - temp, n -= i + j == N - 1)
    {
        for(int k = n; k--; printf("%d ", m[i += I][j += J]));
    }
  • Re: Stampa matrice con ordinamento a spirale

    Grazie Nippolo per l'aiuto. 

    Purtroppo sono i primi codici che scrivo quindi ho un po' di difficoltà a capire il tuo codice. 

    Ho provato a cercare in rete e ho trovato diverse soluzioni in altri linguaggi di programmazione ma non riesco a capire la logica che c'è dietro. 

    Con il mio codice ho provato con carta e penna a "disegnare" il funzionamento dell'algoritmo solo che quando provo ad avviare il programma stampa un'enormità di numeri invece della spirale richiesta. 

  • Re: Stampa matrice con ordinamento a spirale

    Ho letto il tuo codice e credo di aver capito l'idea di fondo che volevi utilizzare, ma purtroppo ci sono alcuni errori logici, e altri presumo di distrazione, che ne minano il corretto funzionamento. Ti posto di seguito una versione corretta (o almeno così mi pare) del tuo codice:

    #include<stdio.h>
    
    #define N 5
    
    int main()
    {
        int m[N][N];
    
        for(int i = 0; i < N; ++i)
        {
            for(int j = 0; j < N; ++j)
            {
                m[i][j] = i * N + j + 1;
            }
        }
    
        for(int i = 0; i < N; ++i)
        {
            for(int j = 0; j < N; printf("%2d ", m[i][j++]));
            printf("\n");
        }
        printf("\n");
    
        for(int U = 0, D = N - 1, L = -1, R = N - 1; D >= U && R >= L;)
        {
            for(int k = ++L; k <= R; printf("%d ", m[U][k++]));
            for(int k = ++U; k <= D; printf("%d ", m[k++][R]));
            for(int k = --R; k >= L; printf("%d ", m[D][k--]));
            for(int k = --D; k >= U; printf("%d ", m[k--][L]));
        }
    
        printf("\n");
        return 0;
    }

    Non so di preciso quale sia il tuo livello, ma se confrontando i codici non riesci a renderti conto in modo autonomo dei vari errori, chiedi pure.


    P.S.
    Ho rinominato le variabili “p”, “n”, “m”, “l” rispettivamente con “R”, “D”, “L”, “U”, che stanno per Right, Down, Left, Up.

  • Re: Stampa matrice con ordinamento a spirale

    Ciao Nippolo, grazie per il tuo aiuto. Ho cercato di confrontare i due codici e sono riuscito a stampare la matrice come richiedeva l'esercizio. 

    Ho avuto un po' di difficoltà a leggerlo in quanto scrivi in un modo che non pensavo fosse possibile, per esempio inserire l'istruzione printf all'interno del ciclo for oppure dichiarare la variabile all'interno del for. 

    Penso che avrai capito che sono solo all'inizio e sto studiando da autodidatta ma nonostante ciò ho trovato, per quel che può valere,  il tuo codice molto elegante. 

    Grazie ancora per l'aiuto!

  • Re: Stampa matrice con ordinamento a spirale

    Di niente!


    Se può essere utile provo a spiegare la logica dietro al mio precedente codice:

    24/05/2023 - Nippolo ha scritto:

    for(int i = 0, j = -1, I = 0, J = 1, temp, n = N; n; temp = I, I = J, J = - temp, n -= i + j == N - 1)
    {
        for(int k = n; k--; printf("%d ", m[i += I][j += J]));
    }

    Si ipotizza di partire dall'elemento in alto a sinistra per poi proseguire in senso orario alternando 4 tipologie di tratti rettilinei:
    - da sinistra a destra, in cui i rimane costante (e quindi I=0) e j aumenta (e quindi J=1) ;
    - dall'alto in basso, in cui i aumenta (e quindi I=1) e j rimane costante (e quindi J=0) ;
    - da destra a sinistra, in cui i rimane costante (e quindi I=0) e j diminuisce (e quindi J=-1) ;
    - dal basso in alto, in cui i diminuisce (e quindi I=-1) e j rimane costante (e quindi J=0) .

    E le istruzioni

    /*
    int I = 0;
    int J = 1;
    */
    
    int temp = I;
    I = J;
    J = - temp; 

    servono appunto per modificare ciclicamente I e J nel modo sopra descritto.

    Considerata poi una generica matrice quadrata di ordine n, si osserva che la lunghezza dei suddetti tratti rettilinei parte da n e diminuisce di 1 ogni volta che l'elemento corrente (individuato dagli indici i e j) si posiziona sulla diagonale secondaria, da cui l'espressione:

    n -= i + j == N - 1;

    Ovviamente quando n diventa 0 significa che tutti gli elementi sono stati stampati e il ciclo for più esterno può essere interrotto.

    Il ciclo for interno invece si limita semplicemente a stampare gli n elementi del tratto considerato.

Devi accedere o registrarti per scrivere nel forum
5 risposte