[C] Ordinare righe di una matrice
Ciao a tutti e buona Pasquetta 
Ho un problema con questo esercizio che non riesco a risolvere.
Ho inizializzato una matrice avente su ogni riga una sequenza di numeri binari, ad esempio:
Mi viene chiesto di calcolare per ogni singola riga la conversione in decimale, quindi con questa funzione:
Mi calcolo il numero decimale di ogni singola riga, e quindi avrò come uscita:
Adesso mi viene chiesto di ordinare la matrice in modo crescente, quindi spostare le varie righe in modo da avere all'inizio i numeri decimali più piccoli ed alla fine i numeri decimali più grandi.
Ho scritto quindi queste due funzioni basate sulla bubble sort in modo da scambiare l'ordine delle varie righe:
Quello che non riesco a capire è come mai la funzione mi dia in uscita un ordine sbagliato, in quanto mi inverte solamente le prime due righe e non tutte le altre!!
Sapreste dirmi dove sbaglio? E' tutto pomeriggio che ci provo ma non riesco proprio a venirne a capo. Questo è il codice completo dell'esercizio:
Grazie mille
Ciaoo

Ho un problema con questo esercizio che non riesco a risolvere.
Ho inizializzato una matrice avente su ogni riga una sequenza di numeri binari, ad esempio:
1 1 1 0 0 0 0 0 1 1 0 1
Mi viene chiesto di calcolare per ogni singola riga la conversione in decimale, quindi con questa funzione:
int conversione (int v[], int n) { int i,tot=0; for (i=0;i<n;i++) { if (v[i]==1) tot=tot+pow(2,i); } return tot; }
Mi calcolo il numero decimale di ogni singola riga, e quindi avrò come uscita:
Conversione in decimale di ogni singola riga: Riga: 0 - Valore: 7 Riga: 1 - Valore: 0 Riga: 2 - Valore: 4 Riga: 3 - Valore: 5
Adesso mi viene chiesto di ordinare la matrice in modo crescente, quindi spostare le varie righe in modo da avere all'inizio i numeri decimali più piccoli ed alla fine i numeri decimali più grandi.
Ho scritto quindi queste due funzioni basate sulla bubble sort in modo da scambiare l'ordine delle varie righe:
void scambia (int v1[], int v2[], int n) { int i,x; for (i=0;i<n;i++) { x=v1[i]; v1[i]=v2[i]; v2[i]=x; } } void ordina (int mat[DIM1][DIM2], int v[]) { int i,j; for (i=0;i<DIM1-1;i++) { for (j=DIM1-1;j>i;j--) { if (v[j-1]>v[j]) { scambia (mat[j-1], mat[j],DIM2); } } } }
Quello che non riesco a capire è come mai la funzione mi dia in uscita un ordine sbagliato, in quanto mi inverte solamente le prime due righe e non tutte le altre!!
Conversione in decimale di ogni singola riga: Riga: 0 - Valore: 0 Riga: 1 - Valore: 7 Riga: 2 - Valore: 4 Riga: 3 - Valore: 5
Sapreste dirmi dove sbaglio? E' tutto pomeriggio che ci provo ma non riesco proprio a venirne a capo. Questo è il codice completo dell'esercizio:
#include <stdio.h> #include <math.h> #define DIM1 4 #define DIM2 3 /* Inizializzo la matrice da un file dat */ int inizializza (int mat[DIM1][DIM2], int n, FILE *fp) { int i=0, j, s=0, m=0, v1[100], v2[100]; while (feof(fp)==0) { if(fread(&v1[i],sizeof(v1),1,fp)>0) { v2[s]=v1[i]; s++; } } for (i=0;i<n;i++) { for (j=0;j<DIM2;j++) { mat[i][j]=v2[m]; m++; } } return i; } /* Produrre la conversione in base 10 di un numero binario le cui cifre sono contenute in un dato vettore di n variabili intere. */ int conversione (int v[], int n) { int i,tot=0; for (i=0;i<n;i++) { if (v[i]==1) tot=tot+pow(2,i); } return tot; } /* Scambiare gli interi presenti in due dati vettori di n variabili intere. */ void scambia (int v1[], int v2[], int n) { int i,x; for (i=0;i<n;i++) { x=v1[i]; v1[i]=v2[i]; v2[i]=x; } } /* Ordinare le n righe di una data matrice di 10 colonne di variabili intere in base al valore (dal più piccolo al più grande) dei numeri decimali ottenuti convertendo i numeri binari presenti sulle righe della matrice. */ void ordina (int mat[DIM1][DIM2], int v[]) { int i,j; for (i=0;i<DIM1-1;i++) { for (j=DIM1-1;j>i;j--) { if (v[j-1]>v[j]) { scambia (mat[j-1], mat[j],DIM2); } } } } /* Stampare a video un vettore di n variabili intere. */ void stampa (int v[], int n) { int i; for (i=0;i<n;i++) printf("%d\t", v[i]); } /* Programma principale */ int main () { int mat[DIM1][DIM2],i,temp[DIM1]; FILE *fp=fopen("numeri.dat","rb"); if (fp==NULL) { printf("Errore apertura file\n"); return -1; } inizializza (mat,DIM1,fp); printf("Stampo la matrice inizializzata:\n"); for (i=0;i<DIM1;i++) { stampa(mat[i],DIM2); printf("\n"); } printf("\nConversione in decimale di ogni singola riga:\n"); for (i=0;i<DIM1;i++) { temp[i]=conversione(mat[i],DIM2); printf("Riga: %d - Valore: %d\n", i, temp[i]); } ordina (mat, temp); printf("\nConversione in decimale di ogni singola riga:\n"); for (i=0;i<DIM1;i++) { temp[i]=conversione(mat[i],DIM2); printf("Riga: %d - Valore: %d\n", i, temp[i]); } fclose (fp); return 0; }
Grazie mille
Ciaoo

