J'ai un tableau multidimensionnel, je veux obtenir les éléments entourant un élément particulier dans ce tableau.
Par exemple si j'ai les éléments suivants:
[[1,2,3,4,5,6]
[8,9,7,5,2,6]
[1,6,8,7,5,8]
[2,7,9,5,4,3]
[9,6,7,5,2,1]
[4,7,5,2,1,3]]
Comment trouver tous les 8 éléments autour de l'un des éléments ci-dessus? Et comment puis-je prendre soin des éléments sur les bords?
Une façon dont j'ai compris est d'écrire un code à 9 lignes pour cela, ce qui est évident, mais existe-t-il une meilleure solution?
for (i = 0; i < array.length; i++) {
for (j = 0; j < array[i].length; j++) {
for (x = Math.max(0, i - 1); x <= Math.min(i + 1, array.length); x++) {
for (y = Math.max(0, j - 1); y <= Math.min(j + 1,
array[i].length); y++) {
if (x >= 0 && y >= 0 && x < array.length
&& y < array[i].length) {
if(x!=i || y!=j){
System.out.print(array[x][y] + " ");
}
}
}
}
System.out.println("\n");
}
}
Merci à toutes les personnes qui ont répondu, mais j’ai compris avec l’aide de ce post que j’ai trouvé tout à l’heure, c’est la solution ci-dessus. Merci encore :)
Vous pouvez utiliser 'direction array' dans la forme
[[-1,-1], [-1,0],[1,0]..and so on]
Et méthode qui prend la coordonnée de point et itère dans le tableau de direction -> ajoute des numéros de direction aux coordonnées, vérifie que les index ne sont pas hors limites et collecte les résultats. Quelque chose comme ceci:
private static int[][] directions = new int[][]{{-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0, -1}};
static List<Integer> getSurroundings(int[][] matrix, int x, int y){
List<Integer> res = new ArrayList<Integer>();
for (int[] direction : directions) {
int cx = x + direction[0];
int cy = y + direction[1];
if(cy >=0 && cy < matrix.length)
if(cx >= 0 && cx < matrix[cy].length)
res.add(matrix[cy][cx]);
}
return res;
}
Pour (i, j) ->
(i - 1, j - 1)
(i - 1, j)
(i - 1, j + 1)
(i, j - 1)
(i, j + 1)
(i + 1, j - 1)
(i + 1, j)
(i + 1, j + 1)
Maintenant, sur les bords, vous pouvez rechercher num % row == 0
, puis sa ligne Edge ... Et num % col == 0
puis sa colonne Edge ..
Voici comment procéder: -
Avec un index (i, j)
.. Vous pouvez trouver des éléments dans les lignes adjacentes à j
pour i - 1
, puis i
et ensuite i + 1
. (NOTE: - pour l'index i
, il vous suffit d'accéder à j - 1
et à j + 1
)
Ensuite, vous pouvez également rechercher le row Edge
et le column Edge
..
Ici, vous pouvez regarder le code ci-dessous, comment cela peut arriver: -
// Array size
int row = 6;
int col = 6;
// Indices of concern
int i = 4;
int j = 5;
// To the left of current Column
int index = i - 1;
for (int k = -1; k < 2; k++) {
if (index % row > 0 && ((j + k) % col) > 0) {
System.out.println(arr[index][j + k]);
}
}
// In the current Column
index = i;
// Increment is 2 as we don't want (i, j)
for (int k = -1; k < 2; k = k + 2) {
if (index % row > 0 && ((j + k) % col) > 0) {
System.out.println(arr[index][j + k]);
}
}
// To the right of current Column
index = i + 1;
for (int k = -1; k < 2; k++) {
if (index % row > 0 && ((j + k) % col) > 0) {
System.out.println(arr[index][j + k]);
}
}
UPDATE: - Le code ci-dessus peut encore être simplifié .. Mais je vous laisse cette tâche .. HINT: - Vous pouvez en réduire une pour cette boucle. .
Le cas de base consiste simplement à obtenir des éléments voisins en indexant le décalage. Pour (i,j)
ce sera (i + 1, j)
, (i - 1, j)
, etc.
J'utilise deux approches sur les bords:
%
pour éviter une exception IndexOutOfBounds
, mais il confond parfois avec une indexation erronée des éléments.Exemple: votre élément par défaut est 0.
0 0 0 0 0 0
0 1 2 3 4 0
0 2 6 7 3 0
0 1 3 5 7 0
0 2 4 6 2 0
0 0 0 0 0 0
Remarque: n'oubliez pas de parcourir la taille réelle la taille du tableau, non étendue.
Ceci est ma solution pour votre problème écrit en Ruby. Au lieu de calculer si l'élément est sur Edge, vous pouvez accéder aux éléments "sur" Edge et gérer les valeurs "nil" ou les exceptions qui s'y produisent. Supprimez ensuite les valeurs "nil" de la liste finale. Cette solution n’est pas aussi efficace que de calculer si un "point" est au-dessus du bord ou non.
big_map = [[1,2,3,4,5,6],
[8,9,7,5,2,6],
[1,6,8,7,5,8],
[2,7,9,5,4,3],
[9,6,7,5,2,1],
[4,7,5,2,1,3]]
# monkey patch classes to return nil.
[NilClass, Array].each do |klass|
klass.class_eval do
def [](index)
return nil if index < 0 or index > self.size rescue nil
self.fetch(index) rescue nil
end
end
end
class Array
# calculate near values and remove nils with #compact method.
def near(i,j)
[ self[i - 1][j - 1], self[i - 1][j - 0], self[i - 1][j + 1],
self[i - 0][j - 1], self[i - 0][j + 1],
self[i + 1][j - 1], self[i + 1][j - 0], self[i + 1][j + 1],
].compact
end
end
puts big_map.near(1,1).inspect
# => [1, 2, 3, 8, 7, 1, 6, 8]
puts big_map.near(0,0).inspect
# => [2, 8, 9]
puts big_map.near(5,5).inspect
# => [2, 1, 1]
Je travaillais sur le même problème et je proposais une petite solution optimisée pour trouver les nombres environnants de tout point dans une matrice 2D. J'espère que cela vous aidera. S'il vous plaît, commentez si je peux raccourcir quelque peu la logique Code: -
import Java.util.ArrayList;
public class test {
public static void main(String[] arg){
int[][] arr = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}};
//int[][] arr = {{width,2,3},{4,5,6},{7,8,9}};
ArrayList<Integer> al = new ArrayList<Integer>();
int x = 2, y = 2;
int width = 2; //change the value of width, according to the requirement
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
if( (i == (x-width) && ( (y+width) >= j && j >= (y-width))) || (i == (x+width) && ( (y+width) >= j && j >= (y-width))) || (j == (y-width) && ( (x+width) >= i && i >= (x-width))) || (j == (y+width) && ( (x+width) >= i && i >= (x-width))) ){
//if( x >= 0 && i < (i+width) && y >= 0 && j < (j+width))
{
al.add(arr[i][j]);
}
}
}
}
System.out.println(al);
}
}
Vous n'avez pas mentionné si vous voulez des voisins cycliques pour les arêtes ou si vous ignorez les voisins cycliques. En supposant que vous vouliez des voisins cycliques, voici le code,
List<Integer> getNeighbours(int[][] mat, int x, int y){
List<Integer> ret = new ArrayList<Integer>();
int rows = mat.length;
int cols = mat[0].length;
for(int i=-1,i<=1;i++)
for(int j=-1;j<=1;j++)
if(i||j) ret = ret.add(mat[(x+i)%rows][(y+j)%cols]);
return ret;
}