PDA

View Full Version : problema di ordinamento di un vettore c


papas_b
20-03-2007, 22:58
salve ragazzi, ho dei problemi con questo esercizio, in pratica la funzione riceve in ingresso un array V di interi e deve creare un array W ordinato con all interno gli elementi di V. ho creato questo sorgente ma non funziona...cosa mi consigliate?


#include <iostream.h>
#include <stdlib.h>
#define N 5

int vect[N];

void ordina(int vettore[N]){
int a,k,i;
int flag[N];
int w[N];
for(int g=0;g<N;g++){
flag[g]=0;
w[g]=0;
}

for(i=0;i<N;i++){
w[i]=vettore[i];
for(k=0;k<N;k++){
if((w[i]>=vettore[k])&&(flag[k]!=1))//trova il minimo e i flag

w[i]=vettore[k];

//w[i]=a;
flag[k]=1;
}
for(int f=0;f<N;f++){
cout<<"flag --> " <<flag[k]<<endl;
cout<<endl;
cout<<"w --> " <<w[f]<<endl;
}
}



main(){
for(int i=0;i<N;i++){
cout<<"digita numero"<<endl;
cin>>vect[i];
}
ordina(vect);
system("PAUSE");
}

cionci
21-03-2007, 07:44
Esistono dei ben precisi algoritmi per effettuare l'ordinamento dei vettori, il più semplice: http://it.wikipedia.org/wiki/Bubble_sort

papas_b
21-03-2007, 08:38
li conosco alcuni, e solo ke vorrei riuscire a creare questa funzione.. se potete aiutarmi a capire, ve ne sarei grato :)

cionci
21-03-2007, 08:40
Ma allora perché non applichi un algoritmo di ordinamento noto ?

papas_b
21-03-2007, 08:59
perke il problema assegnatomi, non lo rikiede.. in pratica si tratta di un esercizio e lo devo svolgere cosi..

cionci
21-03-2007, 09:19
E qual'è il testo del problema ?
Se il testo è quello scritto sopra puoi applicare banalmente un algoritmo di ordinamento copiando prima gli elementi di vettore in w e poi applicando l'algoritmo di ordinamento su w.
Ad occhio quello che stai tentando di fare è trovare il minimo fra gli elementi del vettore non flaggati, per carità dovrebbe funzionare anche così, ma mi sembra ben più complesso.

Comunque l'errore mi sembra qui:

for(i=0;i<N;i++){
w[i]=vettore[i];
for(k=0;k<N;k++){
if((w[i]>=vettore[k])&&(flag[k]!=1))//trova il minimo e i flag

w[i]=vettore[k];

flag[k]=1;
}

k è sempre uguale a N dopo il for.
Devi crearti una variabili minIndex:

if((w[i]>=vettore[k])&&(flag[k]!=1))//trova il minimo e i flag
{
w[i]=vettore[k];
minIndex = k;
}
flag[minIndex] = 1;

cionci
21-03-2007, 09:31
Inoltre vedo una certa confusione...stavi parlando di C e usi iostream del C++ e non solo: iostream.h e stdlib.h sono deprecate. Ora devi includere iostream e cstdlib.

#include <iostream>
#include <cstdlib>

using namespace std; //per includere tutto il namespace std

papas_b
21-03-2007, 09:39
grazie!!! qualcosa sta migliorando solo ke ci sono ancora dei problemi...

cionci
21-03-2007, 09:44
Questa parentesi non ci vuole:

for(k=0;k<N;k++){

o se ce la metti ne metti anche una chiusa dopo l'if...

cionci
21-03-2007, 09:47
cout<<"flag --> " <<flag[k]<<endl;
Ci devi mettere f al posto di k...

papas_b
21-03-2007, 09:53
allora.. alcune cose le avevo corrette cmq grazie :) per il resto, ho detto c e non c++ per evitare di spiegare ke non posso usare le classi, i puntatori e altre cose..cmq.. non riesco a capire perke la funzione funziona solo in parte, cioe ordina solo alcuni numeri...

cionci
21-03-2007, 10:10
Il problema ce l'hai perchè inizializzi w[i] con w[i]=vettore[i];
vettore[i] può essere già flaggato oppure anche l'elemento minimo fra quelli non flaggati, in questo caso lasci un elemento minimo non flaggato che verrà assegnato a tutti i passi successivi come elemento minimo.

papas_b
21-03-2007, 10:25
questo e il codice modificato, ho aggiunto "temp" per ovviare al problema ma lo stesso ho problemi..


void ordina(int vettore[N]){
int minIndex,temp=0;
int a,k,i;
int flag[N];
int w[N];
for(int g=0;g<N;g++){
flag[g]=0;
w[g]=0;
}

for(i=0;i<N;i++){
//w[i]=vettore[i];
temp=vettore[i];
for(k=0;k<N;k++)
if((temp>=vettore[k])&&(flag[k]!=1)){ //trova il minimo e i flag

w[i]=vettore[k];
minIndex = k;

}
flag[minIndex]=1;
}


for(int f=0;f<N;f++){
cout<<" flag --> " <<flag[f]<<endl;
cout<<endl;
cout<<"w --> " <<w[f]<<endl;
}
}


main(){
for(int i=0;i<N;i++){
cout<<"digita numero"<<endl;
cin>>vect[i];
}
ordina(vect);
//cout<<trov_min(vect);
system("PAUSE");
}

cionci
21-03-2007, 10:36
Certo perchè temp potrebbe essere già flaggata e quindi sarebbe minore di tutti gli elementi rimasti... Inizializza temp a INT_MAX.

papas_b
21-03-2007, 10:51
non ci sto capendo niente!!! ..aiutatemi...

okay
21-03-2007, 11:53
non ci sto capendo niente!!! ..aiutatemi...


togli l'ordinamento per il flag e fai un normale ordinamento al minimo...
se tutto ok allora usa il flag...

papas_b
21-03-2007, 12:11
togli l'ordinamento per il flag e fai un normale ordinamento al minimo...
se tutto ok allora usa il flag...

in pratica mi stai dicendo di rifare tutto?

non ci sto.. lo devo risolvere!!! :)

