PDA

Visualizza la versione completa : [C++]Ordinamento per Confronti Successivi


Skull260287
10-05-2008, 11:57
Salve a tutti, ho da proporvi un testo di un esercizio che richiede l'ordinamento per mezzo di confronti successivi, partendo da alcuni dati contenuti in un file. Come risolvereste l'algoritmo che effettua questo ordinamento. E' ovvio che conviene utilizzare insertionsort perchè questi record vengono letti da un file ed inseriti in un array di puntatori. Io per ora ho abbozzato questo codice, che pare non funzionare, ma non mi piace la soluzione di dover utilizzare i flag booleani.

Testo:

Dato il file binario impiegati contenente record del tipo

struct Tipostud{
string Nome; char[]
string Cognome; char[]
int anno;
int mese;
int giorno;
string Ruolo; char[]
double stipendio;
};
Per ogni ruolo ordinare gli impiegati per stipendio, a
parità di stipendio per cognome, a parità di cognome per
età,utilizzando eventualmente un array di puntatori.



void insort(Pstud Punt[],int n,Pstud Temp){

int j;
Punt[0]=Temp;
j=n-1;
bool cecks=false,ceckc=false;
while(Punt[j]->stipendio>=Punt[0]->stipendio){
cecks=true;
Punt[j+1]=Punt[j];
j--;
}
if(cecks && Punt[j]->stipendio==Punt[0]->stipendio &&
stricmp(Punt[j]->Cognome,Punt[0]->Cognome)>=0) {
ceckc=true;
Punt[j+1]=Punt[j];
j--;
}
if(ceckc && stricmp(Punt[j]->Cognome,Punt[0]->Cognome)==0 &&
DataNum(*Punt[j])>DataNum(*Punt[0])) {
Punt[j+1]=Punt[j];
j--;
}
Punt[j+1]=Punt[0];
}


Grazie e tutti coloro che parteciperanno.

MItaly
10-05-2008, 14:53
#include <cstdlib>
using namespace std;
//...
void SortStud(Tipostud ** array, size_t elements);
int StudCompare( const void *arg1, const void *arg2 );
//...
void SortStud(Tipostud ** array, size_t elements)
{
qsort((void *)array,elements,sizeof(*array), StudCompare);
}
int StudCompare(const void *arg1, const void *arg2)
{
Tipostud * t_arg1=*(Tipostud **)arg1, * t_arg2=*(Tipostud **)arg2;
int compResult;
if((compResult=(t_arg1->stipendio-t_arg2->stipendio))==0)
{
if((compResult=stricmp(t_arg1->Cognome,t_arg2->Cognome))==0)
{
if((compResult=(t_arg1->anno-t_arg2->anno))==0)
{
if((compResult=(t_arg1->mese-t_arg2->mese))==0)
{
if((compResult=(t_arg1->giorno-t_arg2->giorno))==0)
{
return 0;
}
}
}
}
}
return compResult;
}

Skull260287
10-05-2008, 18:56
Originariamente inviato da MItaly

#include <cstdlib>
using namespace std;
//...
void SortStud(Tipostud ** array, size_t elements);
int StudCompare( const void *arg1, const void *arg2 );
//...
void SortStud(Tipostud ** array, size_t elements)
{
qsort((void *)array,elements,sizeof(*array), StudCompare);
}
int StudCompare(const void *arg1, const void *arg2)
{
Tipostud * t_arg1=*(Tipostud **)arg1, * t_arg2=*(Tipostud **)arg2;
int compResult;
if((compResult=(t_arg1->stipendio-t_arg2->stipendio))==0)
{
if((compResult=stricmp(t_arg1->Cognome,t_arg2->Cognome))==0)
{
if((compResult=(t_arg1->anno-t_arg2->anno))==0)
{
if((compResult=(t_arg1->mese-t_arg2->mese))==0)
{
if((compResult=(t_arg1->giorno-t_arg2->giorno))==0)
{
return 0;
}
}
}
}
}
return compResult;
}

Gentilissimo, ora mi metto a studiare l'algoritmo che mi hai inviato per capirne il funzionamento e testarlo...grazie ancora..

Skull260287
11-05-2008, 11:04
Ho fatto svariati tentativi ma purtroppo nno sono riuscito a far funzionare il programma correttamente con questo algoritmo che mi hai segnalato, inoltre non ho trovato neppure una soluzione alternativa. Vi prego di darmi una mano, questa cosa mi sta asillando..riesco a fare esercizi di ogni genere, ma questo non vuole girare correttamente, martedì ho l'esame di Programmazione.....

Grazie mille

oregon
11-05-2008, 11:11
Se indichi genericamente un malfunzionamento, non si puo' fare molto ... si dovrebbe prendere tutto il progetto e provarlo di persona ...

