Problema selection sort
Ragazzi buongiorno,
a marzo dovrei fare l'esame di elementi di informatica e avrei dei problemi con l'allocazione dinamica in particolare un esercizio mi chiede di ordinare la diagonale principale di una array bidimensionale in modo crescente questo è il mio programma:
void ordinamento(int mat[][max],int dim)
{
int pos;
int temp;
int min;
int i;
int j;
for(i=0;i
min=mat;
pos=i;
for(j=i+1;j
if(mat[j][j]
mat[j][j]=min;
pos=j;
}
}
temp=mat;
mat=mat[pos][pos];
mat[pos][pos]=temp;
}
chiaramente a monte del mio programma ho definito la costante max;
il programma non dà problemi di compilazione ma quando vado ad inserire la matrice
1 1
1 -5
dovrebbe stampare a video la matrice:
-5 1
1 1
invece stampa a video la matrice
1 1
1 1
Qualcuno puo' aiutarmi ?ho controllato anche la soluzione e non noto differenze con il mio programma.
Grazie mille per la disponibilità.
a marzo dovrei fare l'esame di elementi di informatica e avrei dei problemi con l'allocazione dinamica in particolare un esercizio mi chiede di ordinare la diagonale principale di una array bidimensionale in modo crescente questo è il mio programma:
void ordinamento(int mat[][max],int dim)
{
int pos;
int temp;
int min;
int i;
int j;
for(i=0;i
pos=i;
for(j=i+1;j
pos=j;
}
}
temp=mat;
mat=mat[pos][pos];
mat[pos][pos]=temp;
}
chiaramente a monte del mio programma ho definito la costante max;
il programma non dà problemi di compilazione ma quando vado ad inserire la matrice
1 1
1 -5
dovrebbe stampare a video la matrice:
-5 1
1 1
invece stampa a video la matrice
1 1
1 1
Qualcuno puo' aiutarmi ?ho controllato anche la soluzione e non noto differenze con il mio programma.
Grazie mille per la disponibilità.
Risposte
"michele1239":
Qualcuno puo' aiutarmi ?ho controllato anche la soluzione e non noto differenze con il mio programma.
Sei sicuro? Prova ad eseguire quel codice tu con carta e penna.
l'ho controllare una ventina di volte cercando delle differenze,ma non ne trovo (anche se ci sono visto che la soluzione funziona)
potresti dirmi dove sbaglio?
potresti dirmi dove sbaglio?
Il libro potrebbe avere errori di stompa, cerca invece l'errore nel tuo codice.

potresti darmi un indizio su dove potrebbe essere l'errore?
potrebbe anche essere un problema di indici. prova con una matrice 3x3 o 4x4 e vedi cosa succede.
se usi codeblocks puoi fare i debug ed eseguirlo passo passo
se usi codeblocks puoi fare i debug ed eseguirlo passo passo
Non l'ho provato, ma ad occhio l'errore potrebbe essere qui
perchè nel tuo esempio sostituisci mat[j][j](che è uguale a -5) con il minimo (min=mat=1) perdendo quindi il valore -5. Perciò lo scambio successivo con la variabile pos=j la fai tra 1 e 1.
"michele1239":
if(mat[j][j]<min){ mat[j][j]=min; pos=j;
perchè nel tuo esempio sostituisci mat[j][j](che è uguale a -5) con il minimo (min=mat=1) perdendo quindi il valore -5. Perciò lo scambio successivo con la variabile pos=j la fai tra 1 e 1.
"mide":
Non l'ho provato, ma ad occhio l'errore potrebbe essere qui
[quote="michele1239"]
if(mat[j][j]<min){ mat[j][j]=min; pos=j;
perchè nel tuo esempio sostituisci mat[j][j](che è uguale a -5) con il minimo (min=mat=1) perdendo quindi il valore -5. Perciò lo scambio successivo con la variabile pos=j la fai tra 1 e 1.[/quote]
come dovrei modificare il codice?
posto la soluzione del professore, io non trovo differenze con il mio codice(sarò cieco?!?!?)
//funzione che ordina la diagonale principale
void ordinaDiagonale(int mat[][MAXNUM], int dim) {
int temp, min;
int i, j, pos;
for(i=0; i
min=mat;
pos=i;
for (j=i+1;j
if (mat[j][j]
min=mat[j][j];
pos=j;
}
}
temp=mat;
mat=mat[pos][pos];
mat[pos][pos]=temp;
}
}
//funzione che ordina la diagonale principale
void ordinaDiagonale(int mat[][MAXNUM], int dim) {
int temp, min;
int i, j, pos;
for(i=0; i
pos=i;
for (j=i+1;j
pos=j;
}
}
temp=mat;
mat=mat[pos][pos];
mat[pos][pos]=temp;
}
}
"michele1239":
(sarò cieco?!?!?)
No, semplicemente non hai riletto il tuo codice, altrimenti avresti notato quell'assegnamento invertito.

"Albesa81":
[quote="michele1239"](sarò cieco?!?!?)
No, semplicemente non hai riletto il tuo codice, altrimenti avresti notato quell'assegnamento invertito.

l'ho riletto,ma ripeto non trovo l'errore...
Ohibò...
Che cosa fa
E invece che cosa fa
Che cosa fa
min=mat[j][j];?
E invece che cosa fa
mat[j][j]=min;?
il primo assegna al minimo il valore in posizione j,j.
il secondo assegna al valore in posizione j,j il valore del minimo.
il secondo assegna al valore in posizione j,j il valore del minimo.
grazie mille per la pazienza credo di aver capito!!
potresti darmi qualche consiglio su come evitare certi errori?
potresti darmi qualche consiglio su come evitare certi errori?
"michele1239":
grazie mille per la pazienza credo di aver capito!!
Ah, meno male

"michele1239":
potresti darmi qualche consiglio su come evitare certi errori?
Gli errori capitano a tutti, però quando le cose non ti tornano rileggi criticamente ciò che hai scritto invece di cercare le differenze con soluzioni esterne

per quando fai l'assegnazione puoi ricordarti come si scrive in pseudocodice
a=b;
a <-- b ;
il valore di b va in a
comunque l'errore c'è (quasi) sempre.
considera che quando si scrive codice per lavoro, metà del tempo è dedicato allo sviluppo e l'altra metà al debug (quando va bene)
di solito se un programmatore scrive un codice che compila al primo tentativo allora inizia a preoccuparsi seriamente XD
a=b;
a <-- b ;
il valore di b va in a
comunque l'errore c'è (quasi) sempre.
considera che quando si scrive codice per lavoro, metà del tempo è dedicato allo sviluppo e l'altra metà al debug (quando va bene)
di solito se un programmatore scrive un codice che compila al primo tentativo allora inizia a preoccuparsi seriamente XD
Al di là del codice, ho qualche commento generale:
[list=1][*:2v72ul1w] Il tuo codice non fa alcuna allocazione dinamica. Inoltre, nel caso invece in cui il main la faccia, ti troveresti o con uno spreco di memoria, oppure con un bug piuttosto difficile da notare. In generale, trovo che il metodo usato dal tuo professore non sia sempre la scelta migliore. Un esempio di approccio differente:
[*:2v72ul1w] Il C non ha mai richiesto che le variabili fossero definite ad inizio funzione, quello che richiedeva nello standard del 1989 era che venissero definite ad inizio del blocco in cui "vivevano". Questa richiesta non è più necessaria dallo standard del 1999 in poi. Per esempio, questo codice, equivalente al tuo, viene tranquillamente compilato da gcc con l'opzione [inline]-ansi[/inline]
[list=1][*:2v72ul1w] Il tuo codice non fa alcuna allocazione dinamica. Inoltre, nel caso invece in cui il main la faccia, ti troveresti o con uno spreco di memoria, oppure con un bug piuttosto difficile da notare. In generale, trovo che il metodo usato dal tuo professore non sia sempre la scelta migliore. Un esempio di approccio differente:
#include <stdio.h> #include <stdlib.h> #define MAXDIM 1024 // funzione che ordina la diagonale principale void ordinaDiagonale( int mat[], int dim ) { for ( int i = 0; i < dim * dim; i += dim + 1 ) { int pos = i; int min = mat[i]; for ( int j = i + dim + 1; j < dim * dim; j += dim + 1 ) { if ( mat[j] < min ) { min = mat[j]; pos = j; } } { /* SWAP( mat[i], mat[pos] ) */ int temp = mat[i]; mat[i] = mat[pos]; mat[pos] = temp; } } } int main( void ) { printf( "Inserisci la dimensione:\t" ); int dim; scanf( "%d", &dim ); if ( dim <= 0 || dim > 32 ) { puts( "ERRORE: dimensione non corretta" ); return EXIT_FAILURE; } int mat[MAXDIM] = {0}; for ( int i = 0; i != dim; ++i ) { for ( int j = 0; j != dim; ++j ) { printf( "Inserisci il valore a[%d][%d]:\t", i, j ); scanf( "%d", &mat[i * dim + j] ); } } ordinaDiagonale( mat, dim ); for ( int i = 0; i != dim; ++i ) { for ( int j = 0; j != dim; ++j ) { printf( "%d\t", mat[i * dim + j] ); } puts( "" ); } puts("\nE funziona anche con array multidimensionali statici"); int a[3][3] = { {0, 1, 3}, { 3, -2, 4 }, { 1, 1, 1 } }; for ( int i = 0; i != 3; ++i ) { for ( int j = 0; j != 3; ++j ) { printf( "%d\t", a[i][j] ); } puts( "" ); } puts("Diventa:"); ordinaDiagonale( &a[0][0], 3 ); for ( int i = 0; i != 3; ++i ) { for ( int j = 0; j != 3; ++j ) { printf( "%d\t", a[i][j] ); } puts( "" ); } }La stessa funzione ordinaDiagonale può essere usata anche per array statici di dimensione conosciuta a tempo di compilazione e per array di dimensione fissa. Ovviamente una funzione che accettasse sia il numero di righe che di colonne sarebbe più generica.[/*:m:2v72ul1w]
[*:2v72ul1w] Il C non ha mai richiesto che le variabili fossero definite ad inizio funzione, quello che richiedeva nello standard del 1989 era che venissero definite ad inizio del blocco in cui "vivevano". Questa richiesta non è più necessaria dallo standard del 1999 in poi. Per esempio, questo codice, equivalente al tuo, viene tranquillamente compilato da gcc con l'opzione [inline]-ansi[/inline]
#define MAXNUM 15 /* funzione che ordina la diagonale principale */ void ordinaDiagonale( int mat[][MAXNUM], int dim ) { if ( dim >= 0 ) { int i; for ( i = 0; i < dim; i++ ) { int pos = i; { /* ricerca elemento */ int min = mat[i][i]; int j; for ( j = i + 1; j < dim; j++ ) { if ( mat[j][j] < min ) { min = mat[j][j]; pos = j; } } } { /* SWAP( mat[i][i], mat[pos][pos]) */ int temp = mat[i][i]; mat[i][i] = mat[pos][pos]; mat[pos][pos] = temp; } } } }Ovviamente ho voluto esagerare nell'inserimento dei blocchi, la soluzione migliore è una via di mezzo (sia per leggibilità che come aiuto al compilatore).[/*:m:2v72ul1w][/list:o:2v72ul1w]
"insideworld":
di solito se un programmatore scrive un codice che compila al primo tentativo allora inizia a preoccuparsi seriamente XD
