ciao a tutti, oltre al dizionario con semplice tavola hash che ho implementato nel post precedente, sto implementando anche un dizxionario con liste di trabocco. in fase di test dei metodi l'esecuzione va in crash in appena arriva su un'istruzione che è fatti in modo corretto, cioè su una semplice
cin >> k
che prende da tastiera una stringa e la memorizza nella variabile k che è di tipo char *.
posto i codici che ho implementato per la struttura dizionario con liste di trabocco.
nodop.h
codice:
#ifndef nodop_h
#define nodop_h
#include<iostream>
#include<stdlib.h>
using namespace std;
template<class tipoelem>
class nodop
{
public:
nodop();
void setprec(nodop *);
void setelem(tipoelem);
void setsuc(nodop *);
nodop *getprec();
tipoelem getelem();
nodop *getsuc();
nodop operator=(nodop);
private:
nodop *precedente;
tipoelem elemento;
nodop *successivo;
};
#endif
template<class tipoelem>
nodop<tipoelem>::nodop()
{
precedente = NULL;
successivo = NULL;
}
template<class tipoelem>
void nodop<tipoelem>::setprec(nodop *prec)
{
precedente = prec;
}
template<class tipoelem>
void nodop<tipoelem>::setelem(tipoelem elem)
{
elemento = elem;
}
template<class tipoelem>
void nodop<tipoelem>::setsuc(nodop *suc)
{
successivo = suc;
}
template<class tipoelem>
nodop<tipoelem> *nodop<tipoelem>::getprec()
{
return(precedente);
}
template<class tipoelem>
tipoelem nodop<tipoelem>::getelem()
{
return(elemento);
}
template<class tipoelem>
nodop<tipoelem> *nodop<tipoelem>::getsuc()
{
return(successivo);
}
template<class tipoelem>
nodop<tipoelem> nodop<tipoelem>::operator=(nodop<tipoelem> node)
{
this->precedente = node.getprec();
this->elemento = node.getelem();
this->successivo = node.getsuc();
}
dizionario.h
codice:
#ifndef dizionario_h
#define dizionario_h
#include<iostream>
#include<stdlib.h>
using namespace std;
template<class tipoelem>
class dizionario
{
public:
virtual void creadizionario() = 0;
virtual bool appartiene(char *) = 0;
virtual void inserisci(tipoelem) = 0;
virtual void cancella(char *) = 0;
virtual tipoelem recupera(char *) = 0;
virtual void aggiorna(char *, tipoelem) = 0;
void test();
};
#endif
template<class tipoelem>
void dizionario<tipoelem>::test()
{
cout << " ***test del metodo APPARTIENE***\n\n";
cout << "il metodo controlla se la chiave fornita come argomento e' presente o meno\n";
cout << "nel dizionario.\n\n";
cout << " inserimento nel dizionario dell'elemento:\n";
cout << " valore dell'elemento: ";
tipoelem elem = new char;
cin >> elem;
this->inserisci(elem);
cout << " test con esito negativo:\n";
cout << " appartiene(totaro) = " << this->appartiene("totaro") << "\n\n";
cout << " test con esito positivo:\n";
cout << " appartiene(laforgia) = " << this->appartiene("laforgia") << "\n\n\n\n";
cout << " ***test del metodo RECUPERA***\n\n";
cout << "il metodo fornisce il valore dell'elemento con la relativa chiave che viene\n";
cout << "passato come argomento.\n\n";
cout << " recupera(laforgia) = " << this->recupera("laforgia") << "\n\n";
cout << " ***test del metodo AGGIORNA***\n\n";
cout << "il metodo cambia il valore dell'elemento con la relativa chiave passata come\n";
cout << "argomento.\n\n";
cout << " inserire il valore da sostituire: ";
cin >> elem;
this->aggiorna("laforgia", elem);
cout << " recupera(laforgia) = " << this->recupera("laforgia") << "\n\n";
cout << " ***test del metodo CANCELLA***\n\n";
cout << "il metodo elimina dal dizionario l'elemento con la chiave fornita come argomento.\n";
this->cancella("laforgia");
cout << " recupera(laforgia) = " << this->recupera("laforgia") << "\n\n";
}
dizionariolt.h
codice:
#ifndef dizionariolt_h
#define dizionariolt_h
#include<assert.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include "nodop.h"
using namespace std;
template<class tipoelem>
class dizionariolt : public dizionario<tipoelem>
{
public:
dizionariolt(int);
void creadizionario();
bool appartiene(char *);
void inserisci(tipoelem);
void cancella(char *);
tipoelem recupera(char *);
void aggiorna(char *, tipoelem);
private:
int dimtavola;
typedef struct Elemento
{
tipoelem valore;
char *chiave;
} elemento;
nodop< struct Elemento> **tavola;
int h(char *);
};
#endif
template<class tipoelem>
int dizionariolt<tipoelem>::h(char *key)
{
int i = 0;
int result = 0;
int c = key[i];
int tmp[strlen(key)];
while(c != '\0')
{
if((c >= 48) && (c <= 57))
tmp[i] = c - 48;
else
{
if((c >= 65) && (c <= 90))
tmp[i] = c - 64;
else
{
if((c >= 97) && (c <= 122))
tmp[i] = c - 96;
}
}
i++;
c = key[i];
}
i = strlen(key);
while(i != 0)
{
result += tmp[i - 1] * (int)pow(13, (strlen(key) - i));
i--;
}
result = result % dimtavola;
return result;
}
template<class tipoelem>
dizionariolt<tipoelem>::dizionariolt(int dimvet)
{
dimtavola = dimvet;
this->creadizionario();
}
template<class tipoelem>
void dizionariolt<tipoelem>::creadizionario()
{
tavola = new nodop<struct Elemento> *[dimtavola];
for(int i = 0; i < dimtavola; i++)
tavola[i] = NULL;
}
template<class tipoelem>
bool dizionariolt<tipoelem>::appartiene(char *k)
{
bool risultato = false;
nodop<struct Elemento> *tmp = tavola[h(k)];
bool trovato = false;
while(!trovato && (tmp != NULL))
{
if(tmp->getelem().chiave == k)
trovato = true;
else
tmp = tmp->getsuc();
}
return risultato;
}
template<class tipoelem>
void dizionariolt<tipoelem>::inserisci(tipoelem elem)
{
cout << "inserire la chiave dell'elemento " << elem << ": ";
char *k = new char;
cin >> k;
if(this->appartiene(k))
cout << "elemento gia' esistente nel dizionario.\n\n";
else
{
elemento el;
el.valore = elem;
el.chiave = k;
nodop<struct Elemento> *tmp = new nodop<struct Elemento>;
tmp->setelem(el);
if(tavola[h(k)] == NULL)
tavola[h(k)] = tmp;
else
{
tmp->setsuc(tavola[h(k)]);
tavola[h(k)] = tmp;
}
}
}
template<class tipoelem>
void dizionariolt<tipoelem>::cancella(char *k)
{
if(!this->appartiene(k))
cout << "elemento non presente nel dizionario.\n\n";
else
{
if(tavola[h(k)]->getsuc() == NULL)
tavola[h(k)] = NULL;
else
{
bool trovato = false;
nodop<struct Elemento> *p = tavola[h(k)];
while(!trovato)
{
if(p->getelem().chiave == k)
trovato = true;
else
p = p->getsuc();
}
nodop<struct Elemento> *tmp = tavola[h(k)];
while(tmp->getsuc() != p)
tmp = tmp->getsuc();
tmp->setsuc(p->getsuc());
delete p;
}
}
}
template<class tipoelem>
tipoelem dizionariolt<tipoelem>::recupera(char *k)
{
assert(this->appartiene(k));
bool trovato = false;
nodop<struct Elemento> *p = tavola[h(k)];
while(!trovato)
{
if(p->getelem().chiave == k)
trovato = true;
else
p = p->getsuc();
}
return(p->getelem().valore);
}
template<class tipoelem>
void dizionariolt<tipoelem>::aggiorna(char *k, tipoelem elem)
{
assert(this->appartiene(k));
bool trovato = true;
nodop<struct Elemento> *p = tavola[h(k)];
while(!trovato)
{
if(p->getelem().chiave == k)
{
elemento el;
el.chiave = p->getelem().chiave;
el.valore = elem;
p->setelem(el);
trovato = true;
}
else
p = p->getsuc();
}
}
testdizionari.cpp
codice:
#include "dizionario.h"
#include "dizionariothc.h"
#include "dizionariolt.h"
#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
dizionariolt<char *> D(10);
D.test();
system("pause");
return 0;
}
l'istruzione che fa andare in crash l'esecuzione è quella in rosso. perchè fa questo???