Uma das coisas que sinto falta ao escrever programas em C é uma estrutura de dados do dicionário. Qual é a maneira mais conveniente de implementar uma em C? Não estou procurando desempenho, mas facilidade de codificá-lo do zero. Também não quero que seja genérico - algo como string-> int fará. Mas eu quero que ele seja capaz de armazenar um número arbitrário de itens.
Isto é pretendido mais como um exercício. Eu sei que existem bibliotecas de terceiros disponíveis que podem ser usadas. Mas considere por um momento que eles não existem. Em tal situação, qual é a maneira mais rápida de implementar um dicionário que atenda aos requisitos acima.
c
data-structures
dictionary
Rohit
fonte
fonte
Respostas:
A seção 6.6 da linguagem de programação C apresenta uma estrutura de dados simples de dicionário (hashtable). Eu não acho que uma implementação útil de dicionário possa ser mais simples que isso. Para sua conveniência, reproduzo o código aqui.
Observe que, se os hashes de duas seqüências colidirem, isso poderá levar a um
O(n)
tempo de pesquisa. Você pode reduzir a probabilidade de colisões aumentando o valor deHASHSIZE
. Para uma discussão completa da estrutura de dados, consulte o livro.fonte
hashval = *s + 31 * hashval;
exatamente 31 e nada mais?A maneira mais rápida seria usar uma implementação já existente, como uthash .
E, se você realmente deseja codificá-lo, os algoritmos de
uthash
podem ser examinados e reutilizados. É licenciado pelo BSD, portanto, além do requisito de transmitir o aviso de direitos autorais, você é bastante ilimitado no que pode fazer com ele.fonte
Para facilitar a implementação, é difícil superar ingenuamente a pesquisa através de uma matriz. Além de algumas verificações de erros, esta é uma implementação completa (não testada).
fonte
Crie uma função hash simples e algumas listas vinculadas de estruturas, dependendo do hash, atribua qual lista vinculada inserir o valor. Use o hash para recuperá-lo também.
Eu fiz uma implementação simples há algum tempo:
fonte
GLib e gnulib
Essas são as suas melhores apostas prováveis se você não tiver requisitos mais específicos, pois são amplamente disponíveis, portáteis e provavelmente eficientes.
GLib: https://developer.gnome.org/glib/ pelo projeto GNOME. Vários contêineres documentados em: https://developer.gnome.org/glib/stable/glib-data-types.html, incluindo "Hash Tables" e "Balanced Binary Trees". Licença: LGPL
gnulib: https://www.gnu.org/software/gnulib/ pelo projeto GNU. Você deve copiar e colar a fonte no seu código. Vários contêineres documentados em: https://www.gnu.org/software/gnulib/MODULES.html#ansic_ext_container, incluindo "rbtree-list", "linkedhash-list" e "rbtreehash-list". Licença GPL.
Consulte também: Existem bibliotecas C de código aberto com estruturas de dados comuns?
fonte
Aqui está uma implementação rápida, usei-a para obter uma 'Matrix' (sruct) de uma string. você pode ter uma matriz maior e alterar seus valores em execução também:
fonte
Estou surpreso que ninguém tenha mencionado o conjunto de bibliotecas hsearch / hcreate que, embora não esteja disponível no Windows, é mandatado pelo POSIX e, portanto, disponível nos sistemas Linux / GNU.
O link possui um exemplo básico simples e completo que explica muito bem seu uso.
Ele ainda possui uma variante segura de threads, é fácil de usar e tem um ótimo desempenho.
fonte
Uma hashtable é a implementação tradicional de um simples "Dicionário". Se você não se importa com velocidade ou tamanho, basta pesquisar no Google . Existem muitas implementações disponíveis gratuitamente.
aqui está o primeiro que eu vi - de relance, parece bom para mim. (é bastante básico. Se você realmente deseja que ele mantenha uma quantidade ilimitada de dados, precisará adicionar alguma lógica para "realocar" a memória da tabela à medida que ela cresce.)
boa sorte!
fonte
Hashing é a chave. Eu acho que usar tabela de pesquisa e chave de hash para isso. Você pode encontrar muitas funções de hash online.
fonte
O método mais rápido seria usar a árvore binária. Seu pior caso também é apenas O (logn).
fonte