さまざまな幅のシリーズとの点を考えると、ポイントを含む幅を見つけます

Yorek B:

私は幅とオフセットが、同じ高さを変化させた一連の矩形からなる世界を持っています。私はまた、矩形の境界を横断することができますし、他の人ではないそのうちのいくつかのポイントを、移動しています。この事実を考えると、私は(赤い点を参照)長方形に対するグローバル座標としてではなく、自分の位置を格納しています。

世界のレイアウト

私は、ポイントはそのX座標が与えられた範囲内にある四角形を検索するための高速な方法が必要です。上記画像のために、2つの赤色のドットは、それぞれブラックとイエロー矩形を返します。オリジナルのソリューションは、私は長方形の非常に多くの下にバックルを持っていました:

    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;
    }

このシナリオでは、パフォーマンスが向上すると私は、毎秒検索数千人を行うことを可能にする任意のメソッドまたはデータ構造はありますか?

ダニエル:

私は考えることができる最速の方法は、配列を作成することです:

E[0] = 0
E[i] = x-coordinate indicating where the i-th ends.

あなたの例では、それは次のようになりますE = {0, 100, 150, 225, 350, 375, ...}

任意のドットの位置を見つけるには、あなただけのあなたのクエリあたりO(LG(N))時間を与え、この配列内のバイナリ検索を行うことができます。


ただ、助けに、コードの小さな作品を追加しました:

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);        
}

引数はbs、次のとおりです。

  • m:あなたの配列。
  • l:あなたは常に1を使用する必要があります。
  • r:あなたは、常に使用すべきn - 1ところ、nの長さですm
  • dot:あなたの点のx座標。

例:あなたは(位置X = 230で)2番目のドットの位置を検索したい場合は、あなたが呼び出す必要があります

bs(E, 1, E.length - 1, 230)

それは4を返します。

あなたがこの方法を実行しようとすると、奇妙なことが起こるかもしれないが配列の境界をoutsiteあるx座標(例えば、位置X = 100の最後の長方形の両端であり、あなたは、x = 101のドットを検索してください)。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=373150&siteId=1