java 如何将二维数组中的所有内容左移

a0x5cqrl  于 2023-02-02  发布在  Java
关注(0)|答案(4)|浏览(211)

我需要取一个2D数组,并将所有内容尽可能向左移动。这是一个4X4数组,我已经尝试过这样做,但要么只移动某些项,要么索引超出界限。
gameBoard数组如下所示:

{0 2 4 2}
{0 0 2 0}
{2 2 0 0}
{0 4 0 2}

调用swipeLeft()方法后,它应该如下所示:

{2 4 2 0}
{2 0 0 0}
{2 2 0 0}
{4 2 0 0}

还有一个问题是将零放置到您移动它的前一个索引中。
我创建了一个double for循环来遍历数组,并尝试编写一些代码来移动它,但没有成功。
这是我目前拥有的代码

public void swipeLeft() {
   
    for ( int r = 0; r < gameBoard.length; r++ ) {
        for ( int c = 0; c < gameBoard[r].length; c++ ) {
            
            gameBoard[r][c] = gameBoard[r][ (c+1) % 
                                                gameBoard.length];
        }
    }

    
}
3htmauhk

3htmauhk1#

根据所需的OUTPUT,swipeLeft()似乎应该将所有非零值推到它们所在行的最左侧,将零替换到所有非零值的右侧。
如果这是正确的,这就类似于Old Dog Programmer的方法,除了所有的移位都是“原地”完成的,而没有创建任何新的数组:

import java.util.*;
class Main {

  private static int[][] gameBoard;
  
  public static void main(String[] args) {
    gameBoard = new int[][] {
      {0, 2, 4, 2},
      {0, 0, 2, 0},
      {2, 2, 0, 0},
      {0, 4, 0, 2}
    };

    System.out.println("Before:");
    displayBoard();

    swipeLeft();
    
    System.out.println("\nAfter:");
    displayBoard();
  }

  public static void displayBoard() {
    for(int[] row : gameBoard) {
      System.out.println(Arrays.toString(row));  
    }
  }

  public static void swipeLeft() {
    for(int[] row : gameBoard) {
      // find the first blank (zero) spot
      int nextIndex = 0;
      while(nextIndex < row.length && row[nextIndex] != 0) {
        nextIndex++;
      }
      // start with the first blank, and shift any non-zero
      // values afterwards to the left
      for(int col=nextIndex; col < row.length; col++) {
        if (row[col] != 0) {
          row[nextIndex] = row[col];
          row[col] = 0;
          nextIndex++;
        }
      }
    }
  }
  
}

输出:

Before:
[0, 2, 4, 2]
[0, 0, 2, 0]
[2, 2, 0, 0]
[0, 4, 0, 2]

After:
[2, 4, 2, 0]
[2, 0, 0, 0]
[2, 2, 0, 0]
[4, 2, 0, 0]
a11xaf1n

a11xaf1n2#

从问题中的例子来看,我觉得所要做的是将所有非零元素左移,零元素右移,非零元素的顺序保持不变。
请注意,每一行都独立于其他行。
解决这个问题的一个方法是创建一个处理一维数组的方法,这个方法以一个一维数组为参数,返回另一个元素移位后的一维数组:

public static int [] zeroShift (int [] arr) {
    int [] left = new int [arr.length];
    int count = 0;
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] != 0) {
            left [count++] = arr [i];
        }
    }
    return  left;
}

它将每个非零元素复制到一个相同大小的新数组中,并跟踪(count)到目前为止复制了多少个元素,注意这依赖于left被初始化为全零。
一旦该方法起作用,就可以逐行地将其用于gameBoard

public void swipeLeft() {
    for (int r = 0; r < gameBoard.length; r++) {
        gameBoard [r] = zeroShift (gameBoard [r]);
    }  

    // output for testing 
    for (int i = 0; i < gameBoard.length; ++i) {
        System.out.println(Arrays.toString(gameBoard[i]));
    }
}
jgwigjjp

jgwigjjp3#

要将阵列旋转到位,应将阵列旋转3次:

  1. 123456-〉654312
  2. 654321
  3. 3456..
  4. ....12
public static void shiftLeft(int[] arr, int offs) {
    if (offs <= 0)
        return;

    offs = arr.length - offs % arr.length - 1;

    for (int i = 0, j = arr.length - 1; i < j; i++, j--)
        swap(arr, i, j);
    for (int i = 0, j = offs; i < j; i++, j--)
        swap(arr, i, j);
    for (int i = offs + 1, j = arr.length - 1; i < j; i++, j--)
        swap(arr, i, j);
}

private static void swap(int[] arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
vlf7wbxs

vlf7wbxs4#

所以你的代码打算把板子向左旋转一列,旋转?你在左边推出来的数字可能会在最后回来,对吗?
可能是台词

gameBoard[r][c] = gameBoard[r][ (c+1) % gameBoard.length];

应该是

gameBoard[r][c] = gameBoard[r][ (c+1) % gameBoard[r].length];

但是试着用笔和纸来做这些事情,你应该注意到你会丢失一列/把第二列的值复制到第一列,然后再复制到最后一列。
您需要更改两个项目:

  • 如果仍然需要第一列的值,可以将其存储在某个地方,以便将其推送到最后一列。
  • 只在列数据需要旋转时旋转列数据。换句话说,如果找到零,则旋转行的其余部分。在这种情况下,您不需要记住第一列,因为您将覆盖零并将零推入最后一列。这样,它就不称为rotate,而是shift。

用笔和纸练习,直到你能为其他人写下执行相同操作的指令,然后你也准备好用Java来写。

相关问题