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?
C ++ 11 se entrega con una función hash estándar para cadenas.
https://en.cppreference.com/w/cpp/string/basic_string/hash
#include <string>
#include<functional> // hash
int main(){
std::string s = "Hello";
std::size_t hash = std::hash<std::string>{}(s);
}
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;
}