Click to See Complete Forum and Search --> : hash_map problems...


juanpast
June 24th, 2008, 03:50 AM
Hi Gurus!!


Thanks in advance.


I need to construct a hash table, I use STL hash_map template but I have some errors. I am using Visual Studio 2003 and it is my code:


#include <hash_map>
#include <vector>

struct eqstr {
bool operator()(char* s1, char* s2) {
return strcmp(s1, s2) == 0;
}
};

class CSimplificada {
public:
BOOL nTipo; // 0 S1 1 S2
char sKey[256];
vector <int> vnPosInFile;

CSimplificada() {
sKey[0] = '\0';
nTipo = -1;
vnPosInFile.clear();
}
const CSimplificada & operator = (const CSimplificada &s) {
strcpy(sKey, s.sKey);
nTipo = s.nTipo;
vnPosInFile = s.vnPosInFile;
return *this;
}
bool operator < (const CSimplificada &s) {
if(strcmp(sKey, s.sKey) < 0) return true;
return false;
}
bool operator == (const CSimplificada &s) {
if(strcmp(sKey, s.sKey) == 0 && nTipo == s.nTipo) return true;
return false;
}
};



When I try to declare hash_map, for example:

hash_map <char *,CSimplificada,hash_compare <char*>, eqstr> hashMapS1;


I get compiler errors. Is right the code? what is happening?


Very thanks!!!

juanpast
June 24th, 2008, 04:32 AM
I change the code and now compile:


struct eqstr {
bool operator()(const char* s1, const char* s2) const {
return strcmp(s1, s2) == 0;
}
};


and


hash_map <char *,CSimplificada,hash_compare <char*, eqstr> > hashMapS1;


But when I search for one key not found it:


hash_map <char *,CSimplificada,hash_compare <char*, eqstr> >::iterator itBusca;
CSimplificada sS1;
for(int i=0;i<nRecords;i++) { // nRecords is the number of records where a have the data
itBusca = hashMapS1.find(sKey); // sKey is declared as: char sKey[256]; and fill which data of the i-record
if(itBusca == itS1End) { // not found, add the new key and data
sS1.nTipo = S1; // S1 is: #define S1 0
sS1.vnPosInFile.push_back(i);
hashMapS1[sKey] = sS1;
} else { // encontrado
itBusca->second.vnPosInFile.push_back(i);
}
}



the term: if(itBusca == itS1End) allways evaluated as true but I can find records with the same key.

What is happening now?

GNiewerth
June 24th, 2008, 04:54 AM
Is there a specific reason why you use char[256] instead of string?
Did you make sure the char* used as hash_map key never goes out of scope and remains constant?
Each time you change the sKey string to something different it also affects the elemt already stored in your hash_map, because its key points to sKey. You always refer to the same memory address, thatīs why find always returns a valid iterator.

a1ex07
June 24th, 2008, 11:02 AM
the term: if(itBusca == itS1End) allways evaluated as true but I can find records with the same key.
What is happening now
I haven't worked with Studio 2003 for a long time, but I hope that hash_map implementation in Studio 2005 is the same. The problem is that Microsoft hash_map requires keys to be less than comparable, so instead of eqstr you need less_str (or greater_str, whatever you like). For example

struct less_str {
bool operator()(const char* x, const char* y) const {
if ( strcmp(x, y) > 0)
return true;

return false;
}
};

Now your hash_map looks like
typedef stdext::hash_map <char *,CSimplificada, stdext::hash_compare <char*, less_str> > HM;
and HM::find(key) will return expected results

juanpast
June 25th, 2008, 04:07 AM
thanks!!!


I create a simple project to check this tag. It is a V2003 project:


By carefull with the file path....

"D:\\tono\\Fuentes\\Hash_mapExample\\Hash_mapExample\\List.txt"


And


"D:\\tono\\Fuentes\\Hash_mapExample\\Hash_mapExample\\Output.txt"



Thanks a lot

juanpast
June 25th, 2008, 06:27 AM
I obtain a good results!!!!


Here you are the solution. I need to change CString by string because CString not have size_t operator.


Thanks in any case.


Regards