如何检查来自一个单元格的所有可到达单元格

时间:2017-04-29 16:39:34

标签: java multidimensional-array merge cell

我需要检查可从2d数组中的某个特定单元格到达的所有可能路径。例如;

int [][] grid = {{2, 0, 0, 1, 1, 2}, 
                 {1, 0, 2, 0, 0, 1}, 
                 {1, 0, 2, 0, 4, 2}, 
                 {8, 3, 4, 0, 1, 2}, 
                 {1, 2, 5, 0, 3, 3}, 
                 {5, 1, 1, 2, 1, 0}};`

我想检查从单元格(2)(1)可以访问的所有单元格(它只是一个示例位置)。如果此位置为零,首先会在此处放置一些数字。例如,1位于该位置。 然后我需要开始合并从单元格(2,1)可以到达的所有1个。如果创建此路径的单元格包括至少两个1,则必须用2替换单元格(2)(1)位置1 + 1 = 2。   之后,必须将合并过程中使用的单元分配为零。 但是如果仍然可能合并单元格(2)(1),它们也应该合并。 我尝试使用递归函数,但它没有按我的意愿工作。 如果少于3个包含相同值的相邻单元格以及如何合并直到没有可能合并左边,我无法弄清楚如何防止合并。方法应该继续合并,直到没有可能的合并,但我的代码合并一次。我刚刚开始学习java抱歉已经犯错了。

2 个答案:

答案 0 :(得分:2)

所以... 我不确定我是否把一切都弄好了,因为有些事情是误导的。 单元(2)(2)的初始含量为:2

我认为你所选择的细胞是(1)(2)。 //注意:java中的索引以0开头

所以你的想法有点复杂,不应该只用一种方法来解决。

我写了一些代码:

private static int[][] directions = new int[][]{{1,0},{-1,0},{0,1},{0,-1}};

public static void step(int[][] array, int x, int y) {

     if(array[x][y] == 0){
         array[x][y] = 1;
     }else{
         return;
     }
    int number = 1;
    while(true){
        printGrid(array);
        int amount = process(array, x, y);
        if(amount == 1)break;
        number ++;
        array[x][y] = number;
    }
}

public static int process(int[][] array,int x, int y){
    int number = array[x][y];
    if(number == 0) return 0;
    int total = 1;
    array[x][y] = 0;
    for(int[] dire:directions){
        if(x + dire[0] >= 0 && x + dire[0] < array.length && y + dire[1] >= 0 && y + dire[1] < array[0].length){
            if(array[x + dire[0]][y+dire[1]] == number){
                total += process(array, x + dire[0], y+dire[1]);
            }
        }
    }
    return total;
}


public static void printGrid(int[][] grid) {
    for(int i = 0; i < grid.length; i++){
        String s = "";
        for(int n = 0; n<  grid[0].length; n++){
            s += grid[i][n]+", ";
        }
        System.out.println(s);
    }
    System.out.println("");
}

public static void main(String[] args){
    int [][] grid =
            {{2, 0, 0, 1, 1, 2},
            {1, 0, 2, 0, 0, 1},
            {1, 0, 2, 0, 4, 2},
            {8, 3, 4, 0, 1, 2},
            {1, 2, 5, 0, 3, 3},
            {5, 1, 1, 2, 1, 0}};

    Main.step(grid, 2,1);

   printGrid(grid);

}

我这样修改了它;

public static void main(String []args){
    System.out.println("Welcome to the game Merge Numbers. Your grid as follows:");
    int[][] newGrid = {{2, 0, 1, 1, 0, 8}, 
                      {2, 1, 0, 2, 4, 0}, 
                      {1, 2, 1, 2, 1, 3}, 
                      {2, 3, 2,0, 1, 0}, 
                      {0, 0, 5, 8, 7, 2}, 
                      {2, 0, 1, 1, 0, 0}};
    for(int i = 0 ; i < newGrid.length ; i++){
        for (int j = 0; j < newGrid[i].length; j++) {
            System.out.print(newGrid[i][j] + " ");
        }
        System.out.println();
    }
    try (Scanner keyboard = new Scanner(System.in)){
    System.out.print("Please enter your target's row index:");
    int newRow = keyboard.nextInt();
    System.out.print("Please enter your target's column index:");
    int newColumn = keyboard.nextInt();
    System.out.print("Please enter the number that you want to add to location " + newRow +  " " +  newColumn);
    int newNextNumber = keyboard.nextInt();
    step(newGrid, newRow, newColumn, newNextNumber);
    for(int i = 0 ; i < newGrid.length ; i++){
        for (int j = 0; j < newGrid[i].length; j++) {
            System.out.print(newGrid[i][j] + " ");
        }
        System.out.println();
    }}
}

public static void step(int[][] grid, int row, int column, int nextNumber ) {

     if(grid[row][column] == 0){
         grid[row][column] = nextNumber;
     }else{
         return;
     }
     int number = nextNumber;
    while(true){
        int amount = process(grid, row, column);
        if(amount == 1)break;
        number ++;
        grid[row][column] = number;
    }
}

public static int process(int[][] grid,int row, int column){
    int number = grid[row][column];
    if(number == 0) return 0;
    int total = 1;
    grid[row][column] = 0;
    for(int[] dire:directions){
        if(row + dire[0] >= 0 && row + dire[0] < grid.length && column + dire[1] >= 0 && column + dire[1] < grid[0].length){
            if(grid[row + dire[0]][column+dire[1]] == number){
                total += process(grid, row + dire[0], column+dire[1]);
            }
        }
    }
    return total;
}

} 但是当我运行它时,所有点都包括目标位置变为零。输出就像;

Welcome to the game Merge Numbers. Your grid as follows:
2 0 1 1 0 8 
2 1 0 2 4 0 
1 2 1 2 1 3 
2 3 2 0 1 0 
0 0 5 8 7 2 
2 0 1 1 0 0 
Please enter your target's row index:3
Please enter your target's column index:3
Please enter the number that you want to add to location 3 3: 1
2 0 1 1 0 8 
2 1 0 0 4 0 
1 2 1 0 0 3 
2 3 0 0 0 0 
0 0 5 8 7 2 
2 0 1 1 0 0 

我的意思是如果你看输出中的第一个网格,则单元格(3)(3)为零。当1放在这里时,可以从该单元(3)(3)到达的1合并。然后,单元(3)(3)包括2.然后执行相同的过程。但是当完成所有可能的合并时,在该过程中使用的所有单元格包括中心变为0.每次合并后中心应该增加1。我想,我使用的第四个参数是nextNumber错误。功能过程是否还包括该参数?很抱歉打扰你这么多:)

答案 1 :(得分:1)

这里是你如何找到一个单元格的邻居......

int x[] = {-1, -1, -1, 0, 0, +1, +1, +1}; 
int y[] = {-1, 0, +1, -1, +1, -1, 0, +1};
// looping through the neghibours...
for(int i=0; i<8; i++) {
    if( p+x[i] < n && q+y[i] < m && a[p + x[i]][q + y[i]] == a[p][q]) {
        // neighbour
    }
}

以下是您的问题的递归实施,n&amp; m是网格ap&amp;的大小q是您要执行合并的单元格的索引...

public static void merge(int a[][], int n, int m, int p, int q) {

    int x[] = {-1, -1, -1, 0, 0, +1, +1, +1};
    int y[] = {-1, 0, +1, -1, +1, -1, 0, +1};
    int c = 0;
    // looping through the neghibours...
    for(int i=0; i<8; i++) {
        if( p+x[i] < n && q+y[i] < m && a[p + x[i]][q + y[i]] == a[p][q]) {
            c++;
        }
    }

    if(c > 3) { // merging only if neghibours > 3
        for(int i=0; i<8; i++) {
            if( p+x[i] < n && q+y[i] < m && a[p + x[i]][q + y[i]] == a[p][q]) {
                a[p + x[i]][q + y[i]] = 0;
            }
        }
        a[p][q] += 1;
        merge(a, n, m, p, q); // recurcively merging if possible...
    }
}
相关问题