我一直在想是否有更聪明的解决方案,如果我想检查C中二进制数仅二维数组中任意元素的所有八个邻居
我的工作是:
Psudo代码:
//return how many neighbor of an element at x,y equals 1.
int neighbor(int** array, int x, int y)
if x>WIDTH
error
if y>HIEGHT
error
if x==0
ignore west, nw, sw, and calculate the rest.....
etc..
这是相当沉闷的,有没有更聪明的解决方案?
答案 0 :(得分:1)
一种可能的优化方法是,如果您想知道单元格的邻居数量远远超过您想要更改单元格的数量,那么就是预处理每个单元格的邻居数量并将结果保存在另一个数组中。
int** actualArray;
// fill in with 0s and 1s
int** numberOfNeighbors;
// write a function to calculate the number of neighbors for cell x,y in actualArray and
// store the result in numberOfNeighbors[x][y]
preprocess(actualArray, numberOfNeighbors); // call this whenever actualArray changes
// now you can get the number of neighbors of a cell in constant time
// from numberOfNeighbors[x][y]
答案 1 :(得分:1)
我使用了类似的方法来获取Adjacent Mines
中特定单元格的Minesweeper Game
。我做了什么,是我使用了这样的数组(MAX_NUMBER_OF_CELLS = 8):
int offset[MAX_NUMBER_OF_CELLS][2] = {
{-1, -1},
{-1, 0},
{-1, 1},
{0, -1},
{0, 1},
{1, -1},
{1, 0},
{1, 1}
};
考虑到我们正在讨论矩阵中的CELL
location 0, 0
。我们将简单地将这些偏移值添加到CELL
以检查相邻CELL是否是有效CELL(即它落在矩阵内)。如果有效,那么我们会看到它是否包含1
,如果是,则sum
增加1
,否则不会。
//rest of the values represent x and y that we are calculating
(-1, -1) (-1, 0) (-1, 1)
-------------------------
(0, -1) |(0, 0(This is i and j))| (0, 1)
-------------------------
(1, -1) (1, 0) (1, 1)
sum = 0;
for (k = 0; k < MAX_NUMBER_OF_CELLS; k++)
{
indexX = i + offset[k][0];
indexY = j + offset[k][1];
if (isValidCell(indexX, indexY, model)) // Here check if new CELL is VALID
// whether indexX >= 0 && indexX < rows
// and indexY >= 0 && indexY < columns
{
flag = 1;
if (arr[indexX][indexY] == 1))
sum += 1;
}
}
这是一个有效的例子(C不是我的语言,但我仍然试着给你一个想法:-)):
#include <stdio.h>
#include <stdlib.h>
int findAdjacent(int [4][4], int, int, int, int);
int main(void)
{
int arr[4][4] = {
{0, 1, 0, 0},
{1, 0, 1, 1},
{0, 1, 0, 0},
{0, 0, 0, 0}
};
int i = 2, j = 2;
int sum = findAdjacent(arr, i, j, 4, 4);
printf("Adjacent cells from (%d, %d) with value 1 : %d\n", i, j, sum);
return EXIT_SUCCESS;
}
int findAdjacent(int arr[4][4], int i, int j, int rows, int columns)
{
int sum = 0, k = 0;
int x = -1, y = -1; // Location of the new CELL, which
// we will find after adding offsets
// to the present value of i and j
int offset[8][2] = {
{-1, -1},
{-1, 0},
{-1, 1},
{0, -1},
{0, 1},
{1, -1},
{1, 0},
{1, 1}
};
for (k = 0; k < 8; k++)
{
x = i + offset[k][0];
y = j + offset[k][1];
if (isValidCell(x, y, rows, columns))
{
if (arr[x][y] == 1)
sum += 1;
}
}
return sum;
}
int isValidCell(int x, int y, int rows, int columns)
{
if ((x >= 0 && x < rows) && (y >= 0 && y < columns))
return 1;
return 0;
}
答案 2 :(得分:1)
您是否尝试在阵列中找到元素的当前位置?如果是这样,您可以定义一个宏,如:
#define OFFSET(x,y) ((GridWidth*y)+x)
或者,如果你试图找到哪些周围的“盒子”可以包含一个元素(即哪些邻居是'在边界')......
for k = 0 while k < GridWidth
for m = 0 while m < GridWidth
if k < GridWidth
toRight = true
if m < GridWidth
toDown = true
if k > 1
toLeft = true
if m > 1
toUp = true
从那里,结合方向以获得对角线 - if toRight && toUp, then toUpRight=true
等