Newsgroup: it.comp.lang.c++
Titolo: Eliminare l'ennesimo dato nella lista

Salve ragazzi:
Ho un problema grosso grosso...
In pratica ho una lista di concorrenti (ogni concorrente č un nodo della
lista della classe Concorrente) realizzata con i template...
In pratica dovrei creare una funzione EliminaDato che ha in input un intero
e che elimini dalla lista il concorrente che si trova in quella posizione...
Supponiamo di avere tre concorrenti:
Mario Rossi 34punti
Luca Fabiani 35punti
Maria Bianchi 12punti
Se io da programma principale richiamo la funzione lista.EliminaDato(2) mi
deve eliminare in nodo Luca Fabiani col relativo punteggio ed aggiornare il
puntatore al tipo generico Dato presente nel concorrente Mario Rossi in modo
che punti al Dato Maria Bianchi e non piů al Dato Luca Fabiani come prima...
Mi sono spiegato? Spero di si...
Io vi posto la mia classe al completo in modo che possiate testare l'errore
(sono piů di 1). La funzione  virtual L EliminaDato(int x) č quella da
correggere come ho spiegato sopra... Io l'ho abbozzata ma non funziona. Mi
aiutate voi?
Grazie.
#include <iostream.h>
#include <conio.h>
#include <iomanip.h>
template <class L> class Dato
{
public:
  L dato;
  Dato<L> *successivo;
  Dato<L>(L d, Dato<L> *n=0) : dato(d), successivo(n) {}
};
template <class L> class Lista {
  Dato<L> *cima;
  Dato<L> *coda;
  int conta;
  public:
  //Costruttore
  Lista():cima(0),coda(0),conta(0){}
  //Distruttore
  ~Lista() {
    Dato<L> *Dato = cima;
    while (Dato) {
      cima = Dato->successivo;
      delete Dato;
      Dato = cima;
    }
  }
  virtual bool Push(L &d)
  {
    Dato<L> *p = new Dato<L>(d);
    if (!p)
    {
      cerr << "\nMemoria esaurita\n";
      return false;
    }
    if (cima) coda->successivo = p;
    else cima = p;
    coda = p;
    conta++;
    return true;
  }
  virtual L Pull()
  {
    Dato<L> *p = cima;
    Concorrente d;
    if (p)
    {
      d = p->dato;
      cima = p->successivo;
      delete(p);
      conta--;
    }
    return d;
  }
  virtual double N_Concorrenti()
  {
    return conta;
  }
  virtual L EliminaDato(int x)
  {
    Dato<L> *p = cima;
    for (int i=0; i<x; i++) {
      p=p->successivo;
    }
    delete(p);
    p=p->successivo;
    conta--;
  }
};
//Classe Concorrente
class Concorrente {
  friend int operator > (const Concorrente &x,const Concorrente &y);
  public:
    char Cognome[20];
    char Nome[20];
    int Punteggio;
    int Continua;
    Concorrente():Cognome(),Nome(),Punteggio(0),Continua(0){}
    Concorrente operator = (const Concorrente &x);
};
int operator > (const Concorrente &x,const Concorrente &y)
{
  int i=0;
  int j=0;
  if (x.Punteggio==y.Punteggio)
   {
    i=strcmp(y.Cognome,x.Cognome);
    if (i==0) {
      j=strcmp(y.Nome,x.Nome);
      return ((j==0) || (j>0));
    }
    if (i>0) return 1;
    if (i<0) return 0;
   }
  else return (x.Punteggio>y.Punteggio);
}
Concorrente Concorrente::operator = (const Concorrente &x)
{
  strcpy(this->Cognome,x.Cognome);
  strcpy(this->Nome,x.Nome);
  this->Punteggio=x.Punteggio;
  this->Continua=x.Continua;
  return *this;
}
//Collaudo
void main()
{
  Lista<Concorrente> lista;
  Concorrente dato;
  Concorrente save;
  int check=0;
  int k;
  char risposta;
  cout << "Immissione di un Dato (S/N)? ";
  cin >> risposta;
  if ((risposta=='s') || (risposta=='S')) dato.Continua=1;
  else dato.Continua=0;
  while (dato.Continua)
  {
    //Controllo
    cout << "Inserisci il cognome: ";
    cin >> dato.Cognome;
    cout << "Inserisci il nome: ";
    cin >> dato.Nome;
    cout << "Inserisci il punteggio: ";
    cin >> dato.Punteggio;
    //Immissione
    if (!(lista.Push(dato))) return;
    cout << "Immissione di un Dato (S/N)? ";
    cin >> risposta;
    if ((risposta=='s') || (risposta=='S')) dato.Continua=1;
    else dato.Continua=0;
  } //fine while
  cout << endl;
  cout << "Procedere allo svuotamento della lista (S/N)? ";
  cin >> risposta;
  if (risposta!='S' && risposta!='s') return;
  cout << "Inserisci il numero del dato da eliminare (max " <<
lista.N_Concorrenti() << "): ";
  cin >> k;
  lista.EliminaDato(--k);
  while (lista.N_Concorrenti())
  {
    dato = lista.Pull();
    if (dato>save) save=dato;
    cout << setw(10) << dato.Cognome << " " << dato.Nome << " " <<
dato.Punteggio << endl;
    check=1;
  }
  if (check)
  cout << "Punteggio piu alto: " << save.Cognome << " " << save.Nome << " "
<< save.Punteggio << endl;
  cout << "La memoria e' stata liberata";
  while (!kbhit());
}
--
----------------------------------------
Carlo Camarda
chiamac...@tiscalinet.it
]@#[ Anna I Love You ]#@[

 posizione...
