Ordinamento elementi della diagonale, ordine crescente Help

bad.alex
ho una matrice quadrata di ordine N. devo stampare i valori degli elementi dela prima diagonale, dopo averli ordinati in modo crescente.
Come si svolge la consegna? grazie-

Risposte
david_e1
Credo che la cosa più semplice (e veloce) sia copiare la diagonale in un vettore e riordinarlo, quindi stampare il vettore riordinato. Una cosa del genere:

for(int i=0;i<N;++i) {
    vec[i]=matrix[i][i];
}
sort(vec);  // qui ovviamente il sort è da implementare!


sort sarà una funzione del tipo (supponendo di avere una matrice di double):

void sort(double * &);


puoi pensare di farla tu o di usare una delle funzioni di sort fornite dalle librerie standard del C (o del linguaggio che stai usando).

bad.alex
"david_e":
Credo che la cosa più semplice (e veloce) sia copiare la diagonale in un vettore e riordinarlo, quindi stampare il vettore riordinato. Una cosa del genere:

for(int i=0;i<N;++i) {
    vec[i]=matrix[i][i];
}
sort(vec);  // qui ovviamente il sort è da implementare!


sort sarà una funzione del tipo (supponendo di avere una matrice di double):

void sort(double * &);


puoi pensare di farla tu o di usare una delle funzioni di sort fornite dalle librerie standard del C (o del linguaggio che stai usando).


ti ringrazio david_e soltanto che ancora non ho studiato il sort quindi non i è possibile applicarla. come procedo senza usare questa funzione?
il linguaggio è il C++-

david_e1
La funzione "sort" così come l'ho usata io non esiste (esiste un sort in , ma funziona in maniera un po' diversa), era semplicemente per mostrare a livello di pseudo-codice come avrai fatto io.

Puoi o usare delle funzioni intrinseche di sorting (ad esempio il sort per i vector), oppure puoi pensare di implementare tu una funzione di sorting: ne esistono di vari tipi...

Io ad esempio farei in questo modo, usando le liste:
#include<iostream>
#include<list>

#define N 5

int main() {
    double matrix[N][N];
    std::list<double> l;
    std::list<double>::const_iterator it;

    for(int i=0;i<N;++i) {
        for(int j=0;j<N;++j) {
            matrix[i][j]=(double)(i+j);
        }
    }
    for(int i=0;i<N;++i) {
        l.push_back(matrix[i][i]);
    }
    l.sort();

    for(it=l.begin();it!=l.end();++it) {
        std::cout << *it << std::endl;
    }
}

Chiaramente la parte di input/output è un po' carente così, ma l'idea è questa...

bad.alex
"david_e":
La funzione "sort" così come l'ho usata io non esiste (esiste un sort in , ma funziona in maniera un po' diversa), era semplicemente per mostrare a livello di pseudo-codice come avrai fatto io.

Puoi o usare delle funzioni intrinseche di sorting (ad esempio il sort per i vector), oppure puoi pensare di implementare tu una funzione di sorting: ne esistono di vari tipi...

Io ad esempio farei in questo modo, usando le liste:
#include<iostream>
#include<list>

#define N 5

int main() {
    double matrix[N][N];
    std::list<double> l;
    std::list<double>::const_iterator it;

    for(int i=0;i<N;++i) {
        for(int j=0;j<N;++j) {
            matrix[i][j]=(double)(i+j);
        }
    }
    for(int i=0;i<N;++i) {
        l.push_back(matrix[i][i]);
    }
    l.sort();

    for(it=l.begin();it!=l.end();++it) {
        std::cout << *it << std::endl;
    }
}

Chiaramente la parte di input/output è un po' carente così, ma l'idea è questa...


in teoria, e anche in pratica, potrei dichiarare il vet come matrix ovvero il vettore come vettore formato dagli elementi dela prima diagonale. Ma per poter far sì che ciascuno degli elementi passi in rassegna, per l'ordinamento,
avevo svolto in questo modo:
vet= matrix

ma in generale per ordinare si scrive

