J'ai un monde composé d'une série de rectangles avec différentes largeurs et hauteurs des décalages, mais identiques. J'ai aussi des points en mouvement, dont certains sont en mesure de frontières rectangle croix et d'autres ne sont pas. Compte tenu de ce fait, je stocke leurs positions coordonnées globales et non par rapport au rectangle (voir points rouges).
Je besoin d'un moyen rapide pour rechercher le rectangle un point est donné dans les coordonnées de leur X. Pour l'image ci-dessus, les deux points rouges retourneront les rectangles noirs et jaunes, respectivement. La I solution d'origine avait des boucles sous un très grand nombre de rectangles:
Rect getRectFor(float x) {
float totalSum = 0.0f;
// For each rect (in order)
for (Rect rect : rects) {
// Add the rect's width
totalSum += rect.getWidth();
// If the end of the rect is beyond us, return
if (totalSum >= x) {
return rect;
}
}
// We are beyond the end of all rects
return null;
}
Y a-t-il des structures de méthodes ou de données qui réussissent mieux dans ce scénario et me permettent de réaliser des milliers par seconde de recherches?
Le moyen le plus rapide que je peux penser est de créer un tableau:
E[0] = 0
E[i] = x-coordinate indicating where the i-th ends.
Dans votre exemple, il serait E = {0, 100, 150, 225, 350, 375, ...}
.
Pour trouver la position d'un point, vous pouvez simplement effectuer une recherche binaire dans ce tableau, vous donnant O (lg (n)) par requête.
Juste pour aider, a ajouté un petit morceau de code:
int bs(int[] m, int l, int r, int dot){
int i = (l + r) / 2;
if(m[i - 1] < dot && dot < m[i]) return i;
if(m[i - 1] == dot) return max(1, i - 1);
if(m[i] == dot) return i;
if(dot < m[i]) return bs(m, l, i, dot);
else return bs(m, i + 1, r, dot);
}
Les arguments bs
sont les suivants :
m
: Votre tableau.l
: Vous devriez toujours utiliser 1.r
: Vous devriez toujours utilisern - 1
, oùn
est la longueurm
.dot
: Les coordonnées x de votre point.
Exemple: si vous voulez trouver la position de votre deuxième point (en position x = 230), vous devez appeler
bs(E, 1, E.length - 1, 230)
et il retournerait 4.
Si vous essayez d'exécuter cette méthode avec une coordonnée x qui est outsite les limites du tableau (par exemple, les dernières extrémités du rectangle dans la position x = 100 et vous recherchez un point dans x = 101), des choses étranges peuvent se produire.