Template funzione di ordinamento

di il
9 risposte

Template funzione di ordinamento

Ciao, sono ancora inesperto riguardo la programmazione in c++ poichè lo studio da meno di un anno. Ho un problema, devo fare un template della funzione di ordinamento usando il bubble sort e fin qui tutto ok, il vero problema è ordinare uno struct(in questo caso di studenti dove definisco il nome e il voto) e scegliere all'invocazione della funzione secondo quale campo posso ordinarlo, come posso fare?
Posto il template da me scritto:

template <typename T>
void Ordina(T *vet, int nv)
{
	int scambi;
	do
	{
		scambi=0;
		for(int i=0; i<nv-1; i++)
		{
			if(vet[i]>vet[i+1])
			{
				T appoggio=vet[i];
				vet[i]=vet[i+1];
				vet[i+1]=appoggio;
				scambi++;
			}
		}
	} while(scambi!=0);
}
Grazie anticipate.

9 Risposte

  • Re: Template funzione di ordinamento

    Una soluzione veloce è questa
    
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    enum ordinamento {VOTO,NOME};
    ordinamento ord = VOTO;
    
    struct studenti
    {
    	string nome;
    	int voto;
    
    
    	studenti & operator=(const studenti & rhs)
    	{
    		if(this != &rhs)
    		{
    			nome = rhs.nome;
    			voto = rhs.voto;
    		}
    		return *this;
    	}
    
    	bool operator > (const studenti & rhs) const
    	{
    		if(ord == VOTO)
    			return voto > rhs.voto;
    		else
    			return nome > rhs.nome;
    	}
    
    };
    
    template <typename T>
    void Ordina(T *vet, int nv)
    {
    	int scambi;
    
    	do
    	{
    		scambi=0;
    		for(int i=0; i<nv-1; i++)
    		{
    			if(vet[i]>vet[i+1])
    			{
    				T appoggio=vet[i];
    				vet[i]=vet[i+1];
    				vet[i+1]=appoggio;
    				scambi++;
    			}
    		}
    	} while(scambi!=0);
    }
    int main()
    {
    	studenti stud[100];
    	ord = VOTO;
    	Ordina(stud,100);
    	ord = NOME;
    	Ordina(stud,100);
    	return 0;
    }
    
    
    Ma non mi piace molto perche definisce una varibaile globale. Vediamo se riusciamo a trovarti una solzione più ortodossa
  • Re: Template funzione di ordinamento

    Grazie mille, allora aspetto anche altre soluzioni, grazie davvero :)
  • Re: Template funzione di ordinamento

    C'è un piccolo problema, io il programma l'avevo scritto cosi, in questo modo ci sono purtroppo cose che non capisco, metto il mio codice x intero:
    // template.cpp : file di progetto principale.
    
    #include "stdafx.h"
    #include "iostream"
    #include "time.h"
    using namespace System;
    using namespace std;
    template <class C>
    void Stampa(C *vet, int nv)
     {for(int i=0; i<nv; i++)
    	cout<<vet[i]<<endl;}
    template <typename T>
    void Ordina(T *vet, int nv)
    {int scambi;
    do{scambi=0; 
    for(int i=0; i<nv-1; i++)
    	{if(vet[i]>vet[i+1])
    		{T appoggio=vet[i];
    		vet[i]=vet[i+1];
    		vet[i+1]=appoggio;
    		scambi++;}}} while(scambi!=0);}
    void main()
    {int vet[3];
    vet[0]=2;
    vet[1]=7;
    vet[2]=3;
     int nv=3;
     cout<<"Stampa di un vettore intero"<<endl;
    Stampa(vet, nv);
    Ordina(&vet[0], nv);
    cout<<"Stampa di un vettore intero ordinato"<<endl;
    Stampa(vet, nv);
    double ciao[3];
    ciao[0]=1.5;
    ciao[1]=9.2;
    ciao[2]=8.4;
    cout<<"Stampa di un vettore double"<<endl;
    Stampa(ciao, nv);
    Ordina(&ciao[0], nv);
    cout<<"Stampa di un vettore double ordinato"<<endl;
    Stampa(ciao, nv);
    system("pause");}
    
    E' possibile adattare questo agli astruct? Grazie ancora per la disponibilità.
  • Re: Template funzione di ordinamento

    Tutto si può fare ma per primo metti un codice un pò + leggibile così si capisce niente. Vedo che usi visual studio (stdafx.h) come fa il compilatore a non darti come minimo 2 errori. void main e System?
    stai compilando in CLI ovvero Managed C++?
  • Re: Template funzione di ordinamento

    Soluzione continuando quello di prima
    
    #include "stdafx.h"
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    enum ordinamento {VOTO,NOME};
    ordinamento ord = VOTO;
    
    struct studenti
    {
       string nome;
       int voto;
    
       friend ostream & operator <<(ostream & os, const studenti & rhs)
       {
    	   os << rhs.nome << " - " << rhs.voto << endl;
    	   return os;
       }
    
       studenti & operator=(const studenti & rhs)
       {
          if(this != &rhs)
          {
             nome = rhs.nome;
             voto = rhs.voto;
          }
          return *this;
       }
    
       bool operator > (const studenti & rhs) const
       {
          if(ord == VOTO)
             return voto > rhs.voto;
          else
             return nome > rhs.nome;
       }
    };
    
    
    
    template <class C>
    void Stampa(C *vet, int nv)
    {
    	for(int i=0; i<nv; i++)
    		cout<<vet[i]<<endl;
    }
    
    template <typename T>
    void Ordina(T *vet, int nv)
    {
    	int scambi;
    	do
    	{
    		scambi=0;
    		for(int i=0; i<nv-1; i++)
    		{
    			if(vet[i]>vet[i+1])
    			{
    				T appoggio=vet[i];
    				vet[i]=vet[i+1];
    				vet[i+1]=appoggio;
    				scambi++;
    			}
    		}
    	} while(scambi!=0);
    }
    
    int main()
    {
    	studenti vet[3];
    	vet[0].nome = "Tizio";
    	vet[0].voto = 18;
    	vet[1].nome = "Pallo";
    	vet[1].voto = 15;
    	vet[2].nome = "Pinco";
    	vet[2].voto = 25;
    	int nv=3;
    	cout<<"Stampa di un vettore"<<endl;
    	Stampa(vet, nv);
    
    	Ordina(&vet[0], nv);
    	cout<<"Stampa di un vettore intero ordinato per voto"<<endl;
    	Stampa(vet, nv);
    
    	ord = NOME;
    	Ordina(&vet[0], nv);
    	cout<<"Stampa di un vettore intero ordinato per nome"<<endl;
    	Stampa(vet, nv);
    }
    
    Significa che devi imparare l'overload degli operatori.
  • Re: Template funzione di ordinamento

    Ho scritto il codice spero sia un pò più comprensibile, alla compilazione non mi da nessun errore e funziona perfettamente, ora dovrei solo capire come passare al template il criterio di ordinamento dello struct una volta fatto quello credo di riuscire a modificare il resto,  comunque sto compilando in CLR.
    
    #include "stdafx.h"
    #include "iostream"
    
    using namespace System;
    using namespace std;
    
    template <class C>
    void Stampa(C *vet, int nv)
     {for(int i=0; i<nv; i++)
       cout<<vet[i]<<endl;}
    
    template <typename T>
    void Ordina(T *vet, int nv)
    	{int scambi;
    	do{scambi=0; 
    	for(int i=0; i<nv-1; i++)
      		 {if(vet[i]>vet[i+1])
         	 {T appoggio=vet[i];
          		vet[i]=vet[i+1];
          		vet[i+1]=appoggio;
          		scambi++;}}} while(scambi!=0);}
    void main()
    {int vet[3];
    vet[0]=2;
    vet[1]=7;
    vet[2]=3;
    
     int nv=3;
    
    cout<<"Stampa di un vettore intero"<<endl;
    Stampa(vet, nv);
    
    
    Ordina(&vet[0], nv);
    cout<<"Stampa di un vettore intero ordinato"<<endl;
    
    Stampa(vet, nv);
    
    double ciao[3];
    ciao[0]=1.5;
    ciao[1]=9.2;
    ciao[2]=8.4;
    
    cout<<"Stampa di un vettore double"<<endl;
    Stampa(ciao, nv);
    
    Ordina(&ciao[0], nv);
    cout<<"Stampa di un vettore double ordinato"<<endl;
    Stampa(ciao, nv);
    
    system("pause");} 
  • Re: Template funzione di ordinamento

    Allora non sei in C++ ma in managed C++.
    http://it.wikipedia.org/wiki/Common_Language_Runtim
    cmq leggi la soluzione sopra.
  • Re: Template funzione di ordinamento

    Ho letto la soluzione sopra, e ti ringrazio, il fatto è che la professoressa mi ha chiesto di passare il criterio di ordinamento( per nome o per voto) direttamente al template. E non so come si fa.
  • Re: Template funzione di ordinamento

    Ecco la soluzione togliendo l'enum globale.
    
    #include "stdafx.h"
    #include <iostream>
    #include <functional>
    #include <string>
    
    using namespace std;
    
    struct studenti
    {
       string nome;
       int voto;
    
       friend ostream & operator <<(ostream & os, const studenti & rhs)
       {
          os << rhs.nome << " - " << rhs.voto << endl;
          return os;
       }
    
       studenti & operator=(const studenti & rhs)
       {
          if(this != &rhs)
          {
             nome = rhs.nome;
             voto = rhs.voto;
          }
          return *this;
       }
    
       bool ordinaNome(const studenti & rhs) const
       {
          return nome > rhs.nome;
       }
    
        bool ordinaVoto(const studenti & rhs) const
       {
          return voto > rhs.voto;
       }
    };
    
    
    template <class C>
    void Stampa(C *vet, int nv)
    {
       for(int i=0; i<nv; i++)
          cout<<vet[i]<<endl;
    }
    
    template <typename T, typename C>
    void Ordina(T *vet, int nv, C c)
    {
       int scambi;
       do
       {
          scambi=0;
          for(int i=0; i<nv-1; i++)
          {
             if(c(vet[i+1],vet[i]))
             {
                T appoggio=vet[i];
                vet[i]=vet[i+1];
                vet[i+1]=appoggio;
                scambi++;
             }
          }
       } while(scambi!=0);
    }
    
    int main()
    {
    	studenti vet[3];
       vet[0].nome = "Tizio";
       vet[0].voto = 18;
       vet[1].nome = "Pallo";
       vet[1].voto = 15;
       vet[2].nome = "Pinco";
       vet[2].voto = 25;
       int nv=3;
       cout<<"Stampa di un vettore"<<endl;
       Stampa(vet, nv);
    
       Ordina(&vet[0], nv,mem_fun_ref(&studenti::ordinaVoto));
       cout<<"Stampa di un vettore intero ordinato per voto"<<endl;
       Stampa(vet, nv);
    
        Ordina(&vet[0], nv,mem_fun_ref(&studenti::ordinaNome));
       cout<<"Stampa di un vettore intero ordinato per nome"<<endl;
       Stampa(vet, nv);
    }
    
    
    Praticamente chiami le funzioni membro della struttura a seconda del tipo di ordinamento.
    Al template li passi un functor reso possibile dalla funzione mem_fun_ref del header functional. Ma non so se ste cose li hai imparate o li devi imparare. Cmq un metodo più semplice non lo vedo io.
Devi accedere o registrarti per scrivere nel forum
9 risposte