Um guia para a técnica de dobragem em Java

Um guia para a técnica de dobragem em Java

1. Introdução

Neste tutorial, consideramos técnicas de hash usadas em várias estruturas de dados que fornecem acesso em tempo constante aos seus elementos.

Discutimos com mais detalhes os chamadosfolding techniquee damos uma breve introdução às técnicas de quadratura média e binning.

2. Visão geral

Quando escolhemos estruturas de dados para armazenar objetos, uma das considerações é se precisamos acessá-los rapidamente.

O pacote do utilitário Java oferece muitas estruturas de dados para armazenar nossos objetos. Para obter mais informações sobre estruturas de dados, consulte nossa página de compilaçãoJava Collections que contém guias sobre vários deles.

Como sabemos,some of these data structures allow us to retrieve their elements in constant time, independente do número de elementos que contêm.

Provavelmente, o mais simples é o array. De fato, acessamos elementos na matriz por seu índice. The access time, naturally, does not depend on the size of the array. Na verdade, nos bastidores, muitas estruturas de dados usam arrays intensamente.

O problema é que os índices da matriz devem ser numéricos, enquanto geralmente preferimos manipular essas estruturas de dados com objetos.

Para resolver esse problema, muitas estruturas de dados tentam atribuir um valor numérico que pode servir como um índice de matriz para objetos. We call this value a hash value or simply a hash.

3. Hashing

*Hashing is a transformation of an object into a numerical value. * As funções que realizam essas transformações são chamadas dehash functions.

Para fins de simplicidade, vamos considerar funções hash que transformam strings em índices de array, isto é, em inteiros do intervalo[0, N] com umN finito.

Naturalmente,a hash function is applied to a wide variety of strings. Portanto, suas propriedades "globais" se tornam importantes.

Mapping of strings into array indexesUnfortunately, it’s not possible that a hash function always transforms different strings into different numbers.

Podemos nos convencer facilmente de que o número de strings é muito maior do que o número de inteiros em qualquer intervalo[0, N]. Portanto, é inevitável que haja um par de strings não iguais para as quais uma função hash produz valores iguais. This phenomenon is called collision.

Não vamos mergulhar nos detalhes de engenharia por trás das funções hash, mas está claro que uma boa função hash deve tentar mapear uniformemente as strings nas quais é definida em números.

Outro requisito óbvio é que uma boa função de hash seja rápida. Se demorar muito para calcular um valor de hash, não podemos acessar os elementos rapidamente.

Neste tutorial, consideramos um dostechniques that try to make the mapping uniform enquanto o mantemos rápido.

4. Técnica de dobragem

Nosso objetivo é encontrar uma função que transforma cadeias de caracteres em índices de matriz. Apenas para ilustrar a ideia, suponha que queremos que este array tenha a capacidade para 105 elementos e vamos usar a stringJava language como exemplo.

4.1. Descrição

Vamos começar convertendo os caracteres da string em números. O ASCII é um bom candidato para esta operação:

Convert the string into ascii

Agora, organizamos os números que acabamos de obter em grupos de algum tamanho. Geralmente, escolhemos o valor do tamanho do grupo com base no tamanho do nosso array, que é 105. Como os números nos quais transformamos os caracteres contêm de dois a três dígitos, sem perda de generalidade, podemos definir o tamanho do grupo como dois:

Arrange string’s ascii codes

O próximo passo é concatenar os números em cada grupo como se fossem strings e encontrar sua soma:

Concatenate and sum up the numbers

Agora devemos dar o passo final. Vamos verificar se o número348933 pode servir como um índice de nossa matriz de tamanho 105. Naturalmente, excede o valor máximo permitido99999. Podemos facilmente superar esse problema aplicando o operador de módulo para encontrar o resultado final:

348933 % 10000 = 48933

4.2. Considerações finais

Vemos que o algoritmo não inclui nenhuma operação demorada e, portanto, é bastante rápido. Every character of the input string contributes to the final result. Este fato definitivamente ajuda a reduzir as colisões, mas não a evitá-las completamente.

Por exemplo, se quisermos pular a dobra e aplicar o operador módulo diretamente à sequência de entrada transformada em ASCII (ignorando o problema de estouro)

749711897321089711010311797103101 % 100000 = 3101

então, tal função hash produziria o mesmo valor para todas as strings que têm os mesmos dois últimos caracteres de nossa string de entrada: age, page, large,e assim por diante.

A partir da descrição do algoritmo, podemos ver facilmente que ele não está livre de colisões. Por exemplo, o algoritmo produz o mesmo valor hash paraJava languageevaJa language strings.

5. Outras técnicas

A técnica de dobragem é bastante comum, mas não a única. Às vezes, as técnicasbinning oumid-square também podem ser úteis.

Ilustramos a ideia deles não usando strings, mas números (suponha que já tenhamos transformado as strings em números). Não discutiremos suas vantagens e fraquezas, mas você pode formar uma opinião depois de ver os algoritmos.

5.1. Técnica de Binning

Suponha que tenhamos 100 números inteiros e que nossa função hash os mapeie em uma matriz de 10 elementos. Em seguida, podemos apenas organizar esses 100 números inteiros em dez grupos, de modo que os dez primeiros inteiros terminem no primeiro compartimento, os segundos dez inteiros terminem no segundo compartimento, etc .:

Binning technique

5.2. Técnica do Quadrado Médio

Esse algoritmo foi proposto por John von Neumann e permite gerar números pseudo-aleatórios a partir de um determinado número.

Mid-square hashing Vamos ilustrar com um exemplo concreto. Suponha que temos um número de quatro dígitos1111. De acordo com o algoritmo, elevamos ao quadrado, obtendo assim1234321‬. Agora, extraímos quatro dígitos do meio, por exemplo,2343. O algoritmo nos permite repetir esse processo até estarmos satisfeitos com o resultado.

6. Conclusão

Neste tutorial, consideramos várias técnicas de hash. Descrevemos em detalhes a técnica de dobragem e fornecemos uma descrição instantânea de como conseguir o binning e o quadrado médio.

Como sempre, podemos encontrar os trechos de código correspondentes em nossoGitHub repository.