2010-08-18 11 views
2

J'ai un tableau d'éléments de plage. Chaque élément a un début et une fin. Dans le tableau, les plages ne se chevauchent pas et sont triées.Hacher une plage

ie (code juste pour illustrer, ne vous attendez pas à compiler):

var arr = { [0,3], [5,10], [15,59] }; 

Compte tenu d'une valeur (par exemple 9), est-il une fonction de hachage des gammes qui me permettra d'obtenir rapidement la élément qui a la plage qui contient la valeur?

Bien sûr, il y a la solution naïve, il suffit de faire défiler chaque élément jusqu'à ce que vous trouviez le bon; le plus élaboré, comme la recherche binaire par le début de la gamme; et le breveté de créer un arbre binaire avec les gammes. Mais est-ce que quelqu'un connaît un moyen d'utiliser un hachage?

+0

BTW. Je dois être une fonction, les tables de hachage ne comptent pas. – JorgeLeo

Répondre

0

Vous pouvez créer un index pour les valeurs de départ à indexer en arr.

var arr = { [0,3], [5,10], [15,59] }; 

var dictStart = new Dictionary<int, int>(); 
dictStart.Add(0, 0); 
dictStart.Add(5, 1); 
dictStart.Add(15, 2); 

Maintenant, pour obtenir la gamme que vous pouvez faire une recherche binaire sur les valeurs de la dict dictStart pour le premier élément qui est plus élevé que la valeur à rechercher. Ensuite, prenez l'entrée précédente.

Difficile à expliquer. A titre d'exemple, recherchez 9. Faites la recherche de ce qui a eu l'élément e = [5, 1].

var range = arr[e[1]]; // = [5, 10] 
bool isWithin = val <= range[1] && val >= range[0]; 

Ainsi, la mémoire sera moins invasive. La clé est d'avoir une recherche rapide pour les valeurs de départ des plages. Je suppose que cela va résoudre le problème, mais ce n'est pas un hachage.

+0

Pas exactement ce que je cherchais, mais ça m'a donné une idée. Normaliser la fin des plages, puis utiliser les 4 derniers bits de chaque plage de début normalisée pour calculer le compartiment. Le hachage peut prendre la forme de int [] [], où le premier tableau est le bucket, et le jagged est la liste des plages qui appartiennent à ce bucket. Merci beaucoup – JorgeLeo

2

Vous pouvez calculer à l'avance le quartier le plus proche et le stocker quelque part. Dans votre exemple, la table contient 0..59 entrées et vous stockez l'index de la plage la plus proche à chaque index.

De cette façon, ce sera vraiment rapide.

+0

J'aime cette solution. Votre valeur de recherche devient alors simplement l'index dans votre table et la table retourne l'index de arr []. 2 recherches et vous avez terminé. Cela nécessitera beaucoup de mémoire rapidement, mais cela résout bien le problème. –

+0

Notez que dans l'exemple il y a des trous entre les plages, il n'y a pas de 0 à 59 entrées. Vrai que les trous peuvent être remplacés par des zéros, mais il bat la capacité de le faire dans les gammes, la fusée du ciel de la consommation de la mémoire. les plages que je vois sont entre 0 et 2+ millions, avec beaucoup de trous entre les deux, et j'ai besoin de garder 60k ou plus de ces ensembles en mémoire (d'où les gammes) C'est pourquoi je suis à la recherche d'un solution de hachage. Hachez la gamme de manière à pouvoir répondre à la question: cette position est-elle dans une fourchette (et laquelle), ou tombe-t-elle dans un trou? – JorgeLeo

+0

Cela n'utilise pas de hachage (même si je doute qu'un hachage soit une bonne solution ici). – Frank

1

Que diriez-vous d'utiliser un Dictionary<int, Element> pour contenir tous les nombres dans toutes les plages, i. e. ajouter les quatre entrées

0, [0,3] 
1, [0,3] 
2, [0,3] 
3, [0,3] 

et ainsi de suite pour les autres plages. Il utilise un hachage en utilisant le dictionnaire, mais je doute que ce soit la solution la plus efficace.

+0

Cela va à l'encontre du but de traiter des plages de valeurs, au lieu de valeurs individuelles.Il va résoudre le problème, mais il va créer un plus gros en termes de mémoire – JorgeLeo

+0

Comme je l'ai dit plus haut, il utilise le hachage au besoin, mais ce n'est pas très efficace. – Frank

+0

Un hachage est une fonction à sens unique qui prend une partie si information et renvoie une valeur. Ce que vous avez là est une table de recherche, ou une table de hachage si vous devez; à cause des contraintes de mémoire, j'ai besoin d'une fonction. Je vous remercie de toute façon. – JorgeLeo