¿Cuál es el significado de bucket = Math.abs (x.hashCode () * p)% tablesize en Java?

Esto intenta mejorar la aleatoriedad del valor tomado del hashCode (). El problema es que tiene un error sutil.

x.hashCode () * p

Esto toma un código hash pero lo multiplica por una constante, que con suerte es un número impar razonablemente grande.

El error esta aqui

Math.abs (x.hashCode () * p)

Incluso si x.hashCode () siempre es positivo cuando lo multiplica por p, puede desbordarse y ser negativo. ¿Pero Math.abs que hacen que esto no sea negativo? desafortunadamente no siempre. El problema es el número Integer.MIN_VALUE que no tiene un equivalente positivo, por lo que Math.abs (Integer.MIN_VALUE) == Integer.MIN_VALUE (es decir, se desborda a un número negativo en sí mismo)

La solución es tomar el módulo% primero y luego usar Math.abs

cubo = Math.abs (x.hashCode () * p% tablesize);

Este es un error particularmente grave porque puede ejecutar muchas pruebas, ejecutar durante mucho tiempo en producción y nunca encontrar este error. Tiene una probabilidad de 1 en 4 mil millones de encontrarlo por accidente.

Por cierto. La multiplicación es relativamente costosa y no es una gran función de agitación. Una mejor opción es una función como esta que HashMap solía usar antes de cambiar a árboles en lugar de listas para colisiones.

hash estático int (int h) {
// Esta función asegura que los códigos hash que difieren solo por
// los múltiplos constantes en cada posición de bit tienen un límite
// número de colisiones (aproximadamente 8 con el factor de carga predeterminado).
h ^ = (h >>> 20) ^ (h >>> 12);
devuelve h ^ (h >>> 7) ^ (h >>> 4);
}

Esta función garantiza que los bits más bajos sean más aleatorios.

En serio, no te preocupes por eso. No es importante en detalle.

El panorama general es que algunas estructuras de datos que están diseñadas para ser rápidas de leer, posiblemente más lentas para insertar, usan una estructura de ‘depósito’.

Es posible que tenga 1,000 elementos de datos. Una buena manera de manejar esto es dividirlo en 20 cubos de aproximadamente 50 artículos cada uno.

La función que ha visto decide “qué cubo”.

El elemento de datos se almacena en ese cubo con todos los demás.

La gran ventaja es que ahora ha reducido el espacio de búsqueda de todos los datos a un depósito. Menos trabajo.

Entonces, la fórmula es un poco de “magia” para elegir un balde. Devolverá un número entero entre cero y ‘tablesize-1’ inclusive. Las otras cosas han sido calculadas, o más probablemente, adivinadas , como una forma de ayudar a distribuir los datos de manera uniforme entre los cubos.

¿Yo? Solo lo acepto como magia. Escríbelo y sigue adelante.

Esta es una función para calcular el índice en el que cierto elemento debe almacenarse en una estructura de datos subyacente. En primer lugar, piense en un código hash de un elemento como solo un valor entero generado en función del valor del elemento al que se está llamando, generalmente calculado mediante una fórmula matemática. En Java, el código hash de una cadena, por ejemplo, se calcula de la siguiente manera:

Por ejemplo, imagine casos en los que los elementos que desea almacenar son pocos en número pero muy separados en términos de sus valores de hashcode distintos. En ese caso, no querría tener una matriz de almacenamiento cuya indexación se define por su valor de código hash, sino más bien por el número de entradas que hay o algún otro factor limitante (eficiencia de memoria).

Entonces, para tomar elementos y usar sus valores de código hash para colocarlos en la estructura de datos (matriz, por ejemplo), el código hash se divide por el tamaño de su matriz de respaldo (‘tamaño de tabla’) y luego el resto de esa división ( encontrado usando el operador%) se usa como el índice de la matriz en la que se coloca el elemento (x). Piense en ello como una forma de normalizar el valor del código hash contra el tamaño de la matriz para fines de indexación.

Puede echar un vistazo a las tablas de hash si desea obtener más información sobre el hash y su uso.

¿Qué es esta variable p? ¿Supongo que es algo constante difundir más los valores?

De todos modos, la lista de cubos hash es una matriz de un tamaño determinado. Un código hash es un número entero que puede ser negativo, por lo que debemos tomar su valor absoluto; y puede tener un valor mucho mayor que este tamaño. Entonces coercimos este valor a la dimensión de la matriz, a través del operador de módulo.

Debería poder averiguarlo usted mismo, Google las matemáticas. Función Abs y lo que hace el signo%. Es solo una operación matemática en general.

More Interesting

¿Cómo sé cuándo usar números de coma flotante de precisión simple o doble?

¿Por qué razón se prefieren los operadores de asignación compuesta aritmética al escribir códigos profesionalmente en Java?

¿Cómo se llega a una estructura de datos totalmente nueva?

¿Hay algún método para generar números factoriales grandes usando C ++?

¿Qué campos crees que están más relacionadas con Matemáticas e Informática o Matemáticas y Física?

¿De qué manera aprender matemáticas avanzadas me haría un mejor programador?

Puedo tomar la teoría de grafos o la combinatoria el próximo semestre. Me interesa la informática teórica. ¿Cuál sería mejor?

¿Cómo puede cuantificarse, sumarse y luego compararse métricamente la cantidad de verdad en una declaración compleja con su cantidad de falsedad?

¿Cuál es el orden de las operaciones para la notación sigma?

Hay una recta numérica con puntos enteros. Empiezas en 0. Puedes moverte (saltar) de dos maneras: 'a' avanza o 'b' retrocede a la vez. Si se da un entero de destino particular, x, (x> = 0), ¿cómo encontrar el número mínimo de saltos necesarios para llegar al destino?

¿Hay un sitio como el Proyecto Euler pero sobre matemáticas puras?

¿Debería sentirme desmoralizado porque el cálculo no parece hacer clic para mí?

¿Podría un genio aleatorio resolver el problema P vs NP o pasará a través de avances muy lentos en la ciencia por un grupo de personas que trabajan juntas?

Cómo encontrar un circuito de Euler en un gráfico en tiempo lineal

¿Qué es una variable de instancia?