Una de las cosas que echo de menos al escribir programas en C es una estructura de datos del diccionario. ¿Cuál es la forma más conveniente de implementar uno en C? No busco rendimiento, sino facilidad para codificarlo desde cero. Tampoco quiero que sea genérico, algo como string-> int servirá. Pero sí quiero que pueda almacenar una cantidad arbitraria de artículos.
Esto se pretende más como un ejercicio. Sé que hay bibliotecas de terceros disponibles que se pueden usar. Pero considere por un momento, que no existen. En tal situación, ¿cuál es la forma más rápida de implementar un diccionario que satisfaga los requisitos anteriores?
c
data-structures
dictionary
Rohit
fuente
fuente
Respuestas:
La sección 6.6 del lenguaje de programación C presenta una estructura de datos de diccionario simple (tabla hash). No creo que una implementación útil del diccionario pueda ser más simple que esto. Para su comodidad, reproduzco el código aquí.
Tenga en cuenta que si los hashes de dos cadenas chocan, puede provocar un
O(n)
tiempo de búsqueda. Puede reducir la probabilidad de colisiones aumentando el valor deHASHSIZE
. Para una discusión completa de la estructura de datos, consulte el libro.fuente
hashval = *s + 31 * hashval;
exactamente 31 y no otra cosa?La forma más rápida sería utilizar una implementación ya existente, como uthash .
Y, si realmente desea codificarlo usted mismo, los algoritmos de
uthash
pueden ser examinados y reutilizados. Tiene licencia BSD, por lo que, aparte del requisito de transmitir el aviso de derechos de autor, tiene bastante ilimitado en lo que puede hacer con él.fuente
Para facilitar la implementación, es difícil superar la búsqueda ingenua a través de una matriz. Además de alguna comprobación de errores, esta es una implementación completa (no probada).
fuente
Cree una función hash simple y algunas listas de estructuras vinculadas, dependiendo del hash, asigne en qué lista vinculada insertar el valor. Use el hash para recuperarlo también.
Hice una implementación simple hace algún tiempo:
fuente
GLib y gnulib
Estas son sus mejores apuestas si no tiene requisitos más específicos, ya que están ampliamente disponibles, son portátiles y probablemente eficientes.
GLib: https://developer.gnome.org/glib/ por el proyecto GNOME. Varios contenedores documentados en: https://developer.gnome.org/glib/stable/glib-data-types.html, incluyendo "Tablas hash" y "Árboles binarios equilibrados". Licencia: LGPL
gnulib: https://www.gnu.org/software/gnulib/ por el proyecto GNU. Debes copiar, pegar la fuente en tu código. Varios contenedores documentados en: https://www.gnu.org/software/gnulib/MODULES.html#ansic_ext_container, incluidos "rbtree-list", "Linkedhash-list" y "rbtreehash-list". Licencia GPL.
Ver también: ¿Hay alguna biblioteca C de código abierto con estructuras de datos comunes?
fuente
Aquí hay un implemento rápido, lo usé para obtener una 'Matriz' (sruct) de una cadena. puede tener una matriz más grande y cambiar sus valores en la ejecución también:
fuente
Me sorprende que nadie haya mencionado el conjunto de bibliotecas hsearch / hcreate que, aunque no está disponible en Windows, es un mandato de POSIX y, por lo tanto, está disponible en sistemas Linux / GNU.
El enlace tiene un ejemplo básico simple y completo que explica muy bien su uso.
Incluso tiene una variante segura para hilos, es fácil de usar y muy eficiente.
fuente
Una tabla hash es la implementación tradicional de un simple "Diccionario". Si no te importa la velocidad o el tamaño, solo búscalo en google . Hay muchas implementaciones disponibles gratuitamente.
Aquí está el primero que vi : de un vistazo, me parece bien. (es bastante básico. Si realmente desea que contenga una cantidad ilimitada de datos, deberá agregar algo de lógica para "reasignar" la memoria de la tabla a medida que crece).
¡buena suerte!
fuente
Hashing es la clave. Creo que use la tabla de búsqueda y la clave hash para esto. Puede encontrar muchas funciones de hashing en línea.
fuente
El método más rápido sería usar un árbol binario. Su peor caso también es solo O (logn).
fuente