【问题标题】:Moving recursively in arrays [closed]在数组中递归移动[关闭]
【发布时间】:2015-02-19 07:26:17
【问题描述】:

有谁知道如何移动“on the ones”并将它们更改为 2?我认为我们需要递归,但我不是很擅长,所以我请你帮忙。

您只能向上、向下、向左或向右移动。

这是一个例子:

int[][] a = {{ 0, 0, 0},
             {1, 1, 0},
             {1, 1, 1},
             {1, 0, 1} };

recursiveFunction(a, 1, 1); // (<array you're checking>, <x of the group>, <y of the group>

/* int a now contains:
 * { 0, 0, 0,
 *   2, 2, 0,
 *   2, 2, 2,
 *   2, 0, 2 } */

int[][] b = {{0, 0, 0, 0, 1},
             {1, 1, 0, 0, 1},
             {1, 1, 1, 0, 1},
             {1, 0, 1, 0, 1} };

recursiveFunction(b, 0, 5);
/* int b now contains:
 * { 0, 0, 0, 0, 2
 *   1, 1, 0, 0, 2
 *   1, 1, 1, 0, 2
 *   1, 0, 1, 0, 2 } */ 

【问题讨论】:

  • 这不会编译。您声明一个二维数组,但将其初始化为一维数组。
  • 除了类型不应该是char而是int

标签: java arrays recursion


【解决方案1】:

您只定义了一维数组及其编号,因此您应该使用 int。

不要递归地做,而是尝试用两个for循环(1个用于行,1个用于列)来轻松解决二维数组,如下所示:

int array[][] = {{0, 0, 0},
                 {1, 1, 0},
                 {1, 1, 1},
                 {1, 0, 1}};
for (int i = 0; i< array.length; i++) {
    for (int j = 0; j< array[0].length; j++) {
         if (array[i][j] == 1) {
             array[i][j] = 2;
         }
    }
}

【讨论】:

  • 我也向你道歉。原始帖子具有误导性。
【解决方案2】:

你不需要递归。这很简单。还要注意我创建二维数组的方式

char[][] a = { {0, 0, 0},
           {1, 1, 0},
           {1, 1, 1},
           {1, 0, 1 }}; 

for(int i = 0; i < a.length; i++)
  for(int j = 0; j < a[i].length; j++) {

     if(a[i][j] == 1)
        a[i][j] = 2;
   }

  }

这行得通吗?

【讨论】:

  • 对不起,我在帖子中不太清楚。这适用于这个简单的案例,但我得到的是一个包含多个组的更大的数组,我必须只更改我被告知的那个。一组是左、右、上或下连接的所有组。
  • 我们必须使用连接组件算法以最佳方式完成此操作。我已经这样做了一段时间,所以我正在研究它,并将很快编辑我的解决方案。 en.wikipedia.org/wiki/…
【解决方案3】:

您可以创建一个函数并将要替换的值传递给它。它会比递归更好,因为您可以避免在每次递归调用期间需要额外的 stack 成本

public static void replace(char[][] arr, char target, char replacment) {
    for (int i = 0; i< arr.length; i++) {
        for (int j = 0; j< arr[i].length; j++) {
            if (arr[i][j] == target) {
                arr[i][j] = replacment;
            }
        }
    }
}

那你就可以这样称呼了

replace(arr, (char)1, (char)2);

【讨论】:

  • 你的答案更笼统,1票赞成。
【解决方案4】:

好的,所以如果你想改变连接组件的值,你从这里开始应该可以工作。

public class Example {
    public static void main(String[] args) {
        int[][] b = 
            {
                {0, 0, 0, 0, 1},
                {1, 1, 0, 0, 1},
                {1, 1, 1, 0, 1},
                {1, 0, 1, 0, 1}
            };

        rec(b, 0, 4);

        for (int[] row : b) {
            System.out.println(Arrays.toString(row));
        }
    }

    public static void rec(final int[][] grid, final int row, final int col) {
        if (grid[row][col] != 1) return;

        grid[row][col]++;

        if (row-1 >= 0) rec(grid, row-1, col);
        if (row+1 < grid.length) rec(grid, row+1, col);
        if (col-1 >= 0) rec(grid, row, col-1);
        if (col+1 < grid[0].length) rec(grid, row, col+1);
    }
}

请注意,根据您的组件有多大,您可能会用完堆栈。您要么必须在代码中显式管理自己的堆栈,要么需要增加 JVM 可用的堆栈空间。

【讨论】:

  • 我不太确定我是否理解这一点。但我认为它也会改变我们正在查看的元素的对角线值。它应该只改变左、右、上或下的值
  • 好的,简化了。现在它不会沿对角线遍历了。
【解决方案5】:

为什么你认为你需要递归?您可以遍历数组并将每个元素乘以 2(因为无论如何,0 * 20,而且它比检查元素要快):

for (int i = 0; i < a.length; ++i) {
    for (int j = 0; j < a[i].length; ++j) {
        a[i][j] *= 2;
    }
}

【讨论】:

  • 但如果他的值不是一和二,那就错了
  • @user2397162 true - 但问题是关于 1 和 0 的矩阵。正如我所说,这是一种优化。如果您的数据不同,则必须检查元素的内容 - if (a[i][j] == 1) {a[i][j] = 2;}
  • 不错的解决方案,但原始帖子具有误导性。对不起。我现在编辑了,应该更清楚了。
【解决方案6】:

如果您使用的是 Java 8,则可以使用 Arrays.parallelSetAll 方法。

public static void replace(int[][] arr, int target, int replacement) {
    Arrays.parallelSetAll(arr, row -> {
        Arrays.parallelSetAll(arr[row], col -> arr[row][col] == target ? replacement : arr[row][col]);
        return arr[row];
    });
}

它使用 Java 8 Stream API:s 并提供了一个非常好的紧凑编程模型。此外,它使用 ForkJoinPool,因此性能可能会更好,因为它可能是多线程的(取决于 CPU 等)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-07
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 2022-01-12
    • 2015-06-25
    • 2016-04-25
    相关资源
    最近更新 更多