strtoint sprintf dev convert c++ hash string cstring

sprintf - strtoint c++



¿Cómo puedo enlazar una cadena a un int usando c++? (9)

Aquí hay una función hash C (++) que encontré en el libro de Stroustrup:

int hash(const char *str) { int h = 0; while (*str) h = h << 1 ^ *str++; return h; }

Si lo está utilizando para una tabla hash (lo que hace Stroustrup), en su lugar, puede devolver a los abs del módulo hash un número primo. Así que en vez

return (h > 0 ? h : -h) % N_BUCKETS;

para la ultima linea

Tengo que escribir mi propia función hash. Si quisiera simplemente realizar la función hash simple que asigna cada letra de la cadena a un valor numérico (es decir, a = 1, b = 2, c = 3, ...), ¿hay alguna manera de poder realizar este hash en una cadena sin tener que convertirla primero en una cadena-c para ver cada carácter individual? ¿Hay una forma más eficiente de hash cadenas?



Otra forma de cuerdas pequeñas:

int hash(const char* str) { int hash = 0; int c = 0; while (c < std::strlen(str)) { hash += (int)str[c] << (int)str[c+1]; c++; } return hash; }


Para los personajes juntos, cuatro a la vez.


Por experiencia personal sé que esto funciona y produce buenas distribuciones. (Plagiado de here ):

djb2

este algoritmo (k = 33) fue reportado por primera vez por dan bernstein hace muchos años en comp.lang.c. otra versión de este algoritmo (ahora favorecida por bernstein) usa xor: hash (i) = hash (i - 1) * 33 ^ str [i]; la magia del número 33 (por qué funciona mejor que muchas otras constantes, prime o no) nunca se ha explicado adecuadamente.

unsigned long hash(unsigned char *str) { unsigned long hash = 5381; int c; while (c = *str++) { hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ } return hash; }


Puede examinar cada carácter individual desde una cadena estándar :: usando el operador [] . Sin embargo, puede consultar Boost::Functional/Hash para obtener orientación sobre un mejor esquema de hashing. También hay una lista de funciones de hashing en c here .


Puede utilizar el operator[] funciones miembro operator[] o at la clase de cadena o los iteradores para acceder al carácter individual de un objeto de cadena sin convertirlo en una matriz de caracteres de estilo c.

Para enlazar un objeto de cadena a un entero, tendrá que acceder a cada carácter individual del objeto de cadena que puede hacer como:

for (i=0; i < str.length(); i++) { // use str[i] or str.at(i) to access ith element. }


Re la primera pregunta, claro, por ejemplo, algo como:

int hash = 0; int offset = ''a'' - 1; for(string::const_iterator it=s.begin(); it!=s.end(); ++it) { hash = hash << 1 | (*it - offset); }

con respecto a la segunda, hay muchas mejores maneras de codificar cadenas. Por ejemplo, vea here algunos ejemplos de C (fácilmente traducibles a C ++ a lo largo de las líneas del fragmento de código anterior).


#include <iostream> #include <string> #include <algorithm> using namespace std; // a variation on dan bernstein''s algorithm // [http://www.cse.yorku.ca/~oz/hash.html] template<typename Int> struct hash { hash() : acc(5381) { } template<typename Ch> void operator()(Ch ch) { acc = ((acc << 5) + acc) ^ ch; } operator Int() const { return acc; } Int acc; }; int main(int argc, char* argv[]) { string s("Hellp, world"); cout << hex << showbase << for_each(s.begin(), s.end(), hash<unsigned long long>()) << ''/n''; return 0; }