cionci
21-03-2007, 12:13
Hai provato ad inizializzare temp a INT_MAX ?

alberto.frz
21-03-2007, 12:23
...prova a guardare il bubble sort e traine spunto...cosi vedi come procedere...

papas_b
21-03-2007, 12:55
gazie.. ma devo sistemare questo codice.. si tratta di qualke disattenzione (spero!!)

alberto.frz
21-03-2007, 13:43
...non sono espertissimo di c...però se mi mandi il sorgente provo a smanettarci un po'...lo faccio volentieri:D

papas_b
21-03-2007, 13:47
...non sono espertissimo di c...però se mi mandi il sorgente provo a smanettarci un po'...lo faccio volentieri:D
ecco.. questo e quello a cui ci sto lavorando...
ho inserito delle stampe sul video per regolarmi sui procedimenti..

#include <iostream.h>
#include <stdlib.h>
#define N 5

int vect[N];

void stampa(int vett[N],int vett1[N]){
for(int f=0;f<N;f++){
cout<<" flag --> " <<vett1[f]<<endl;
cout<<endl;
cout<<"w --> " <<vett[f]<<endl;
}
}
//--------------------------------------------------------

void ordina(int vettore[N]){
int minIndex,temp;
int i,k;
int flag[N];
int w[N];
for(int g=0;g<N;g++){
flag[g]=0;
w[g]=0;
}

for(i=0;i<N;i++){
//w[i]=vettore[i];
temp=vettore[i];
cout<<"assegno a temp "<< vettore[i]<<endl;
for(k=0;k<N;k++){
cout<<"for interno "<<k<<endl;
if((temp>=vettore[k])&&(flag[k]!=1)){ //trova il minimo e i flag
cout<<endl<<temp<<" > " <<vettore[k]<<" NOflag "<<endl;
w[i]=vettore[k];
cout<<"assegno a w"<<i<<"-->"<< vettore[k]<<endl;
minIndex = k;
temp=vettore[k];

}
}
flag[minIndex]=1;
cout<<"flaggo"<<minIndex<<endl;
}
stampa(w,flag);
}





main(){
for(int i=0;i<N;i++){
cout<<"digita numero"<<endl;
cin>>vect[i];
}
ordina(vect);
//cout<<trov_min(vect);
system("PAUSE");
}

cionci
21-03-2007, 13:48
Vedo che non hai provato ad inizializzare temp a INT_MAX ;)

papas_b
21-03-2007, 14:01
Vedo che non hai provato ad inizializzare temp a INT_MAX ;)

si.. ma int_max ke e??