variabile= vet
vet=vet[j]
vet[j]=variabile.....
soltanto che mentre vettore i dovrebbe contenere gli elementi della prima diagonale, il confronto dovrebbe avvenire tra il primo elemento della prima diagonale con i restanti 4, il secondo con i restanti 3....
con un ciclo for.....
ma non riesco:(

bad.alex
"bad.alex":
ho una matrice quadrata di ordine N. devo stampare i valori degli elementi dela prima diagonale, dopo averli ordinati in modo crescente.
Come si svolge la consegna? grazie-


non riesco a completare la parte relativa all'ordinamento.

david_e1
Usando un classico Bubblesort:

#include<iostream>

#define N 5

void print(double const * v,int size);
void sort(double * v);

int main() {
    double matrix[N][N];
    double vec[N];

    for(int i=0;i<N;++i) {
        for(int j=0;j<N;++j) {
            matrix[i][j]=(double)(N*N-i-j);
        }
    }

    for(int i=0;i<N;++i) {
        vec[i]=matrix[i][i];
    }

    print(vec,N);
    sort(vec);
    std::cout << std::endl;
    print(vec,N);
}

void print(double const * v,int n) {
    for(int i=0;i<n;++i) {
        std::cout << v[i] << std::endl;
    }
}

void sort(double * v) {
    int changes=0;
    double tmp;
    do {
        changes=0;
        for(int i=1;i<N;++i) {
            if(v[i-1]>v[i]) {
                ++changes;
                tmp=v[i];
                v[i]=v[i-1];
                v[i-1]=tmp;
            }
        }
    } while(changes);
}

bad.alex
dove è il mio errore? purtroppo ancora non siamo arrivati a studiare granchè e le mie conoscenze sono ridotte a quanto segue:


vet=mat;
for( i=0; i<=N-1; i++) {
if (vet[i-1]>vet) {
}
}

david_e1
Non basta una sola passata di scambi per ordinare il vettore, ma devi ripetere quel passo più volte. Pensa ad esempio al caso:

(10, 1, 12, 3, 4)

con una sola passata del tuo ciclo arrivi a:

(1, 10, 3, 4, 12)

infatti fai:

(1, 10, 12, 3, 4)
(1, 10, 3, 12, 4)
(1, 10, 3, 4, 12)

devi ripetere più volte fino a che non ci sono più scambi, quindi devi "inscatolare" il for dentro un while, come ho fatto io...

*** edit ***
Ovviamente era "non basta..."

bad.alex
ma sempre lavorando sulle nostre basi, considerando che gli unici costrutti che noi conosciamo sono for if e do while, come verrebbe?
(changes....?)

david_e1
Ma anche io l'ho fatto solo con for e while: :-D
int changes=0;
double tmp;
do {
    changes=0;
    for(int i=1;i<N;++i) {
        if(v[i-1]>v[i]) {
            ++changes;
            tmp=v[i];
            v[i]=v[i-1];
            v[i-1]=tmp;
        }
    }
} while(changes);

changes è solo un int... ricordo che in C++ un intero diverso da zero è sempre true.

bad.alex
"david_e":
No basta una sola passata di scambi per ordinare il vettore, ma devi ripetere quel passo più volte. Pensa ad esempio al caso:

(10, 1, 12, 3, 4)

con una sola passata del tuo ciclo arrivi a:

(1, 10, 3, 4, 12)

infatti fai:

(1, 10, 12, 3, 4)
(1, 10, 3, 12, 4)
(1, 10, 3, 4, 12)

come faccio a trasformare gli elementi successivi al primo, nella prima diagonale, in vettori?

se noi fissiamo vet = mat,
quale altro vettore indicherà gli elementi successivi al vet[0] corrispondente a mat[0][0]?

impossibile sostituire ad i , i+1.....mi dè errore

devi ripetere più volte fino a che non ci sono più scambi, quindi devi "inscatolare" il for dentro un while, come ho fatto io...

bad.alex
"david_e":
Ma anche io l'ho fatto solo con for e while: :-D
int changes=0;
double tmp;
do {
    changes=0;
    for(int i=1;i<N;++i) {
        if(v[i-1]>v[i]) {
            ++changes;
            tmp=v[i];
            v[i]=v[i-1];
            v[i-1]=tmp;
        }
    }
} while(changes);

changes è solo un int... ricordo che in C++ un intero diverso da zero è sempre true.

in questo modo ancora non mi risulta.... :cry:

david_e1
Eccolo qui, ho esplicitato la condizione nel while:
int changes=0;
double tmp;
do {
    changes=0;
    for(int i=1;i<N;++i) {
        if(v[i-1]>v[i]) {
            ++changes;
            tmp=v[i];
            v[i]=v[i-1];
            v[i-1]=tmp;
        }
    }
} while(changes==0);

sono solo for, if e un do-while. changes è un intero (potevo chiamarlo pippo...).

david_e1
Ecco poi occhio che non basta fare:
vec[i]=mat[i][i];

altrimenti lui assegna soltanto vec con "i" fissato (probabilmente fisso al valore terminale del ciclo prima), bisogna fare:
for(int i=0;i<N;++i) {
    vec[i]=mat[i][i];
}

bad.alex
"david_e":
Eccolo qui, ho esplicitato la condizione nel while:
int changes=0;
double tmp;
do {
    changes=0;
    for(int i=1;i<N;++i) {
        if(v[i-1]>v[i]) {
            ++changes;
            tmp=v[i];
            v[i]=v[i-1];
            v[i-1]=tmp;
        }
    }
} while(changes==0);

sono solo for, if e un do-while. changes è un intero (potevo chiamarlo pippo...).


ancora niente....deve esserci qualche errore...

david_e1
"bad.alex":
ancora niente....deve esserci qualche errore...

Hai corretto quella cosa del vec che ho aggiunto dopo? Se non va ancora prova a postare per intero il tuo codice così com'è...

bad.alex
"david_e":
[quote="bad.alex"]ancora niente....deve esserci qualche errore...

Hai corretto quella cosa del vec che ho aggiunto dopo? Se non va ancora prova a postare per intero il tuo codice così com'è...[/quote]


Niente.

non saprei cosa scrivere....

david_e1
Ci sono un po' di errori:

1. vec lo devi inizializzare in un ciclo a parte, prima di ordinarlo. In un ciclo for (con i=0,1,2,...N-1), prima del do-while. Non puoi contemporaneamente definirlo e ordinarlo.
2. Gli estremi del ciclo sono sbagliati: devi partire da 1 e arrivare a N-1 dato che accedi a vec[i-1] e vec.

Il printf non è il modo migliore per stampare a monitor in C++: molto meglio la cout. Tra l'altro dato che non uso printf e soci da una vita non ti so trovare errori li perché non mi ricordo assolutamente come si usano. E anche le librerie: al massimo bisognerebbe fare un #include (non stdio.h) in modo da non importare tutti i comandi nel namespace principale.

bad.alex
"david_e":
Ci sono un po' di errori:

1. vec lo devi inizializzare in un ciclo a parte, prima di ordinarlo. In un ciclo for (con i=0,1,2,...N-1), prima del do-while. Non puoi contemporaneamente definirlo e ordinarlo.
2. Gli estremi del ciclo sono sbagliati: devi partire da 1 e arrivare a N-1 dato che accedi a vec[i-1] e vec.

Il printf non è il modo migliore per stampare a monitor in C++: molto meglio la cout. Tra l'altro dato che non uso printf e soci da una vita non ti so trovare errori li perché non mi ricordo assolutamente come si usano. E anche le librerie: al massimo bisognerebbe fare un #include (non stdio.h) in modo da non importare tutti i comandi nel namespace principale.


ancora non riesco.....devo riuscire ad inizializzare il vet con gli elementi della prima diagonale =(

david_e1
"bad.alex":
[quote="david_e"]Ci sono un po' di errori:

1. vec lo devi inizializzare in un ciclo a parte, prima di ordinarlo. In un ciclo for (con i=0,1,2,...N-1), prima del do-while. Non puoi contemporaneamente definirlo e ordinarlo.
2. Gli estremi del ciclo sono sbagliati: devi partire da 1 e arrivare a N-1 dato che accedi a vec[i-1] e vec.

Il printf non è il modo migliore per stampare a monitor in C++: molto meglio la cout. Tra l'altro dato che non uso printf e soci da una vita non ti so trovare errori li perché non mi ricordo assolutamente come si usano. E anche le librerie: al massimo bisognerebbe fare un #include (non stdio.h) in modo da non importare tutti i comandi nel namespace principale.


ancora non riesco.....devo riuscire ad inizializzare il vet con gli elementi della prima diagonale =([/quote]
Per inizializzare vec devi fare:
for(int i=0;i<N;++i) {
     vec[i]=mat[i][i];
}

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.