【问题标题】:Traverse an array from outer elements to inner ones将数组从外部元素遍历到内部元素
【发布时间】:2020-04-18 15:43:22
【问题描述】:

我们正在做以下练习:Snail

为了能够完成程序我们想到了下面的例子:

给定数组:

[1, 2, 3, 1]
[4, 5, 6, 4]
[7, 8, 9, 7]
[7, 8, 9, 7]


1. Iterate over first row (i==0) j++
[0,0]=1, [0,1]=2, [0,2]=3, [0,3]=1

2. Traverse last column (j==array[i].length-1) i++
[1,3]=4, [2,3]=7, [3,3]=7

3. Iterate over last row (i==array.length-1) j--
[3,2]=9, [3,1]=8, [3,0]=7

4. Go up into first column, do not take first row (j==0) (0>i<array.length-1) i--
[2,0]=7, [1,0]=4

5. Iterate over second row, do not take the last column (i==1) (-1>j<array.length-2) j++
[1,1]=5, [1,2]=6

6. Get middle elements
[2,2]=9, [2,1]=8

我们编写了以下代码:

import java.util.*;
import java.util.stream.*;

public class Snail {
    public static int[] snail /*????????????*/ (int[][] array) {
      System.out.println("array: "+Arrays.deepToString(array));

      /*
      1. Iterate over first row (i==0) j++
      2. Traverse last column (j==array[i].length-1) i++
      3. Iterate over last row (i==array.length-1) j--
      4. Go up into first column, do not take first row (j==0) (0>i<array.length-1) i--
      5. Iterate over second row, do not take the last column (i==1) (-1>j<array.length-2) j++
      6. Do it and finally get the middle elements (i==2) (0<j<array[i].length-1)
      */

      List<Integer> firstRow = getRow(0,0,array[0].length,1,array);
      System.out.println("firstRow: "+Arrays.toString(firstRow.toArray()));

      List<Integer> lastColumn = getColumn(array[0].length-1,1,array[0].length,1,array);
      System.out.println("lastColumn: "+Arrays.toString(lastColumn.toArray()));

      List<Integer> lastRow = getRow(array.length-1,(array[array.length-1].length) - 2,-1,-1,array);
      System.out.println("lastRow: "+Arrays.toString(lastRow.toArray()));

      List<Integer> firstColumn = getColumn(0,array[0].length-2,0,-1,array);
      System.out.println("firstColumn: "+Arrays.toString(firstColumn.toArray()));

      List<Integer> middle = getRow(1,1,array[1].length-1,1,array);
      System.out.println("middle: "+Arrays.toString(middle.toArray()));


      List<Integer> middle2 = getRow(2,array[1].length-2,0,-1,array);
      System.out.println("middle2: "+Arrays.toString(middle2.toArray()));


      middle.addAll(middle2);
      firstColumn.addAll(middle);
      lastRow.addAll(firstColumn);
      lastColumn.addAll(lastRow);
      firstRow.addAll(lastColumn);
      System.out.println("firstRow: "+Arrays.toString(firstRow.toArray()));

      return firstRow.stream().mapToInt(i->i).toArray();
   }

   public static List<Integer> getRow(int row, int from, int to, int modifier, int[][] array){
     List<Integer> result = new ArrayList<>();

     for(int j=from; Math.max(j,to)>Math.min(j,to); j+=modifier){
       System.out.println("j: "+j);
       result.add(array[row][j]);
     }
     return result;
   }

   public static List<Integer> getColumn(int column, int from, int to, int modifier, int[][] array){
     List<Integer> result = new ArrayList<>();

     for(int j=from; Math.max(j,to)>Math.min(j,to); j+=modifier){
       System.out.println("j: "+j);
       result.add(array[j][column]);
     }
     return result;
   }

}

如您所见,我们已按照步骤操作。但是,无论给定数组的大小,我们如何制定这个解决方案?

目前发布的代码通过了第一个测试,但没有通过第二个测试(所以我们需要一种方法来回答所有可能的数组大小的练习):

import org.junit.Assert;
import org.junit.Test;
import org.junit.runners.JUnit4;
import java.util.Arrays;
import java.util.Random;
import static java.util.stream.Collectors.joining;

public class SnailTest {