alberto.frz
21-03-2007, 14:08
mi sa che stai programmando in windows giusto?
cmq a te interessa che una funzione con vettore di interi non ordinati restituisca un altro vettore con gli stessi elementi ordinati!?giusto? o ho capito male?

cionci
21-03-2007, 14:15
si.. ma int_max ke e??
INT_MAX è una costante ed è pari all'intero positivo massimo che può stare all'interno di un int...

papas_b
21-03-2007, 14:16
mi sa che stai programmando in windows giusto?
cmq a te interessa che una funzione con vettore di interi non ordinati restituisca un altro vettore con gli stessi elementi ordinati!?giusto? o ho capito male?

esatto!

papas_b
21-03-2007, 14:21
INT_MAX è una costante ed è pari all'intero positivo massimo che può stare all'interno di un int...

questo l ho provato.. e nn va..
prova.. se nn e troppo disturbo, ad eseguire il codice postato sopra.. e ti farai un idea del problema :)

papas_b
21-03-2007, 14:50
ti conviene a indentarlo perchè se no nn si capisce nulla...

indentarlo... ke vuol dire?

papas_b
21-03-2007, 15:11
ehm... evidenzi la struttura del codice... ad es così (codice qualsiasi):

#include <stdio.h>

int main (void)
{
printf ("Hello, World!");
return 0;
}


così lo rendi più leggibile a tutti quanti...

ma non so come si fa... me lo spighi per favore..

alberto.frz
21-03-2007, 15:24
ma non so come si fa... me lo spighi per favore..

con TAB.


questa funzione ordina il vettore in modo crescente


