以螺旋顺序打印二维数组

59

我如何以螺旋顺序打印一个5×5的二维数组?

是否有任何公式可以让我按照螺旋顺序打印任何大小的数组?


6
在什么背景下?HTML?WPF?命令行?Matlab?空中写字? - Tom Ritter
也许他正在解决这个Project Euler问题:http://projecteuler.net/index.php?section=problems&id=28 - Chris Upchurch
38个回答

0
#include <iostream>

using namespace std;

const int MAX=100;

int main(void)
{
int a[MAX][MAX],i,j,lower,upper,k,n=0,am=0;
cout<<"enter number or size of matrix \n"<<endl;
cin>>n;

// assigning the value 
for(i=0;i<n;i++)
{
    for(j=0;j<n;j++)
      a[i][j]=am+1;

}
i=0;
j=0;
lower=0,upper=n-1;
for(k=0;k<(n*n);k++)
{
    cout<<a[i][j]<<"\t";
    if((i==lower)&&(j<upper))
            j++;
    else if((j==upper)&&(i<lower))
            j--;
    else if((j==lower)&&(i>lower))
           i--;
    if((a[i][j]==a[lower][i]))
    {
        lower++;
        upper--;
        i++;
        j++;
    }
}
return 0;
}

请在您的答案中增加一些解释,以便于未来的访客。 - Nikolay Mihaylov

0
//shivi..coding is adictive!!
#include<shiviheaders.h>
#define R 3
#define C 6
using namespace std;

void  PrintSpiral(int er,int ec,int arr[R][C])
{
    int sr=0,sc=0,i=0;


    while(sr<=er && sc<=ec)
    {
        for(int i=sc;i<=ec;++i)
            cout<<arr[sr][i]<<" ";
        ++sr;

        for(int i=sr;i<=er;++i) 
            cout<<arr[i][ec]<<" ";
        ec--;

        if(sr<=er)  
        {
            for(int i=ec;i>=sc;--i)
                cout<<arr[er][i]<<" ";
            er--;   
        }

        if(sc<=ec)
        {
            for(int i=er;i>=sr;--i)
                cout<<arr[i][sc]<<" ";
            ++sc;   
        }

    }

}

int main()
{
    int a[R][C] = { {1,  2,  3,  4,  5,  6},
            {7,  8,  9,  10, 11, 12},
            {13, 14, 15, 16, 17, 18}
        };

        PrintSpiral(R-1, C-1, a);
}

0

我已经用Python3解决了这个问题。它几乎通过了所有的边缘情况。

def spiralOrder(self, matrix):
    r = len(matrix)
    if r == 0:
        return []

    c = len(matrix[0])

    result = []
    x = 0; y = 0
    while x< r and y<c:
        for i in range(y,c):
            result.append(matrix[x][i])
        x+=1
        for i in range(x,r):
            result.append(matrix[i][c-1])
        c-=1
        if x < r:
            for i in range(c-1,y-1,-1):
                result.append(matrix[r-1][i])
            r -=1
        if y <c :
            for i in range(r-1,x-1,-1):
                result.append(matrix[i][y])
            y+=1

    return result

0

这是我能想到的C语言递归版本:

void printspiral  (int[][100],int, int, int, int);

int main()
{
  int r,c, i, j;
  printf ("Enter the dimensions of the matrix");
  scanf("%d %d", &r, &c);
  int arr[r][100];
  int min = (r<c?r:c);
  if (min%2 != 0) min = min/2 +1;
  for (i = 0;i<r; i++)
    for (j = 0; j<c; j++)
        scanf ("%d",&arr[i][j]);

  printspiral(arr,0,r,c,min );


}

void printspiral (int arr[][100], int i, int j, int k, int min)
{
   int a;

   for (a = i; a<k;a++)
   printf("%d\n", arr[i][a]);
   for (a=i+1;a<j;a++) 
   printf ("%d\n", arr[a][k-1]);
   for (a=k-2; a>i-1;a--)
   printf("%d\n", arr[j-1][a]);
   for (a=j-2; a>i; a--)
   printf("%d\n", arr[a][i]);
   if (i < min)
       printspiral(arr,i+1, j-1,k-1, min);

 }

0

这是我的Java实现:

public class SpiralPrint {
static void spiral(int a[][],int x,int y){

    //If the x and y co-ordinate collide, break off from the function

    if(x==y)
        return;
    int i;

    //Top-left to top-right

    for(i=x;i<y;i++)
        System.out.println(a[x][i]);

    //Top-right to bottom-right 

    for(i=x+1;i<y;i++)
        System.out.println(a[i][y-1]);

    //Bottom-right to bottom-left

    for(i=y-2;i>=x;i--)
        System.out.println(a[y-1][i]);

    //Bottom left to top-left

    for(i=y-2;i>x;i--)
        System.out.println(a[i][x]);

    //Recursively call spiral

    spiral(a,x+1,y-1);

}

public static void main(String[] args) {

    int a[][]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
    spiral(a,0,4);
    /*Might be implemented without the 0 on an afterthought, all arrays will start at 0 anyways. The second parameter will be the dimension of the array*/ 

    }

}

0
public class SpiralPrint{

    //print the elements of matrix in the spiral order.
    //my idea is to use recursive, for each outer loop

    public static void printSpiral(int[][] mat, int layer){
        int up = layer;
        int buttom = mat.length - layer - 1;
        int left = layer;
        int right = mat[0].length - layer - 1;
        if(up > buttom+1 || left > right + 1)
            return; // termination condition

        //traverse the other frame, 
        //print up
        for(int i = left; i <= right; i ++){
            System.out.print( mat[up][i]+ " " );
        }
        //print right
        for(int i = up + 1; i <=buttom; i ++){
            System.out.print(mat[i][right] + " ");
        }

        //print buttom
        for(int i = right - 1; i >= left; i --){
            System.out.print(mat[buttom][i] + " ");
        }

        //print left
        for(int i = buttom - 1; i > up; i --){
            System.out.print(mat[i][left] + " ");
        }

        //recursive call for the next level
        printSpiral(mat, layer + 1);
    }

    public static void main(String[] args){

        int[][] mat = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16}};
        int[][] mat2 = {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}};
        SpiralPrint.printSpiral(mat2,0);
        return;
    }
}

0

这是我的C#解决方案:

public static void PrintSpiral(int[][] matrix, int n)
{
    if (matrix == null)
    {
        return;
    }

    for (int layer = 0; layer < Math.Ceiling(n / 2.0); layer++)
    {
        var start = layer;
        var end = n - layer - 1;
        var offset = end - 1;

        Console.Write("Layer " + layer + ": ");

        // Center case
        if (start == end)
        {
            Console.Write(matrix[start][start]);
        }

        // Top
        for (int i = start; i <= offset; i++)
        {
            Console.Write(matrix[start][i] + " ");
        }

        // Right
        for (int i = start; i <= offset; i++)
        {
            Console.Write(matrix[i][end] + " ");
        }

        // Bottom
        for (int i = end; i > start; i--)
        {
            Console.Write(matrix[end][i] + " ");
        }

        // Left
        for (int i = end; i > start; i--)
        {
            Console.Write(matrix[i][start] + " ");
        }

        Console.WriteLine();
    }
}

0

这是我的方法,使用了迭代器。请注意,这几乎解决了相同的问题。 完整代码在此处:https://github.com/rdsr/algorithms/blob/master/src/jvm/misc/FillMatrix.java

import java.util.Iterator;

class Pair {
    final int i;
    final int j;

    Pair(int i, int j) {
        this.i = i;
        this.j = j;
    }

    @Override
    public String toString() {
        return "Pair [i=" + i + ", j=" + j + "]";
    }
}


enum Direction {
    N, E, S, W;
}


class SpiralIterator implements Iterator<Pair> {
    private final int r, c;
    int ri, ci;
    int cnt;

    Direction d; // current direction
    int level; // spiral level;

    public SpiralIterator(int r, int c) {
        this.r = r;
        this.c = c;

        d = Direction.E;
        level = 1;
    }

    @Override
    public boolean hasNext() {
        return cnt < r * c;
    }

    @Override
    public Pair next() {
        final Pair p = new Pair(ri, ci);
        switch (d) {
            case E:
                if (ci == c - level) {
                    ri += 1;
                    d = changeDirection(d);
                } else {
                    ci += 1;
                }
                break;

            case S:
                if (ri == r - level) {
                    ci -= 1;
                    d = changeDirection(d);
                } else {
                    ri += 1;
                }
                break;

            case W:
                if (ci == level - 1) {
                    ri -= 1;
                    d = changeDirection(d);
                } else {
                    ci -= 1;
                }
                break;

            case N:
                if (ri == level) {
                    ci += 1;
                    level += 1;
                    d = changeDirection(d);
                } else {
                    ri -= 1;
                }
                break;
        }

        cnt += 1;
        return p;
    }