  @Test
    public void SnailTest0() {
        int[][] array
                = {{1, 2, 3, 1},
                {4, 5, 6, 4},
                {7, 8, 9, 7},
                {7, 8, 9, 7}};
        int[] r = {1, 2, 3, 1, 4, 7, 7, 9, 8, 7, 7, 4, 5, 6, 9, 8};
        test(array, r);
    }

  @Test
    public void SnailTest1() {
        int[][] array
                = {{1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}};
        int[] r = {1, 2, 3, 6, 9, 8, 7, 4, 5};
        test(array, r);
    }

 public String int2dToString(int[][] a) {
        return Arrays.stream(a).map(row -> Arrays.toString(row)).collect(joining("\n"));
    }

    public void test(int[][] array, int[] result) {
        String text = int2dToString(array) + " should be sorted to " + Arrays.toString(result);
        System.out.println(text);
        Assert.assertArrayEquals( result, Snail.snail(array));
    }

}

我们如何改进这个算法来遍历一个从外部元素到内部元素的数组?你将如何修改这个算法以能够处理给定的任何数组大小?

【问题讨论】:

  • 您的列表达式错误。而不是 'array[i].length-1' 你应该使用 'array[i][length-1]' 这将获得第 i 行最后一列的结果。

标签: java arrays algorithm


【解决方案1】:

您需要一个通用算法,该算法可以打印任何给定维度为n, m 的数组所需的内容。

这与您在互联网上任何地方都可以找到的二维阵列问题的螺旋打印非常相似。

这是一个示例代码:


// declare n, m as number of rows and number of columns
// of the given matrix "array"

int startCol = 0, endCol = m - 1;
int startRow = 0, endRow = n - 1;

while(startRow <= endRow && startCol <= endCol) {
    for(int i = startCol; i <= endCol; i++) {
        System.out.println(array[startRow][i]);
    }
    for(int j = startRow + 1; j <= endRow; j++) {
        System.out.println(array[j][endCol]);
    }
    for(int i = endCol - 1; i >= startCol; i -= 1) {
        System.out.println(array[endRow][i]);
    }
    for(int j = endRow-1; j > startRow; j--) {
        System.out.println(array[j][startCol]);
    }

    startCol++;
    endCol--;
    startRow++;
    endRow--;
}

【讨论】:

    【解决方案2】:

    编写适用于任何数组大小的正确算法是相当棘手的。我们可以认为这是一个递归问题,我们复制数组的外部“层”,然后得到一个更小的数组。较小的阵列少 2 行和少 2 列。我们继续重复这个过程,直到嵌套数组不为空(有零行或零列)。这是我的代码和几个测试:

    package com.stackoverflow;
    
    import static org.junit.Assert.assertArrayEquals;
    
    import org.junit.Test;
    
    public class SnailTest {
      public static int[] snail(int[][] a) {
        return snail(a, 0, 0, new int[a.length * (a.length > 0 ? a[0].length : 0)], 0);
      }
    
      private static int[] snail(int[][] a, int row, int col, int[] result, int offset) {
        if (offset == result.length) {
          return result;
        }
    
        int height = a.length - 2 * row;
        int width = a[row].length - 2 * col;
    
        for (int i = 0; i < width; i++) {
          result[offset++] = a[row][col + i];
        }
        for (int j = 1; j < height - 1; j++) {
          result[offset++] = a[row + j][col + width - 1];
        }
        if (height > 1) {
          for (int i = width - 1; i >= 0; i--) {
            result[offset++] = a[row + height - 1][col + i];
          }
        }
        if (width > 1) {
          for (int j = height - 2; j > 0; j--) {
            result[offset++] = a[row + j][col];
          }
        }
        return snail(a, row + 1, col + 1, result, offset);
      }
    
      @Test
      public void test3x3() {
        assertArrayEquals(snail(new int[][] { //
            { 1, 2, 3 }, //
            { 8, 9, 4 }, //
            { 7, 6, 5 } }), //
            new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
      }
    
      @Test
      public void test4x4() {
        assertArrayEquals(snail(new int[][] { //
            { 1, 2, 3, 4 }, //
            { 12, 13, 14, 5 }, //
            { 11, 16, 15, 6 }, //
            { 10, 9, 8, 7 } }), //
            new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-03
      • 2020-08-08
      • 2018-04-06
      • 2015-01-16
      • 1970-01-01
      • 1970-01-01
      • 2014-12-17
      • 1970-01-01
      相关资源
      最近更新 更多