2

嗨,我正在开发一个简单的 L 游戏。我想从左到右水平翻转一个数组。例如,

{ 'x',' ',' ',' ' },

{ 'x',' ',' ',' ' },

{ 'x','x',' ',' ' },

{ ' ',' ',' ',' ' }

我想把它翻转到

{ ' ','x',' ',' ' },

{ ' ','x',' ',' ' },

{ 'x','x',' ',' ' },

{ ' ',' ',' ',' ' }

这是我当前的代码

    public void flipArray() {
    int rows = cells.length;
    int cols = cells[0].length;
    char temp[][] = new char[rows][cols];
    for (int i = rows-1; i>=0; i--) {
        for (int j = cols-1; j>=0; j--) {
            temp[rows-1-i][cols-1-j] = cells[i][j];
        }
    }
    for (int i=0; i<rows; i++) {
        for (int j=0; j<cols; j++) {
            System.out.print(temp[i][j] + " ");
        }
    }
    }

非常感谢您的任何帮助。这是我想要的结果。



    rand_seed = 14427                                                       rand_seed = 14427
$ LGame.main({})                                                        $ LGame.main({})
A i i                                                                   A i i   
  o i                                                                     o i   
  o i                                                                     o i   
  o o B                                                                   o o B 
Move: o101                                                              Move: o101
A i i                                                                   A i i   
  o i                                                                |  o   i   
  o i                                                                |  o   i   
o o   B                                                                 o o   B 

4

1 回答 1

2

你的代码太复杂了,我什至没有试图理解它。如果将问题拆分为子问题,问题就会变得更简单、更容易掌握。

首先是基本构建块,反转单个数组:

 static void flip(char[] array) {
     int left = 0;
     int right = array.length - 1;
     while (left < right) {
         char temp = array[left];
         array[left] = array[right];
         array[right] = temp;
         ++left;
         --right;
     }
 }

现在您可以遍历行数组并为每一行调用翻转:

static void flip(char[][] rows) {
    for (char[] row : rows) {
        flip(row);
    } 
}

当你把它分解成更小的问题时,你会发现它非常简单。

编辑:在二维数组中找到“L”的边界框可以再次拆分为更小的问题。您可以只遍历行,检查它们是否完全为空,如果不是,则找到“设置”单元格的最小和最大索引。为简单起见,我在两个嵌套循环中以一种方法执行此操作:

 static int[] getBoundingBox(char[][] rows) {
     int minY = Integer.MAX_VALUE;
     int maxY = Integer.MIN_VALUE;
     int minX = Integer.MAX_VALUE;
     int maxX = Integer.MIN_VALUE;
     for (int y=0; y<rows.length; ++y) {
         // find the rows min/max populated index
         char[] row = rows[y];
         int rowMinX = Integer.MAX_VALUE;
         int rowMaxX = Integer.MIN_VALUE;
         for (int x=0; x<row.length; ++x) {
             if (row[x] == 'x') {
                 rowMinX = Math.min(rowMinX, x);
                 rowMaxX = Math.max(rowMaxX, x);
             }                 
         }
         // check if the row is empty (min > max)
         if (rowMinX > rowMaxX) {
              // empty row, skip
              continue;
         }
         // update bounding box variables
         minY = Math.min(minY, y);
         maxY = Math.max(maxY, y);
         minX = Math.min(minX, rowMinX);
         maxX = Math.max(maxX, rowMaxX);
     }          
     // result is an array containing the bounds
     return new int[] { minX, minY, maxX, maxY };
}

你现在应该真的能够连接这些部分了。

Edit2:剩下要做的就是修改翻转(行[] [])以获取边界,并仅对 minY 和 maxY 之间的行调用翻转(行 [])。然后行翻转需要从边界传递最小/最大 X,并使用传递的值而不是左/右的 0/length。仔细想一想,稍微想一想就明白了。

题外话,但您可能仍在学习:您将代码拆分为仅解决一个子问题的小方法的原因是您可以 a) 重新使用它们来解决相同的问题不同的地方和b)方法中的代码越少,就越容易验证它的作用以及它是否有效。将所有内容打包在一个大方法中会使您更难理解,并且当您需要在其他地方解决部分问题时,您会重复代码(和努力)。

于 2013-10-27T15:04:23.973 回答