    private static Direction changeDirection(Direction d) {
        switch (d) {
            case E:
                return Direction.S;
            case S:
                return Direction.W;
            case W:
                return Direction.N;
            case N:
                return Direction.E;
            default:
                throw new IllegalStateException();
        }
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }

}


public class FillMatrix {
    static int[][] fill(int r, int c) {
        final int[][] m = new int[r][c];
        int i = 1;
        final Iterator<Pair> iter = new SpiralIterator(r, c);
        while (iter.hasNext()) {
            final Pair p = iter.next();
            m[p.i][p.j] = i;
            i += 1;
        }
        return m;
    }

    public static void main(String[] args) {
        final int r = 19, c = 19;
        final int[][] m = FillMatrix.fill(r, c);
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                System.out.print(m[i][j] + " ");
            }
            System.out.println();
        }
    }
}

0
public static void printSpiral1(int array[][],int row,int col){

    int rowStart=0,colStart=0,rowEnd=row-1,colEnd=col-1;
    int i;

    while(rowStart<=rowEnd && colStart<= colEnd){

        for(i=colStart;i<=colEnd;i++)
            System.out.print(" "+array[rowStart][i]);   

        for(i=rowStart+1;i<=rowEnd;i++)
            System.out.print(" "+array[i][colEnd]); 

        for(i=colEnd-1;i>=colStart;i--)
            System.out.print(" "+array[rowEnd][i]); 

        for(i=rowEnd-1;i>=rowStart+1;i--)
            System.out.print(" "+array[i][colStart]);   

        rowStart++;
        colStart++;
        rowEnd--;
        colEnd--;
    }

}

我认为这里有个错误...尝试printSpiral1(new int[]{ 1, 2 }, 1, 2)。 - peter
这不是重载方法,所以你只能传递2-D数组。 - Akhilesh Dhar Dubey
抱歉,我的意思是printSpiral1(new int [] [] {{1,2}}, 1,2) - peter
新的int[][] {{ 1, 2, 3 }, { 16, 17, 4 }, { 15, 18, 5 },{ 14, 19, 6 }, { 13, 20, 7 },{ 12, 21, 8 },{ 11, 10, 9 } }。尝试一下,你会看到。 - peter

0

有人感兴趣的话,这是Java代码。
输入:
4
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7

输出: 1 2 3 4 8 3 7 6 5 4 9 5 6 7 2 1

public class ArraySpiralPrinter {

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt(); //marrix size
    //read array
    int[][] ar = new int[n][n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        ar[i][j] = sc.nextInt();
      }
    }
    printTopRight(0, 0, n - 1, n - 1, ar);
  }
    //prints top and right layers.
  //(x1,y1) to (x1, y2) - top layer & (x1,y2) to (x2, y2)
  private static void printTopRight(int x1, int y1, int x2, int y2, int[][] ar) {
    //print row values - top
    for (int y = y1; y <= y2; y++) {
      System.out.printf("%d ", ar[x1][y]);
    }
    //print column value - right
    for (int x = x1 + 1; x <= x2; x++) {
      System.out.printf("%d ", ar[x][y2]);
    }

    //are there any remaining layers
    if (x2 - x1 > 0) {
      //call printBottemLeft
      printBottomLeft(x1 + 1, y1, x2, y2 - 1, ar);
    }
  }

    //prints bottom and left layers in reverse order
  //(x2,y2) to (x2, y1) - bottom layer & (x2,y1) to (x1, y1)
  private static void printBottomLeft(int x1, int y1, int x2, int y2, int[][] ar) {
    //print row values in reverse order - bottom
    for (int y = y2; y >= y1; y--) {
      System.out.printf("%d ", ar[x2][y]);
    }

    //print column value in reverse order - left
    for (int x = x2-1; x >= x1; x--) {
      System.out.printf("%d ", ar[x][y1]);
    }

    //are there any remaining layers
    if (x2 - x1 > 0) {
      printTopRight(x1, y1 + 1, x2 - 1, y2, ar);
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接