[英]find neighbours in 2d array by position of elements
我需要通過元素的位置在二維數組中找到鄰居
可用數據:
網格的大小。 例如 - 3*3 將返回 3,4*4 將返回 4
網格中填充單元格的數量。 例如 - 4
獲取填充單元格的 x 坐標- 例如 0 或 1 或 2 等
獲取填充單元格的 y 坐標- 例如 0 或 1 或 2 等
例如
int[][] room = {
{0, 0, X},
{0, X, 0},
{X, 0, 0}
};
這里,網格的大小 = 3
網格中填充單元格的數量 = 3(因為有三個“X”,它在其他單元格上的值無關緊要)
獲取填充單元格的 x 坐標 - 第一個元素為 0,第二個元素為 1,第三個元素為 2
獲取填充單元格的 y 坐標 - 第一個元素為 2,第二個元素為 1,第三個元素為 0
所以,坐標變成 (0,2),(1,1),(2,0)
我需要用至少一個相鄰的“X”來計算“X”的數量。 如果“X”在基本方向上彼此相鄰,但不是對角線,則它們被認為是鄰居。 所以上面的情況將返回0。
int[][] room = {
{X, X, 0},
{0, 0, 0},
{0, 0, 0}
};
這應該返回 2。
我使用的語言是 Java。
我嘗試迭代填充元素的數量並使用如下所示的鄰居邏輯,但在某些或其他情況下它會中斷你上面的鄰居 = (x, y-1),
你下面的鄰居 = (x, y+1),
你左邊的鄰居 = (x-1, y),
你右邊的鄰居 = (x+1, y)
for (int x = 0; x < nums; x++) {
int xcord = xmap.get(x); //return x cord
int ycord = ymap.get(x); //return y cord
int xcordLeft = x - 1 >= 0 ? xmap.get(x - 1) : 0;
int ycordLeft = x - 1 >= 0 ? ymap.get(x - 1) : 0;
int xcordRight = x + 1 < size ? xmap.getOrDefault(x + 1, 0) : 0;
int ycordRight = x + 1 < size ? ymap.getOrDefault(x + 1, 0) : 0;
int xcordTop = xcord - 1 >= 0 ? xmap.get(xcord - 1) : 0;
int ycordTop = ymap.get(ycord);
int ycordBottom = ymap.get(ycord);*/
//left
if (xcord >= 0 && x - 1 >= 0 && xcord == xcordLeft && ycord - 1 == ycordLeft) {
neighbours++;
}
//right
if (xcord >= 0 && x + 1 < size && xcord == xcordRight && ycord + 1 == ycordRight) {
neighbours++;
}
//top
if (xcord >= 0 && xcord - 1 >= 0 && xcord - 1 == xcordTop && ycord == ycordTop) {
neighbours++;
}
//bottom
}
您正在使用指定 X 位置的坐標列表。
當曼哈頓距離為 1 時,兩個單元格p ( x p , y p ) 是q ( x q , y q ) 相鄰的:
| x p − x q | + | y p − y q | = 1
與其嘗試查找頂部、底部、左側和右側鄰居的坐標並在列表中查找它們,不如遍歷列表並計算鄰居:
for (int i = 0; i < nums; i++) {
int x = xmap.get(i);
int y = ymap.get(i);
int neighbors = 0;
for (int j = 0; j < nums; j++) {
int xx = xmap.get(j);
int yy = ymap.get(j);
if ((abs(x - xx) + abs(y - yy) == 1) {
neighbors++;
}
}
if (neighbors) // do stuff
}
一個單元格到它自己的曼哈頓距離是 0,所以它不算作鄰居。 該代碼對於大而密集的網格不是很有效,但是如果您的 X 很少,那么嵌套的 lops 應該沒問題。
讓它簡單明了。
通過檢查所有四個相鄰坐標來計算鄰居,並有一些條件來檢查相鄰坐標是否在邊界內:
bool inBounds(int x, int y){
return 0 <= x and x < size and 0 <= y and y < size;
}
int countNeighbours(int x, int y) {
int count = 0;
for(int i=-1; i<=1; i+=2){
if(inBounds(x+i, y))
if(data[x+i][y] == X){
count++;
}
}
if(inBounds(x, y+i))
if(data[x][y+i] == X){
count++;
}
}
}
return count;
}
int countGroupedEntries(){
int count = 0;
for(int x=0; x<size; x++){
for(int y=0; y<size; y++){
if(data[x][y] == X){
if(countNeighbours(x,y) != 0){
count++;
}
}
}
}
return count;
}
我的意思是,這里的某些算法可能更聰明,但是如果您沒有一些效率瓶頸,請使算法盡可能簡單,使其具有可讀性(並不是說該算法特別糟糕,僅適用於 Θ(size²)很好,唯一需要考慮的是線性因素)。
執行inBounds
檢查而不是確保您在特殊情況下保持在邊界內可以防止countNeighbours
方法過度擁擠。
如果您想計算鄰居關系的數量,您可以:
private int countNeighborRelations(int[][] array, int yourX) {
int neighborRelationCount = 0;
for (int y = 0; y < array.length; y++) {
for (int x = 0; x < array[y].length - 1; x++) {
if (array[y][x] == yourX && array[y][x + 1] == yourX) {
neighborRelationCount += 2;
}
}
}
for (int y = 0; y < array.length - 1; y++) {
for (int x = 0; x < array[y].length; x++) {
if (array[y][x] == yourX && array[y + 1][x] == yourX) {
neighborRelationCount += 2;
}
}
}
return neighborRelationCount;
}
如果您想計算您的 X 中有多少具有 neigbourHoodRelations(換句話說,所有 X 至少有一個鄰居),您可以使用以下代碼:
private int countNeighbors(int[][] array, int yourX) {
int[][] neighborRelationCount = new int[array.length][array[0].length];
for (int y = 0; y < array.length; y++) {
for (int x = 0; x < array[y].length - 1; x++) {
if (array[y][x] == yourX && array[y][x + 1] == yourX) {
neighborRelationCount[y][x]++;
neighborRelationCount[y][x + 1]++;
}
}
}
for (int y = 0; y < array.length - 1; y++) {
for (int x = 0; x < array[y].length; x++) {
if (array[y][x] == yourX && array[y + 1][x] == yourX) {
neighborRelationCount[y][x]++;
neighborRelationCount[y + 1][x]++;
}
}
}
int neighbourCount=0;
for (int y = 0; y < neighborRelationCount.length; y++) {
for (int x = 0; x < neighborRelationCount[y].length; x++) {
if (0<neighborRelationCount[y][x]) {
neighbourCount++;
}
}
}
return neighbourCount;
}
當然,如果您確實使用其他數據格式,則有更簡單的解決方案,但使用原始 int[][] 我認為這是最簡單的方法。
以下是我測試功能的方法:
@Test
public void testRelations() {
// TODO Auto-generated method stub
int[][] room0_0 = { { 1, 0, 1 }, { 0, 1, 0 }, { 1, 0, 1 } };
int[][] room2_2 = { { 1, 1, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
int[][] room4_3 = { { 1, 1, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };
int[][] room4_4 = { { 1, 1, 0 }, { 0, 0, 0 }, { 0, 1, 1 } };
int[][] room8_5 = { { 1, 1, 0 }, { 0, 1, 0 }, { 0, 1, 1 } };
int[][] room24_9 = { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
assertTrue(countNeighborRelations(room0_0, 1)==0);
assertTrue(countNeighborRelations(room2_2, 1)==2);
assertTrue(countNeighborRelations(room4_3, 1)==4);
assertTrue(countNeighborRelations(room4_4, 1)==4);
assertTrue(countNeighborRelations(room8_5, 1)==8);
assertTrue(countNeighborRelations(room24_9, 1)==24);
assertTrue(countNeighbors(room0_0, 1)==0);
assertTrue(countNeighbors(room2_2, 1)==2);
assertTrue(countNeighbors(room4_3, 1)==3);
assertTrue(countNeighbors(room4_4, 1)==4);
assertTrue(countNeighbors(room8_5, 1)==5);
assertTrue(countNeighbors(room24_9, 1)==9);
}
編輯為完整請求的功能添加了完整的實現
以下代碼的復雜度為 O(gridSize^2)
private int neigbours(Collection<CoordinatedObject> cos,int gridSize) {
boolean[][] array=new boolean[gridSize][gridSize];
for(CoordinatedObject co:cos) {
array[co.getX()][co.getY()]&=true;
}
boolean[][] neighborRelations = new boolean[array.length][array[0].length];
for (int y = 0; y < array.length; y++) {
for (int x = 0; x < array[y].length - 1; x++) {
if (array[y][x] && array[y][x + 1]) {
neighborRelations[y][x]&=true;
neighborRelations[y][x + 1]&=true;
}
}
}
for (int y = 0; y < array.length - 1; y++) {
for (int x = 0; x < array[y].length; x++) {
if (array[y][x] && array[y + 1][x]) {
neighborRelations[y][x]&=true;
neighborRelations[y + 1][x]&=true;
}
}
}
int neighbourCount=0;
for (int y = 0; y < neighborRelations.length; y++) {
for (int x = 0; x < neighborRelations[y].length; x++) {
if (neighborRelations[y][x]) {
neighbourCount++;
}
}
}
return neighbourCount;
}
我假設您將所有 x 的坐標按順序存儲在兩張地圖中(一張用於 x,一張用於 y)。 所以例如
{X , X , 0 , X},
{X , 0 , X , X}
{0 , 0 , X , X}
{X , X, 0 , 0}
所以你的地圖會有這樣的條目
xmap = {
0 : 0,
1 : 1,
2 : 3,
3 : 0,
4 : 2,
5 : 3,
6 : 2,
7 : 3,
8 : 0,
9 : 1
}
ymap = {
0 : 0,
1 : 0,
2 : 0,
3 : 1,
4 : 1,
5 : 1,
6 : 2,
7 : 2,
8 : 3,
9 : 3,
}
我認為左右可以像這樣編輯
//left
if (xcord >= 0 && x - 1 >= 0 && xcord - 1 == xcordLeft && ycord == ycordLeft) {
neighbours++; //comparing (x - 1 , y) && (x , y)
}
//right
if (xcord >= 0 && x + 1 < size && xcord + 1 == xcordRight && ycord == ycordRight) {
neighbours++; // comparing(x , y) && (x + 1 , y)
}
實際上 xcordTop 應該是 ycordTop 但讓我們假設它相當於找到頂部元素
the mistake you are doing is that how can you be sure that
int xcordTop = xcord - 1 >= 0 ? xmap.get(xcord - 1) : 0; will give you coordinate of just upper element, because key of
the map is not x coordinates it is just numbering of X'S
所以對於給定矩陣中的第 7 個 X(其索引為 6,以 0 為基礎的編號),讓我們取它的 x 和 y 坐標
xcord = 2
ycord = 2
now let's us take xmap.get(2)
what do we get xcordTop = 0
即使我們從 ycordTop 邏輯出發,它也會給我們錯誤的坐標,因為地圖鍵值只是總 X 序列的值
so let's take ymap.get(ycord)
ycord = 2
so ycordTop = ymap.get(2)
we get ycordTop = 0 so which is 0th row
所以一個簡單的解決方案是遍歷二維數組並檢查你提到的所有鄰居
for(int y = 0; y < array.length; ++y){
for(int x = 0; x < array[y].length; ++x){
if(array[x][y] == 'X'){
if(x - 1 >= 0 && array[x - 1][y] == 'X'){
++neighbors;
}
else if(x + 1 < array[y].length && array[x + 1][y] == 'X'){
++neighbors;
}
else if(y - 1 >= 0 && array[x][y - 1] == 'X'){
++neighbors;
}
else if(y + 1 < array.length && array[x][y + 1] == 'X'){
++neighbors;
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.