Forse un errore di disegno; se hai bisogno di accesso random rapido
usa un altro tipo di container.
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy          loreti at pd dot infn dot it

 Forse un errore di disegno; se hai bisogno di accesso random rapido
Ehm...
Scusa ma non sono molto pratico di c e non ho capito una mazza di quello che
hai detto...
Cmq non è un mio piccio di fare questo, ma è un esercizio per la scuola ed
il prof lo vuole così...
Se sapessi aiutarmi mi farebbe piacere...
Grazie


 Grazie
Prego.


Azz che spiritoso che sei...
Cmq il professore non ci ha mai detto come si leva un dato dal centro di una
lista...
Cioè tecnicamente lo so...
Basta far puntare un puntatore del dato precedente al dato successivo della
lista e togliere quello centrale...
Il problema è dirglielo al computer :-)
Vabe ci proverò da solo...
Grazie lo stesso e grazie per le spiegazioni...
Ciao


 Il problema è dirglielo al computer :-)
Dipende dal tipo di lista: se la lista è semplice, cioè se ogni nodo ha solo
un puntatore che punta all'elemento successivo, allora procedi così:
- se l'elemento da cancellare è la testa, salvi il puntatore alla testa in
un puntatore temporaneo, fai puntare la testa al secondo elemento, ed
elimini il puntaore salvato;
- altrimenti fai una ricerca usando il puntatore al successivo elemento del
nodo corrente; una volta trovato, lo salvi, fai puntare il nodo corrente a
quello che sta due posti dopo, ed elimini il puntatore salvato.
Supponendo che un nodo sia una struct di questo tipo:
struct Node {
    Node *next;
    int val;
}
piu o meno viene così:
cur = head;
if (cur->val == val_to_delete) {
    Node *temp = cur;
    head = cur->next;
    delete cur;
    return 0;
}
while (cur->next) {
    if (cur->next->val == val_to_delete) {
        Node *temp = cur->next;
        cur->next = temp->next;
        delete temp;
        return 0;
    }
    cur = cur->next;
}
return 1;
Se la lista è doppia, cioè ogni nodo ha anche un puntatore all'elemento
precedente, allora devi anche ricordarti di far puntare l'elemento
successivo a quello che elimini all'elemento precedente; occhio a quando
elimini l'ultimo elemento.
--
ciao,
Cecco
---------
Visit: 
www.sourceforge.net/projects/dlab
Home Page: 
http://dlab.sourceforge.net/
Dlab-developer mailing list
https://lists.sourceforge.net/lists/listinfo/dlab-developer

deve eliminare in nodo Luca Fabiani col relativo punteggio
Non mi sembra stilisticamente corretto avere una lista di dati
identificati da un nome(quindi una stringa) e manipolarli tramite un
indice. A mio avviso, se vuoi fare una cosa carina ed efficiente
potrersi basarti su uno std::map<std::string,concorrente>, dove il
nome del concorrente é la chiave e la classe concorrente il
contenitore dei suoi dati(che contiene quindi punteggio, ecc.ecc.).
Per rimuovere un concorrente in questo caso di basterebbe fare
std::map<std::string,concorrente> mappa;
/*.......*/
mappa.erase("nomeconcorrente");
é chiaro che detto cosi' sembra un pò grezzo, ma potresti comunque
wrappare la gestione dei concorrenti dentro un' unica classe che
contiene anche il dizionario, e fornire una serie di funzioni membro
che ti permettono di eseguire le operazioni sui concorrenti.
Il Ghenio
---------
// TODO: Place your ass here

 contenitore dei suoi dati(che contiene quindi punteggio, ecc.ecc.).
Leggi il post che ho mandato a Maurizio...
te lo riporto per evitarti la ricerca...
[CUT]
Cmq non è un mio piccio di fare questo, ma è un esercizio per la scuola ed
il prof lo vuole così...
[/CUT]
Capito?
Fosse per me non lo farei ne in un modo ne nell'altro...
Ciao


[/CUT]
Gli esercizi purtroppo non sono sempre utili come sembrano.
Nella programmazione reale é molto più utile essere in grado di
sfruttare le caratteristiche del linguaggio che si usa piuttosto che
reinventarsi la ruota, e nel caso del C++ sfruttare il linguaggio
significa che non si ha bisogno di crearsi a mano il codice per
gestire una lista in quanto lo standard te lo offre già pronto, con i
vantaggi che puoi immaginare( sicurezza,portabilità, maggiore
produttività, ecc...ecc.).


 ha scritto nel messaggio
news:vMP1PD0enoPm3V...@4ax.com...

Si, immagino e ti dico che per me va bene come dici tu... Ma il prof lo
vuole così e basta...
E come se il prof mi dice:
Fai un programma in pascal che trasformi una stringa nella corrispondente
maiuscola e io gli scrivo:
Program stringa;
Begin
S:=Upcase(S);
End.
Mi capisci? Forse il suo intento è quello di farci capire come ragionare
(come dovrebbe essere di norma) e non farci fare cose belle e fatte...
Ciaooo


 (sono più di 1). La funzione  virtual L EliminaDato(int x) è quella da


Attento ho notato di aver dimenticato i punti e virgola alla fine della 
classe e della struct...
scusate, ma ho proprio fretta :-((((
S.

 ha scritto nel messaggio
news:zyqJ8.32001$8x3.6...@twister1.libero.it...

Grazie 1000 la provo subito...