void ordina (int a[], int dim) {

int i,j,temp;

for (i=0; i<dim-1; i++) {
for (j=0; j<dim-1; j++) {
if (a[j] > a[j+1]) {
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
return;
}

papas_b
21-03-2007, 15:31
con TAB.


questa funzione ordina il vettore in modo crescente


void ordina (int a[], int dim) {

int i,j,temp;

for (i=0; i<dim-1; i++) {
for (j=0; j<dim-1; j++) {
if (a[j] > a[j+1]) {
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
return;
}


si..e l algoritmo bublesort...

cionci
21-03-2007, 15:32
Ma lui vuole usare il metodo che ha partorito (anche giustamente da un certo punto di vista) ;)

cionci
21-03-2007, 15:50
Guarda ho solo indentato e messo INT_MAX e ha funzionato subito:

#include <iostream>
#include <cstdlib>
#define N 5

using namespace std;

int vect[N];

void stampa(int vett[N], int vett1[N])
{
for(int f = 0; f < N; f++) {
cout << " flag --> " << vett1[f] << endl;
cout << endl;
cout << "w --> " << vett[f] << endl;
}
}

void ordina(int vettore[N])
{
int minIndex;
int i, k;
int flag[N];
int w[N];
for(int g = 0; g < N; g++) {
flag[g] = 0;
w[g] = 0;
}

for(i = 0; i < N; i++) {
w[i] = INT_MAX;
for(k = 0; k < N; k++) {
if(w[i] >= vettore[k] && flag[k]!=1) {
w[i] = vettore[k];
minIndex = k;
}
}
flag[minIndex]=1;
}

stampa(w, flag);
}

int main(){
for(int i = 0; i < N; i++) {
cout << "digita numero" << endl;
cin >> vect[i];
}
ordina(vect);
system("PAUSE");
return 0;
}

alberto.frz
21-03-2007, 16:32
si..e l algoritmo bublesort...

...ecco perche funziona cosi bene:Prrr:

papas_b
21-03-2007, 16:32
cionci sei un grande!!!
ma mi spieghi cosa hai fatto e cosa sono queste due cose, cosi potro riutilizzarle..

using namespace std;

w[i] = INT_MAX;

grazie!!!!!

cionci
21-03-2007, 18:21
Ho eliminato temp in quanto aveva la stessa funzione di w[i]...comunque funzionava tutto anche lasciando temp...
INT_MAX come ti avevo già detto sopra è il massimo intero positivo rappresentabile in un int...
Esiste anche INT_MIN che è appunto il massimo intero negativo...
Sia INT_MAX che INT_MIN sono costanti definite nella libreria standard di C e C++...

Inizializzando w[i] a INT_MAX, w[i] è >= di tutti gli interi possibili. Di conseguenza un ramo if viene sempre fatto...

Riguardo ad using è una direttiva che si trova già da molti anni nello standard C++...
Nota anche gli include nella forma diversa...gli include del C++ mantengono lo stesso nome senza il .h, gli include del C mantengono lo stesso nome senza il .h ma hanno una "c" come prefisso (cstdio, cstdlib, ctime e così via).

Gli include nella forma in cui l'avevi messa tu sono deprecati (ovvero sono aderenti ad uno standard vecchio del C++ e se ne sconsiglia l'uso). Quindi se stai studiando C++ su un libro o una guida renditi conto che la tua documentazione fa riferimento ad uno standard vecchio del C++...

Using serve ad importare dei "nomi" all'interno dello spazio di definizione corrente...

Già da diversi anni in C++ esistono appunto i cosiddetti "namespace": vedi un namespace come un insieme coerente di dichiarazioni di classi, funzioni e variabili. Vedilo come una scatola in cui sono rinchiuse le dichiarazioni.
Tutta la libreria standard C++ è definita all'interno del namespace chiamato "std".
using namespace std; serve proprio per riuscire a "vedere" direttamente tutte le classi, funzioni, variabili dichiarate all'interno del namespace std.

Ti faccio un esempio:

#include <iostream> //nota senza il .h

...
...
std::cout << std::endl;
...
...

Accedo direttamente al namespace con "std::" ed uso cout e endl.
Avrei potuto importare direttamente cout ed endl in modo da non usare "std::":

#include <iostream> //nota senza il .h

using std::cout; //importo il solo cout
using std::end; //importo il solo endl

...
...
cout << endl;
std::cin >> i;
...
...

Però come vedi cin continuerò a vederlo solo "aprendo" la scatola con "std::"
Posso importare anche tutto il namespace std:


#include <iostream> //nota senza il .h

using namespace std; //importo tutti i nomi dichiarati in std

...
...
cout << endl;
cin >> i;
...
...

Appena i tuoi progetti cresceranno tornerà comodo anche a te usare i namespace per definirvi all'interno strutture omogenee (ad esempio classi che formano un'unica entità).

namespace mio
{
int endl = 10;
};

Nota che in questo modo potrò usare mio::endl nel sorgente indipendentemente dalla definizione di std::endl, l'importante è non importare entrambi i namespace.


#include <iostream> //nota senza il .h
#include "mio.h" //qui è dichiarato il namespace mio

using namespace std; //importo tutti i nomi dichiarati in std

...
...
cout << endl << mio::endl;
...
...

Quando non esistevano i namespace questa cosa non era possibile ;)

papas_b
21-03-2007, 18:46
grazie!!! sei stato molto kiaro e gentile.. vorrei kiederti un ultima cosa, riguarda un altra funzione, penso di essere a buon punto, ma il compilator mi da degli errori..

si tratta di 2 vettori, un vettore (Seq1) viene copiato in un terzo (Seq_diff) escludendo gli elementi uguali ke si trovano nel secondo vettore (Seq2)

#include <iostream>
#include <cstdlib>
#define N 5
#define A 0

using namespace std;


int vect1[N]={1,3,7,9,10};
int vect2[N]={3,5,6,9,11};

int RicBin(int V[N],int x, int a, int z){
if(a>z)
return -1;
else{
int m=(a+z)/2;
if(V[m]==x)
return m;
if(x<V[m])
return RicBin(V,x,a,m-1);
else
return RicBin(V,x,m+1,z);
}
}


void fusione(int Seq1[],int Seq2[],int N){
int a=0;
int tmp;
int Seq_diff[N];
for(int j=0;j<N;j++){
for(int i=0;i<N;i++){
tmp=(RicBin(Seq2,Seq1[i],a,N));
if(tmp=-1)
Seq_diff[j]=Seq1[i];
}
}
}

//----------------------------------------------

int main(){
for(int i = 0; i < N; i++) {
cout << vect2[i] << endl;
}
fusione(vect2,vect1,A,N);
system("PAUSE");
return 0;
}


p.s. nn ho capito come formattare il testo...

cionci
21-03-2007, 18:48
Per fare vedere il codice formattato usa (ma con le quadre):
{code}
{/code}

cionci
21-03-2007, 18:50
Il primo errore che vedo è:

if(tmp=-1)

L'operatore = è quello di assegnazione, mentre quello di confronto è ==

Che compilatore usi ?

papas_b
21-03-2007, 19:03
gia!!!...
uso il devc++

papas_b
21-03-2007, 19:05
#include <iostream>
#include <cstdlib>
#define N 5
#define A 0

using namespace std;


int vect1[N]={1,3,7,9,10};
int vect2[N]={3,5,6,9,11};

int RicBin(int V[N],int x, int a, int z){
if(a>z)
return -1;
else{
int m=(a+z)/2;
if(V[m]==x)
return m;
if(x<V[m])
return RicBin(V,x,a,m-1);
else
return RicBin(V,x,m+1,z);
}
}


void fusione(int Seq1[],int Seq2[],int N){
int a=0;
int tmp;
int Seq_diff[N];
for(int j=0;j<N;j++){
for(int i=0;i<N;i++){
tmp=(RicBin(Seq2,Seq1[i],a,N));
if(tmp==-1)
Seq_diff[j]=Seq1[i];
}
}
}

//----------------------------------------------

int main(){
for(int i = 0; i < N; i++) {
cout << vect2[i] << endl;
}
fusione(vect2,vect1,A,N);
system("PAUSE");
return 0;
}

cionci
21-03-2007, 19:09
Questa volta l'hai indentato anche meglio, ma io almeno all'inizio mettere anche un po' di spazio fra gli operatori..

Nota che i vettori che hai immesso sono ordinati, quindi non serve alcuna ricerca...pensaci un po'...

papas_b
21-03-2007, 19:12
Questa volta l'hai indentato anche meglio, ma io almeno all'inizio mettere anche un po' di spazio fra gli operatori..

Nota che i vettori che hai immesso sono ordinati, quindi non serve alcuna ricerca...pensaci un po'...

spiegami meglio...

cionci
21-03-2007, 19:24
int vect1[N]={1,3,7,9,10};
int vect2[N]={3,5,6,9,11};

Sono vettori ordinati, giusto ?
Ti mantieni due indici sui vettori, entrambi gli indici partono da zero...
Un indice per il vettore risultato...

se(v1[i1] < v2[i2]) allora { v3[i3] = v1[i1]; i1++; i3++; }
se(v2[i1] > v2[i2]) allora { v3[i3] = v2[i2]; i2++; i3++; }
e se v1[i1] == v2[i2] ? Ovviamente incrementi entrambi gli indici e non inserisci niente.

Nota che devi fare un controllo per evitare che gli indici i1 e i2 vengano incrementati oltre i limiti.
Quando sono stati valutati tutti gli elementi esci...

papas_b
21-03-2007, 19:31
io avevo pensato a questa..


#include <iostream>
#include <cstdlib>
#define N 5
#define A 0

using namespace std;


int vect1[N]={1,3,7,9,10};
int vect2[N]={3,5,6,9,11};



void fusione(int Seq1[],int Seq2[],int N){
int Seq_diff[N];
for(int i=0;i<N;i++){
for(int j=0;j<N;j++)
if(Seq1[i]!=Seq2[j])
Seq_diff[i]=Seq1[j];
}
}

cionci
21-03-2007, 19:43
Se vuoi farlo con for annidati non sfrutti comunque il fatto che i vettori siano ordinati...se li hai inseriti ordinati solo per fare un esempio allora è un altro paio di maniche...
Con i for annidati inoltre non ottieni un terzo vettore ordinato...

Comunque c'è qualche errore, la struttura con i for annidati deve essere questa:

per i da 0 a N-1
inserisco l'elemento v1[i] in v_diff solo se è diverso da TUTTI gli elementi di v2

Però devi tenere conto anche di v2 perchè devi isnerire anche gli elementi di v2 in v3, quindi diventa:

per i da 0 a N-1
inserisco l'elemento v1[i] in v_diff solo se è diverso da TUTTI gli elementi di v2
inserisco l'elemento v2[i] in v_diff solo se è diverso da TUTTI gli elementi di v1

Il confronto con tutti gli elementi dell'altro vettore è ovviamente un ulteriore for, l'inserimento lo andrai a fare solo fuori dal for se non ci sono elementi uguali (quindi ti servirà un flag)

papas_b
21-03-2007, 19:55
no, nn devo inserire gli elementi di v2..ma solo quelli di v1 nn uguali a quelli di v2

poi, perke mi da errore qui "void fusione(int Seq1[],int Seq2[],int N){"?
il compilatore dice:
expected `,' or `...' before numeric constant
In function `int main()':
too many arguments to function `void fusione(int*, int*, int)'
at this point in file

ke vuol dire? forse centrano i puntatori?