Risposte
/*
Ordinare le n righe di una data matrice di 10 colonne di variabili intere in base al valore (dal più piccolo al più grande) dei numeri decimali ottenuti convertendo i numeri binari presenti sulle righe della matrice.
*/
void ordina (int mat[DIM1][DIM2], int v[])
{
int i,j;
int vv;
for (i=0;i
{
for (j=DIM1-1;j>i;j--)
{
if (v[j-1]>v[j])
{
scambia (mat[j-1], mat[j],DIM2);
vv = v[j-1];
v[j-1] = v[j];
v[j] = vv;
}
}
}
}
Ordinare le n righe di una data matrice di 10 colonne di variabili intere in base al valore (dal più piccolo al più grande) dei numeri decimali ottenuti convertendo i numeri binari presenti sulle righe della matrice.
*/
void ordina (int mat[DIM1][DIM2], int v[])
{
int i,j;
int vv;
for (i=0;i
for (j=DIM1-1;j>i;j--)
{
if (v[j-1]>v[j])
{
scambia (mat[j-1], mat[j],DIM2);
vv = v[j-1];
v[j-1] = v[j];
v[j] = vv;
}
}
}
}
Mi sono imbranato con l'editor.
Vediamo se mi riesce meglio adesso...
Comunque dovevi scambiare anche il vettore dei numeri convertiti.
Ciao
Stefano.
/*
Ordinare le n righe di una data matrice di 10 colonne di variabili intere in base al valore (dal più piccolo al più grande) dei numeri decimali ottenuti convertendo i numeri binari presenti sulle righe della matrice.
*/
void ordina (int mat[DIM1][DIM2], int v[])
{
int i,j;
int vv;
for (i=0;i
{
for (j=DIM1-1;j>i;j--)
{
if (v[j-1]>v[j])
{
scambia (mat[j-1], mat[j],DIM2);
vv = v[j-1];
v[j-1] = v[j];
v[j] = vv;
}
}
}
}
Vediamo se mi riesce meglio adesso...
Comunque dovevi scambiare anche il vettore dei numeri convertiti.
Ciao
Stefano.
/*
Ordinare le n righe di una data matrice di 10 colonne di variabili intere in base al valore (dal più piccolo al più grande) dei numeri decimali ottenuti convertendo i numeri binari presenti sulle righe della matrice.
*/
void ordina (int mat[DIM1][DIM2], int v[])
{
int i,j;
int vv;
for (i=0;i
for (j=DIM1-1;j>i;j--)
{
if (v[j-1]>v[j])
{
scambia (mat[j-1], mat[j],DIM2);
vv = v[j-1];
v[j-1] = v[j];
v[j] = vv;
}
}
}
}
niente da fare. non riesco a indentare il codice.
comunque ho messo in grassetto le mie aggiunte
comunque ho messo in grassetto le mie aggiunte
@sp640919: esiste un tag code
Il forum non è una chat quindi non aggiungere nuove risposte per cercare di correggerli: puoi modificare i messaggi.
@floppyes: Ordinare numeri scritti in un formato posizionale non richiede di capire il numero. Si tratta di usare l'ordine lessicografico. Inoltre per convertire non ti serve usare pow.
Prendi \(\displaystyle 10011101 \). Parti da \(\displaystyle 1 \) e hai come risultato parziale \(\displaystyle 1 \). Lo moltiplichi per 2 e ci aggiungi 0 ricavando 2. Quindi fai lo stesso ricavando 4. Ora hai un 1, quindi moltiplichi per 2 e sommi 1 ricavando 9. A questo punto moltiplichi per due e aggiungi 1 ricavando 19. Lo fai nuovamente ricavando 39. In definitiva lo moltiplicherai per 4 e ci aggiungerai ancora 1 ricavando 157.
[code]scrivi il codice qui.... Anche formattato[/code]
Il forum non è una chat quindi non aggiungere nuove risposte per cercare di correggerli: puoi modificare i messaggi.
@floppyes: Ordinare numeri scritti in un formato posizionale non richiede di capire il numero. Si tratta di usare l'ordine lessicografico. Inoltre per convertire non ti serve usare pow.
Prendi \(\displaystyle 10011101 \). Parti da \(\displaystyle 1 \) e hai come risultato parziale \(\displaystyle 1 \). Lo moltiplichi per 2 e ci aggiungi 0 ricavando 2. Quindi fai lo stesso ricavando 4. Ora hai un 1, quindi moltiplichi per 2 e sommi 1 ricavando 9. A questo punto moltiplichi per due e aggiungi 1 ricavando 19. Lo fai nuovamente ricavando 39. In definitiva lo moltiplicherai per 4 e ci aggiungerai ancora 1 ricavando 157.
Ciao!
Grazie per le risposte e scusate il ritardo!
Si alla fine mi sono dimenticato di scambiare l'ordine anche del vettore, infatti ora funziona tutto quanto. In effetti potevo utilizzare il tuo metodo e non quello della potenza, però mi sembrava più veloce usare il secondo metodo
Grazie mille ancora
Ciaoo!
Grazie per le risposte e scusate il ritardo!
Si alla fine mi sono dimenticato di scambiare l'ordine anche del vettore, infatti ora funziona tutto quanto. In effetti potevo utilizzare il tuo metodo e non quello della potenza, però mi sembrava più veloce usare il secondo metodo

Grazie mille ancora
Ciaoo!
A dire il vero non è né più veloce da scrivere né in termini di velocità di esecuzione. La moltiplicazione per due è poi spesso ottimizzata dal compilatore. Riguardo alla tua devi tenere conto che fai 1-2 conversioni da int a double e una da double a int oltre al calcolo di una potenza di un double. Inoltre fai un if in più. Probabilmente persino calcolare la potenza n-esima con pow e poi dividere per due tale valore è più rapido di chiamare pow per ogni valore.
Il codice in fine dei conti sarebbe:
Il codice in fine dei conti sarebbe:
int conversione (int v[], int n) { int tot=v[0]; for (int i=1;i<n;i++) { tot = tot*2 + v[i]; } return tot; }