Java 编程逻辑:如何检查网格中的邻居?

Java 编程逻辑:如何检查网格中的邻居?,java,grid,Java,Grid,在一个基于网格的类编程项目中,我很难想出一种逻辑方法来检查邻居 我遇到的主要问题是想办法有效地检查它是否在边上,这样我就不会得到一个索引越界错误 编辑: 我忘了提到我使用的是二维数组。什么是二维数组?也许有些对象的状态是“已占用”和“空”之类的?在这种情况下,引入一种新的状态,如“边缘”和“角”,并在每个方向上创建一个较大的二维阵列单元。然后,您的邻居检查器可以只使用简单的+/-逻辑,然后对邻居集的处理可以选择忽略任何边。以下是获取邻居位置的简单方法,避免担心边: int leftX = (x

在一个基于网格的类编程项目中,我很难想出一种逻辑方法来检查邻居

我遇到的主要问题是想办法有效地检查它是否在边上,这样我就不会得到一个索引越界错误

编辑:
我忘了提到我使用的是二维数组。

什么是二维数组?也许有些对象的状态是“已占用”和“空”之类的?在这种情况下,引入一种新的状态,如“边缘”和“角”,并在每个方向上创建一个较大的二维阵列单元。然后,您的邻居检查器可以只使用简单的+/-逻辑,然后对邻居集的处理可以选择忽略任何边。

以下是获取邻居位置的简单方法,避免担心边:

int leftX = (x - 1 + width) % width;
int rightX = (x + 1) % width;
int aboveY = (y - 1 + height) % height;
int belowY = (y + 1) % height;
这可能不是最有效的方法,但它将每个计算保持为一个简单的表达式。当然,这是假设你想绕过去。如果你不这样做,你将不得不有条件地做事情:

if (x > 0)
{
    // Use x - 1
}
if (x < width - 1)
{
    // Use x + 1
}
if(x>0)
{
//使用x-1
}
如果(x<宽度-1)
{
//使用x+1
}

如前所述,[x,y]的左邻居是[x,y-1],右邻居是[x,y+1],依此类推。但是,您还应该检查y>=1,否则您将越界。类似地,y必须小于数组的大小。您可以使用if语句或(不推荐)处理ArrayIndexOutOfBoundsException。

基本上,您希望访问单元格的邻居,同时确保您未脱离网格。您可以尝试一种简单的算法:

假设中心单元格(您所在的位置)是
(x,y)
,并且您还希望检查对角线。
你的网格是[0,W[在X上,[0,H[在Y上(基本上
wxh
),从(0,0)开始)

经常有(如果不是总是的话)在速度和内存方面的牺牲;不久前我不得不用Java实现一个数独解算器,为每个单元格分配一个单元格组列表会更快。因此,我不必每次都检查边界,只需遍历每个组,然后遍历每个组中的每个单元格。只需进行一次检查即可创建组

比如:

class Neighbors {
   ArrayList<Point> pList = new ArrayList<Point>();
}
嗯,我的解决方案有点复杂,但原理是一样的。如果网格是一个二维对象数组,那么邻居实际上可以是
grid[nx][ny]
上的对象,而不是直接访问对象的点


您最终需要检查
x>=0
y>=0
x如何分解您需要的位?类似于
isOccupied(x,y)
方法,该方法为超出边界的值返回false:

  public boolean isOccupied(int x, int y) {
    if (!inXRange(x) || !inYRange(y))
      return false;
    return occupied[y][x]; // or [x][y] depending on row/col major preferences
  }
那么count Neights方法将非常简单:

  public int countNeighbours(int x, int y) {
    int neighbours = 0;
    for (int dx = -1; dx <= 1; ++dx) {
      for (int dy = -1; dy <= 1; ++dy) {
        if (((dx != 0) || (dy != 0)) && isOccupied(x + dx, y + dy))
          neighbours += 1;
      }
    }
    return neighbours;
  }
公共整数(整数x,整数y){
int=0;

对于(intdx=-1;dx来说太晚了,但是提供的答案要么太复杂,要么不完整,所以我将尝试回答它

基本上,你要做的是找到从
x
y
的偏差,范围从-1到1。因此,最大邻居数是3^2-1(节点本身)

现在,如果网格有边界,只需检查新的
x
y
是否仍在边界内

常数x=6;
常数y=1;
常数W=7;
常数H=7;
常量邻居=[];
对于(a=-1;a<2;a++){
对于(b=-1;b<2;b++){
如果(!(a==0&&b==0)){
常数nX=x+a;
常数nY=y+b;
如果((nX>=0&&nX=0&&nYconsole.log(邻居)
您使用的是什么数据结构?哦,是的,我的错,在许多算法中使用的二维arrayA技术是使数组1的宽度和高度更大,从而避免索引越界和大量if语句。当然,第一行和第一列中的值不需要影响算法的有效性,因此您是否可以使用它取决于具体情况。FWIW@lassespeholt,我认为你的评论比任何答案都要好得多。避免像感谢或+1…+1++感谢这样的评论!顺便说一句,假设你想要一个特定已知位置没有对角线的网格邻居:
for(int I=-1;I<2;++I){int dX=x+i,dY=y+i;//水平方向:栅格[dX][y];//垂直方向:如果(i!=0)栅格[x][dY]
int[][] grid = new int[10][10];
Neighbors[][] n = new Neighbors[10][10];

for (int x=0; x<10; x++) {
   for (int y=0; y<10; y++) {
      grid[x][y] = (y*10)+x;  // 0..99
      n[x][y] = new Neighbors();
      for (int nx=x-1; nx<=x+1; nx++) {
         for (int ny=y-1; ny<=y+1; ny++) {
            if (!(x==nx && y==ny) && nx>=0 && ny>=0 && nx<10 && ny<10) {
               n[x][y].pList.add(new Point(nx,ny)); // add valid neighbor
            }
         }
      }
   }
}
for (Point p : n[x][y].pList) {
   // grid[p.x][p.y]  is a neighbor of grid[x][y]
}
int pad_size = 1;  // how many neighbors around x,y
int size_w = 10+(pad_size*2);
int size_h = 10+(pad_size*2);
int[][] grid = new int[size_w][size_h];

for (int x=0; x<size_w; x++) {
  for (int y=0; y<size_h; y++) {
     if (x<pad_size || x>=size_w-pad_size || y<pad_size || y>=size_h-pad_size) {
        grid[x][y] = -1;  // ignore
     } else {
        grid[x][y] = ((y-pad_size)*10)+(x-pad-size);  // 0..99
     }
  }
}
for (int nx=x-pad_size; nx<=x+pad_size; nx++) {
  for (int ny=y-pad_size; ny<=y+pad_size; ny++) {
     if (-1!=grid[nx][ny] && !(nx==x && ny==y)) {
        // grid[p.x][p.y]  is a neighbor of grid[x][y]
     }
  }
}
  public boolean isOccupied(int x, int y) {
    if (!inXRange(x) || !inYRange(y))
      return false;
    return occupied[y][x]; // or [x][y] depending on row/col major preferences
  }
  public int countNeighbours(int x, int y) {
    int neighbours = 0;
    for (int dx = -1; dx <= 1; ++dx) {
      for (int dy = -1; dy <= 1; ++dy) {
        if (((dx != 0) || (dy != 0)) && isOccupied(x + dx, y + dy))
          neighbours += 1;
      }
    }
    return neighbours;
  }