Étant donné une série de largeurs variables et un point, pour la largeur contenant le point

Yorek B:

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).

mise en page du monde

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?

Daniel:

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 bssont les suivants :

  • m: Votre tableau.
  • l: Vous devriez toujours utiliser 1.
  • r: Vous devriez toujours utiliser n - 1, où nest la longueur m.
  • 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.

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=373151&siteId=1
conseillé
Classement