Problema con la diagonale secondaria!

di il
7 risposte

Problema con la diagonale secondaria!

Ciao, ho fatto un programma in cui data una matrice m, devo allocare dinamicamente una matrice che ha le diagonali scambiate. Quindi la diagonale principale deve essere scambiata con la diagonale secondaria. Il mio programma funziona correttamente solo per una matrice 3 x 3, ma non per matrici con altre dimensioni. Il problema sta nel fatto che non riesco a trovare la formulina che mi riconosce un elemento della diagonale secondaria, cosi me lo scambia poi con elemento della diagonale principale. In questo caso ho utilizzato
m->cols + (2 * r) - 1
per identificare l'indice di ogni elemento della diagonale secondaria, cosi mentre scorro la matrice quando incontro un elemento della diagonale principale lo scambio con un elemento della diagonale secondaria. Sono abbastanza sicuro del mio programma che vada bene, però c'è quella piccola imperfezione che non riesco a capire come modificarla. Qualcuno per favore mi dà una mano?
Questo è il mio codice:
file.h

#if !defined MATRIX_H
#define MATRIX_H
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define DIMENSIONE ris->rows * ris->cols
struct matrix{
	size_t rows, cols;
	double *data;
};

extern struct matrix *scambia_diagonali(const struct matrix *m);



#endif
file.c
#include "matrix.h"

struct matrix *scambia_diagonali(const struct matrix *m){
	if (m == NULL){
		return NULL;
	}

	struct matrix *ris = malloc(sizeof(struct matrix));
	ris->cols = m->cols;
	ris->rows = m->rows;
	ris->data = malloc(DIMENSIONE * sizeof(double));

	double temp; //variabile temporanea
	int centrale = ((m->cols - 1) / 2);
	int colonne = m->cols % 2; //se c'è elemento centrale

	//alloco matrice originale
	for (unsigned int r = 0; r < m->rows; r++){
		for (unsigned int c = 0; c < m->cols; c++){
			int indice = (m->cols * r) + c;
			ris->data[indice] = m->data[indice];
		}
	}

	for (unsigned int r = 0; r < m->rows; r++){
		for (unsigned int c = 0; c < m->cols; c++){
			int indice = (m->cols * r) + c;
			if (r == c){
				if (colonne != 0 && r == centrale && c == centrale){		//caso particolare elemento centrale, non scambio
					continue;
				}
				//faccio scambio perchè ho un elemento della diagonale principale
				temp = m->data[indice];
				ris->data[indice] = m->data[m->cols + (2 * r) - 1];
				ris->data[m->cols + (2 * r) - 1] = temp;
				continue;
			}
		}
	}

	return ris;
}
main.c
#include "matrix.h"

int main(){
	double data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	struct matrix m = { 3, 3, data };

	struct matrix *ris = scambia_diagonali(&m);

	return 0;
}

7 Risposte

  • Re: Problema con la diagonale secondaria!

    Prima di parlare del problema, perché utilizzi una struttura per la tua matrice e non una semplice matrice tipo
    
    	double mm[3][3] = 
    	{
    		{ 1, 2, 3 },
    		{ 4, 5, 6 },
    		{ 7, 8, 9 }
    	};
    
  • Re: Problema con la diagonale secondaria!

    Perchè il mio professore ci ha caldamente consigliato di usare la tecnica del singolo puntatore per esercizi con matrici e perciò di evitare quell'altra strada..
    Al di là di questo, la consegna del problema precedentemente mi obbliga di risolvere il problema partendo da quella struct che ho scritto nel file.h..
  • Re: Problema con la diagonale secondaria!

    Ok ... data l'esigenza didattica, penso che dovresti usare questo codice nella for
    
    			int indice = (ris->cols * r) + c;
    			if (r == c) {
    				int indice2 = (ris->cols * r) + (ris->cols - c - 1);
    			
    				temp = ris->data[indice];
    				ris->data[indice] = ris->data[indice2];
    				ris->data[indice2] = temp;
    			}
    
    non tenendo conto della questione dell'elemento centrale che, se esiste, viene scambiato con se stesso senza problemi.

    Ho visto che nella funzione usi, a volte ris-> e a volte m-> ... se utilizzi una struttura locale ris->, fallo sempre dopo averla copiata da m->
  • Re: Problema con la diagonale secondaria!

    Ok grazie mille! Si effettivamente hai ragione, spesso uso anche m->, grazie per il consiglio!
  • Re: Problema con la diagonale secondaria!

    Oppure non usare proprio ris
  • Re: Problema con la diagonale secondaria!

    Se la consegna dell'esercizio è quella ok, ma avete chiesto al prof perché non vuole che usiate i puntatori doppi? Si tratta di un argomento che non avete ancora approfondito oppure il motivo è un altro?

    In ogni caso io farei qualcosa del genere:
    #include<stdio.h>
    #include<stdlib.h>
    
    struct matrix
    {
        unsigned int rows;
        unsigned int cols;
        int *data;
    };
    
    unsigned int indice(unsigned int i, unsigned int j, unsigned int rows)
    {
        return i * rows + j;
    }
    
    struct matrix* scambia_diagonali(const struct matrix *m)
    {
        if(m == NULL)
        {
            return NULL;
        }
        struct matrix *ris = malloc(sizeof(struct matrix));
        ris->rows = m->rows;
        ris->cols = m->cols;
        ris->data = malloc(ris->rows * ris->cols * sizeof(double));
        unsigned int i;
        int temp;
        for(i = 0; i < m->rows * m->cols; ++i)
        {
            ris->data[i] = m->data[i];
        }
        for(i = 0; i < m->rows; ++i)
        {
            temp = ris->data[indice(i, i, m->rows)];
            ris->data[indice(i, i, m->rows)] = ris->data[indice(i, m->cols - i - 1, m->rows)];
            ris->data[indice(i, m->cols - i - 1, m->rows)] = temp;
        }
        return ris;
    }
    
    void mostra_matrice(const struct matrix *m)
    {
        for(unsigned int i = 0; i < m->rows; ++i)
        {
            for(unsigned int j = 0; j < m->cols; ++j)
            {
                printf("%d\t", m->data[indice(i, j, m->rows)]);
            }
            printf("\n");
        }
    }
    
    int main()
    {
        int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        struct matrix m = {3, 3, data};
        mostra_matrice(&m);
        printf("\n");
        struct matrix *ris = scambia_diagonali(&m);
        mostra_matrice(ris);
        return 0;
    }
  • Re: Problema con la diagonale secondaria!

    Nippolo ha scritto:


    Se la consegna dell'esercizio è quella ok, ma avete chiesto al prof perché non vuole che usiate i puntatori doppi? Si tratta di un argomento che non avete ancora approfondito oppure il motivo è un altro?
    Di norma gli array multidimensionali hanno performance peggiori rispetto alla controparte con una sola dimensione, però mi sembra "eccessivo" proibire addirittura di usarli quando si sta ancora prendendo confidenza col linguaggio
Devi accedere o registrarti per scrivere nel forum
7 risposte