Il codice dell'ordinamento e' corretto ... probabilmente ci sono dei problemi nella scrittura dei dati ... ma come si puo' esserne certi senza il codice e senza i dati?

Dovresti fare un po' di debugging, fermando l'esecuzione durante l'ordinamento e controllando il contenuto delle variabili e delle strutture man mano che viene eseguito ...

Skull260287
11-05-2008, 11:16
Originariamente inviato da oregon
Se indichi genericamente un malfunzionamento, non si puo' fare molto ... si dovrebbe prendere tutto il progetto e provarlo di persona ...

Il codice dell'ordinamento e' corretto ... probabilmente ci sono dei problemi nella scrittura dei dati ... ma come si puo' esserne certi senza il codice e senza i dati?

Dovresti fare un po' di debugging, fermando l'esecuzione durante l'ordinamento e controllando il contenuto delle variabili e delle strutture man mano che viene eseguito ...

Ok procederò come dici e vi farò sapere i risultati, una sola domanda quale codice di ordinamento è corretto? Quello segnalato da me o quello postato da MItaly? Perchè nell'usare quello ho anche un problema di assegnazione da double (stipendio nella mia struttura) a int nei parametri accettati da qsort.

MItaly
11-05-2008, 15:37
Il mio codice è collaudato con una versione ridotta della tua struttura e funziona. Studiatelo per capire come usare SortStud.


#include <cstdlib>
#include <iostream>
using namespace std;
struct Tipostud
{
char * Cognome;
int anno;
int mese;
int giorno;
double stipendio;
};
void SortStud(Tipostud ** array, size_t elements);
int StudCompare( const void *arg1, const void *arg2 );
void DisplayStud(Tipostud & stud);
int main()
{
Tipostud a, b, c;
Tipostud * arr[3]={&c, &a, &b};
a.Cognome = "Italia";
a.anno = 1990;
a.mese = 9;
a.giorno = 8;
a.stipendio=1500;
b.Cognome = "Castiglioni";
b.anno = 1958;
b.mese = 8;
b.giorno = 13;
b.stipendio=1000;
c.Cognome = "Castiglioni";
c.anno = 1932;
c.mese = 8;
c.giorno = 3;
c.stipendio=1000;
SortStud(arr,3);
DisplayStud(*arr[0]);
DisplayStud(*arr[1]);
DisplayStud(*arr[2]);
cin.sync();
cin.ignore();
return 0;
}
void DisplayStud(Tipostud & stud)
{
cout<<"---"<<endl
<<"Stipendio: "<<stud.stipendio<<endl
<<"Cognome: "<<stud.Cognome<<endl
<<"Data di nascita: "<<stud.giorno<<"/"<<stud.mese<<"/"<<stud.anno<<endl
<<"---"<<endl;
}
void SortStud(Tipostud ** array, size_t elements)
{
qsort((void *)array,elements,sizeof(*array), StudCompare);
}
int StudCompare(const void *arg1, const void *arg2)
{
Tipostud * t_arg1=*(Tipostud **)arg1, * t_arg2=*(Tipostud **)arg2;
int compResult;
if((compResult=(t_arg1->stipendio-t_arg2->stipendio))==0)
{
if((compResult=stricmp(t_arg1->Cognome,t_arg2->Cognome))==0)
{
if((compResult=(t_arg1->anno-t_arg2->anno))==0)
{
if((compResult=(t_arg1->mese-t_arg2->mese))==0)
{
if((compResult=(t_arg1->giorno-t_arg2->giorno))==0)
{
return 0;
}
}
}
}
}
return compResult;
}

