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&&nY console.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;
}