私はC++のRobertSedwickAlgorithmsの本を読んでいます。以下は、複合データ構造に関する本に記載されている例です。
問題の説明:「d」が与えられた場合、単位正方形内のN点のセットから、「d」より短い長さの直線で接続できるペアの数を知りたいと思います。
ロジックを使用する次のプログラムは、ユニットの正方形をグリッドに分割し、リンクされたリストの2次元配列を維持し、1つのリストが各グリッドの正方形に対応します。グリッドは、距離「d」内のすべてのポイントが同じグリッドの正方形または隣接する正方形のいずれかにあるように十分に細かく選択されます。
私の質問は
- なぜ作者はmalloc2d(G + 2、G + 2)にG + 2を割り当てているのですか?
- gridinsert関数で、作成者が次のステートメントを実行している理由int X = x * G + 1; int Y = y * G + 1; ?
- forループでは、なぜiをX-1に初期化し、jをY-1に初期化するのですか?
- コードのどこで、同じグリッドの正方形または隣接するグリッドの正方形の距離d内のポイントを維持していますか?
次のプログラムを理解するための簡単な例で助けを求めてください。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
using namespace std;
float randFloat() {
return 1.0*rand()/RAND_MAX;
}
struct myPoint {
float x;
float y;
};
float myDistance(myPoint a, myPoint b) {
float dx = a.x - b.x, dy = a.y - b.y;
return sqrt(dx*dx + dy*dy);
}
struct node {
myPoint p; node *next;
node(myPoint pt, node* t) {
p = pt; next = t;
}
};
typedef node *link;
static link **grid = NULL;
link **malloc2d(int r, int c) {
link **t = new link*[r];
for (int i = 0; i < r; i++) {
t[i] = new link[c];
}
return t;
}
static int G, cnt = 0;
static float d;
void gridinsert(float x, float y) {
int X = x*G+1;
int Y = y*G+1;
myPoint p;
p.x = x; p.y = y;
link s, t = new node(p, grid[X][Y]);
for (int i = X-1; i <= X+1; i++)
for (int j = Y-1; j <= Y+1; j++)
for (s = grid[i][j]; s != 0; s = s->next)
if (myDistance(s->p, t->p) < d) cnt++;
grid[X][Y] = t;
}
int main(int argc, char *argv[]) {
int i;
int N = 10;
d = 0.25;
G = 1/d;
grid = malloc2d(G+2, G+2);
for (i = 0; i < G+2; i++)
for (int j = 0; j < G+2; j++)
grid[i][j] = 0;
for (i = 0; i < N; i++)
gridinsert(randFloat(), randFloat());
cout << cnt << " pairs within " << d << endl;
return 0;
}