Skull260287
11-05-2008, 18:59
Ciao, grazie, ho studiato la funzione ed ho capito come utilizarla. Su questa riga il mio compilatore (Dev-C++) mi da errore ([Warning] converting to `int' from `double') :


if((compResult=(t_arg1->stipendio-t_arg2->stipendio))==0)


L'ho riscitta così e sembra funzionare:



if((compResult=(static_cast<int>(t_arg1->stipendio)-static_cast<int>(t_arg2->stipendio)))==0)


Però provando con questo file che ti allego: rinominalo in .bin, l'ordinamento non viene effettuato correttamente.

Ecco il codice che ho utilizzato:



#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

struct Tipostud{
char Nome[20];
char Cognome[20];
int anno;
int mese;
int giorno;
char Ruolo[20];
double stipendio;
};
typedef Tipostud* Pstud;

void Inserimento (Tipostud &, char &);
void getfile(Pstud [],int );
void putfile(Pstud [],int ,int );
void stampa(Tipostud & stud);
void SortStud(Tipostud ** array, size_t elements);
int StudCompare( const void *arg1, const void *arg2 );

const char Nomefile[ ]="studenti2.bin";
const int Lrec=sizeof(Tipostud);
const int Numpers=8;

int main(){

char chr;
Tipostud studente;

/*
int Numpers;
cout<<"Numero di persone da inserire: ";
cin>>Numpers;
fstream filepers;
filepers.open("studenti.bin",ios::in|ios::out|ios::binary|ios::ate);
if (!filepers)
filepers.open("studenti.bin",ios::out|ios::binary|ios::trunc);
while(Numpers>0){
Inserimento(studente,chr);
if (chr=='s') {
filepers.seekp(0,ios::end);
filepers.write((char*)&studente,Lrec);
Numpers--;
}}
filepers.close();*/

Pstud PuntaP1[101];
getfile(PuntaP1,Lrec);
SortStud(PuntaP1,Numpers);
putfile(PuntaP1,Numpers,Lrec);

for(int k=1;k<=Numpers;k++){
stampa(*PuntaP1[k]);
}



system("pause");
return 0;

}

void Inserimento (Tipostud &pers1, char &ch)

{

cout << "INSERIMENTO PERSONE" << endl << endl;
cout << "Cognome= ";
cin >> pers1.Cognome;
cout << "Nome= ";
cin >> pers1.Nome;
cout << "Data di Nascita (GG MM AAAA)= ";
cin >> pers1.giorno >> pers1.mese >> pers1.anno;
cout << "Ruolo= ";
cin >> pers1.Ruolo;
cout << "Stipendio= ";
cin >> pers1.stipendio;
cout << "Salva (s/n)? ";
cin >> ch;

}

void getfile(Pstud PuntaP1[],int Lrec){

fstream file;
Tipostud studente;
file.open("studenti2.bin",ios::in|ios::out|ios::binary|ios::ate);
if (!file)
file.open("studenti2.bin",ios::out|ios::binary|ios::trunc);

int Numstud=file.tellg()/Lrec;

file.seekg(0,ios::beg);

for(int i=1;i<=Numstud;i++){

file.read((char*) &studente,Lrec);

PuntaP1[i]=new Tipostud;
*PuntaP1[i]=studente;
}
file.close();

}

void SortStud(Tipostud ** array, size_t elements)
{
qsort((void *)array,elements,sizeof(*array), StudCompare);
}
int StudCompare(const void *arg1, const void *arg2)
{
Tipostud * t_arg1=*(Tipostud **)arg1, * t_arg2=*(Tipostud **)arg2;
int compResult;
if((compResult=(static_cast<int>(t_arg1->stipendio)-static_cast<int>(t_arg2->stipendio)))==0)
{
if((compResult=stricmp(t_arg1->Cognome,t_arg2->Cognome))==0)
{
if((compResult=(t_arg1->anno-t_arg2->anno))==0)
{
if((compResult=(t_arg1->mese-t_arg2->mese))==0)
{
if((compResult=(t_arg1->giorno-t_arg2->giorno))==0)
{
return 0;
}
}
}
}
}
return compResult;
}


void putfile(Pstud Punt[],int Numero,int Lrec){

fstream file;
file.open("studenti.bin",ios::out|ios::ate|ios::binary);

if (!file)
file.open("studenti.bin",ios::out|ios::binary|ios::trunc);

for(int i=1;i<=Numero;i++){
file.write((char*) &*Punt[i],Lrec);
}
}

void stampa(Tipostud & stud){

cout<<"---"<<endl
<<"Stipendio: "<<stud.stipendio<<endl
<<"Cognome: "<<stud.Cognome<<endl
<<"Data di nascita: "<<stud.giorno<<"/"<<stud.mese<<"/"<<stud.anno<<endl
<<"---"<<endl;
}

MItaly
11-05-2008, 19:24
Originariamente inviato da Skull260287
Ciao, grazie, ho studiato la funzione ed ho capito come utilizarla. Su questa riga il mio compilatore (Dev-C++) mi da errore ([Warning] converting to `int' from `double') :


if((compResult=(t_arg1->stipendio-t_arg2->stipendio))==0)


L'ho riscitta così e sembra funzionare:



if((compResult=(static_cast<int>(t_arg1->stipendio)-static_cast<int>(t_arg2->stipendio)))==0)


Bastava semplicemente


if((compResult=(int)(t_arg1->stipendio-t_arg2->stipendio))==0)



Però provando con questo file che ti allego: rinominalo in .bin, l'ordinamento non viene effettuato correttamente.

Non c'è nessun allegato...

Skull260287
11-05-2008, 19:40
Scusami, non me l'ha fatto passare per via della modifica dell'astensione, puoi scaricarlo da qui: http://www.galileonews.it/files/studenti.bin


Grazie Mille per L'aiuto che mi stai dando.

Il file è un elenco gìà ordinato che dovrebbe rimanere tale ed invece non lo risulta.

Loading