web-dev-qa-db-ja.com

2次元配列をスパイラル順に印刷する

5×5の2次元配列をスパイラル順に印刷するにはどうすればよいですか?

任意のサイズの配列をスパイラル順に印刷できる数式はありますか?

55
Rahul Vyas

この考え方は、マトリックスを一連のレイヤー、右上のレイヤー、左下のレイヤーとして扱うことです。マトリックスを螺旋状に印刷するには、これらのマトリックスからレイヤーを剥離し、剥離した部分を印刷し、左の部分の印刷を再帰的に呼び出します。印刷するレイヤーがなくなると、再帰は終了します。

入力行列:

1 2 3 4 
5 6 7 8
9 0 1 2   
3 4 5 6 
7 8 9 1

右上のレイヤーを剥離した後:

 1 2 3 4 
       8
5 6 7  2
9 0 1  6   
3 4 5  1 
7 8 9

サブマトリックスから左下のレイヤーを剥離した後:

   6 7
5  0 1   
9  4 5
3 
7 8 9 

サブマトリックスから右上のレイヤーを剥離した後:

    6 7
      1   
   0  5
   4

サブマトリックスから左下のレイヤーを剥離した後:

  0
  4

再帰は終了します。


C関数:

// function to print the top-right peel of the matrix and 
// recursively call the print bottom-left on the submatrix.
void printTopRight(int a[][COL], int x1, int y1, int x2, int y2) {
    int i = 0, j = 0;

    // print values in the row.
    for(i = x1; i<=x2; i++) {
        printf("%d ", a[y1][i]);
    }

    // print values in the column.
    for(j = y1 + 1; j <= y2; j++)         {
        printf("%d ", a[j][x2]);
    }

    // see if more layers need to be printed.
    if(x2-x1 > 0) {
        // if yes recursively call the function to 
        // print the bottom left of the sub matrix.
        printBottomLeft(a, x1, y1 + 1, x2-1, y2);
    }
}

// function to print the bottom-left peel of the matrix and 
// recursively call the print top-right on the submatrix.
void printBottomLeft(int a[][COL], int x1, int y1, int x2, int y2) {
    int i = 0, j = 0;

    // print the values in the row in reverse order.
    for(i = x2; i>=x1; i--) {
        printf("%d ", a[y2][i]);
    }

    // print the values in the col in reverse order.
    for(j = y2 - 1; j >= y1; j--) {
        printf("%d ", a[j][x1]);
    }

    // see if more layers need to be printed.
    if(x2-x1 > 0) {
        // if yes recursively call the function to 
        // print the top right of the sub matrix.
        printTopRight(a, x1+1, y1, x2, y2-1);
    }
}

void printSpiral(int arr[][COL]) {
    printTopRight(arr,0,0,COL-1,ROW-1);
    printf("\n");
}
77
codaddict
  1. ポップトップ行
  2. 転置して上下逆さまにします(反時計回りに90度回転するのと同じ)
  3. 1に行く

Pythonコード:

import itertools

arr = [[1,2,3,4],
       [12,13,14,5],
       [11,16,15,6],
       [10,9,8,7]]

def transpose_and_yield_top(arr):
    while arr:
        yield arr[0]
        arr = list(reversed(Zip(*arr[1:])))

print list(itertools.chain(*transpose_and_yield_top(arr)))
31
Rick S

コードで1つだけfor loop再帰なしを使用している人はいないので、貢献したいと思います。

アイデアは次のとおりです。

ポイント(0,0)にカメが立っていることを想像してください。つまり、左上隅で、東(右)に面しています。

それは前進し続けるであり、サインを見るたびに、亀は右に曲がる

したがって、タートルを右向きのポイント(0,0)に配置し、適切な場所に標識を配置すると、タートルは螺旋状に配列を移動します。

問題は「標識をどこに置くか」です。

記号(#でマーク、Oで数字)を配置する場所を見てみましょう。

このようなグリッドの場合:
 OOOO 
 OOOO 
 OOOO 
 OOOO 
 
このような標識:
 OOO#
#O#O 
 O##O 
#OO#
 
グリッド用
 OOO 
 OOO 
 OOO 
 OOO 
 
次のように標識を付けます:
 OO#
##O 
 O#O 
#O#
 
そして、次のようなグリッドの場合:
 
#OOOO#O 
 O#OO#OO 
 O#OOO#O 
#OOOOO#

ポイントが左上にない限り、記号は最も近い水平方向の境界線と最も近い垂直方向の境界線までの距離は同じですの位置にあることがわかります。 -左の部分、上の境界線までの距離は左の境界線までの距離よりも1つ大きい、ポイントが水平方向に中央にある場合は右上、ケースの場合は左上が優先されるポイントは垂直方向に中央揃えです。

これは、最小の(curRowheight-1-curRow)を取得し、次に最小の(curColwidth-1-curCol)とそれらが同じかどうかを比較してください。ただし、左上、つまり最小値がcurRowおよびcurCol自体である場合を考慮する必要があります。その場合、それに応じて垂直距離を短くします。

Cコードは次のとおりです。

#include <stdio.h>

int shouldTurn(int row, int col, int height, int width){
    int same = 1;
    if(row > height-1-row) row = height-1-row, same = 0; // Give precedence to top-left over bottom-left
    if(col >= width-1-col) col = width-1-col, same = 0; // Give precedence to top-right over top-left
    row -= same; // When the row and col doesn't change, this will reduce row by 1
    if(row==col) return 1;
    return 0;
}

int directions[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
void printSpiral(int arr[4][4], int height, int width){
    int directionIdx=0, i=0;
    int curRow=0, curCol=0;
    for(i=0; i<height*width; i++){
        printf("%d ",arr[curRow][curCol]);
        if(shouldTurn(curRow, curCol, height, width)){
            directionIdx = (directionIdx+1)%4;
        }
        curRow += directions[directionIdx][0];
        curCol += directions[directionIdx][1];
    }
    printf("\n");
}

int main(){
    int arr[4][4]= {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
    printSpiral(arr, 4, 4);
    printSpiral(arr, 3, 4);
}

どの出力:

 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 
 1 2 3 4 8 12 11 10 9 5 6 7 
23
justhalf

ここに3つの興味深い方法があります

  1. 螺旋状に読むことは、ヘビが境界に向かって移動し、境界またはそれ自体にヒットするように扱うことができます(N反復の単一ループであることがエレガントで最も効率的であることがわかります)

    ar = [
         [ 0,  1,  2,  3, 4],
         [15, 16, 17, 18, 5],
         [14, 23, 24, 19, 6],
         [13, 22, 21, 20, 7],
         [12, 11, 10, 9, 8]]
    
    def print_spiral(ar):
        """
        assuming a rect array
        """
        rows, cols = len(ar), len(ar[0])
        r, c = 0, -1 # start here
        nextturn = stepsx = cols # move so many steps
        stepsy = rows-1
        inc_c, inc_r = 1, 0 # at each step move this much
        turns = 0 # how many times our snake had turned
        for i in range(rows*cols):
            c += inc_c
            r += inc_r 
    
            print ar[r][c],
    
            if i == nextturn-1:
                turns += 1
                # at each turn reduce how many steps we go next
                if turns%2==0:
                    nextturn += stepsx
                    stepsy -= 1
                else:
                    nextturn += stepsy
                    stepsx -= 1
                # change directions
                inc_c, inc_r = -inc_r, inc_c  
    
    print_spiral(ar)
    

出力:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
  1. 再帰的なアプローチは、外側のレイヤーを印刷し、内側の長方形に対して同じ関数を呼び出すことです。

    def print_spiral(ar, sr=0, sc=0, er=None, ec=None):
        er = er or len(ar)-1
        ec = ec or len(ar[0])-1
    
        if sr > er or sc > ec:
            print
            return
    
        # print the outer layer
        top, bottom, left, right = [], [], [], []
        for c in range(sc,ec+1):
            top.append(ar[sr][c])
            if sr != er:
                bottom.append(ar[er][ec-(c-sc)])
    
        for r in range(sr+1,er):
            right.append(ar[r][ec])
            if ec != sc:
                left.append(ar[er-(r-sr)][sc])
    
        print " ".join([str(a) for a in top + right + bottom + left]),
    
        # peel next layer of onion
        print_spiral(ar, sr+1, sc+1, er-1, ec-1)
    

最後にこれを行うための小さなスニペットがありますが、効率的ではありませんが楽しいです:)、基本的に一番上の行を印刷し、長方形全体を反時計回りに回転して繰り返します

def print_spiral(ar):
    if not ar: return
    print " ".join(str(a) for a in ar[0]),
    ar = Zip(*[ reversed(row) for row in ar[1:]])
    print_spiral(ar)
8
Anurag Uniyal

このプログラムは、任意のn * n行列に対して機能します。

public class circ {
    public void get_circ_arr (int n,int [][] a)
    {
        int z=n;
        {
            for (int i=0;i<n;i++)
            {
                for (int l=z-1-i;l>=i;l--)
                {
                    int k=i;
                    System.out.printf("%d",a[k][l]);
                }           

                for (int j=i+1;j<=z-1-i;j++)
                {
                    int k=i;
                    {
                        System.out.printf("%d",a[j][k]);
                    }
                }

                for (int j=i+1;j<=z-i-1;j++)
                {
                    int k=z-1-i;
                    {
                        System.out.printf("%d",a[k][j]);
                    }
                }

                for (int j=z-2-i;j>=i+1;j--)
                {
                    int k=z-i-1;        
                    {
                        System.out.printf("%d",a[j][k]);
                    }
                }
            }
        }
    }
}

それが役に立てば幸い

6
Surendran

Rubyを学んでいたとき、この問題に夢中になりました。これは私ができる最善のことでした:

def spiral(matrix)
  matrix.empty? ? [] : matrix.shift + spiral(matrix.transpose.reverse)
end

この Gist のリビジョンをステップバックして、他のソリューションのいくつかをチェックアウトできます。また、私が要点を分岐したリンクに戻ると、他の巧妙な解決策を見つけることができます。複数のエレガントな方法、特にRubyで解決できる本当に興味深い問題。

5
O-I

JavaScriptソリューション:

var printSpiral = function (matrix) {
  var i;
  var top = 0;
  var left = 0;
  var bottom = matrix.length;
  var right = matrix[0].length;

  while (top < bottom && left < right) {

    //print top 
    for (i = left; i < right; i += 1) {
      console.log(matrix[top][i]);
    }
    top++;

    //print right column
    for (i = top; i < bottom; i += 1) {
      console.log(matrix[i][right - 1]);
    }
    right--;

    if (top < bottom) {
      //print bottom
      for (i = right - 1; i >= left; i -= 1) {
        console.log(matrix[bottom - 1][i]);
      }
      bottom--;
    }

    if (left < right) {
      //print left column
      for (i = bottom - 1; i >= top; i -= 1) {
        console.log(matrix[i][left]);
      }
      left++;
    }
  }
};
3
spark

シンプルに保つ->

public class spiralMatrix {

public static void printMatrix(int[][] matrix, int rows, int col)
{
    int rowStart=0;
    int rowEnd=rows-1;
    int colStart=0;
    int colEnd=col-1;

    while(colStart<=colEnd && rowStart<=rowEnd)
    {
        for(int i=colStart;i<colEnd;i++)
            System.out.println(matrix[rowStart][i]);

        for(int i=rowStart;i<rowEnd;i++)
            System.out.println(matrix[i][colEnd]);

        for(int i=colEnd;i>colStart;i--)
            System.out.println(matrix[rowEnd][i]);

        for(int i=rowEnd;i>rowStart;i--)
            System.out.println(matrix[i][colStart]);
        rowStart++;
        colEnd--;
        rowEnd--;
        colStart++;

    }

}
public static void main(String[] args){

    int[][] array={{1,2,3,4},{5,6,7,8}};
    printMatrix(array,2,4);
}

}

2
piyush121

2次元N * Nマトリックスは正方マトリックス

アイディア:

らせん状に移動するには、4つの異なる方向に移動する必要があります。スパイラルの1つの層が終了したら、マトリックス内を移動する必要があります。合計で、5つのループ、スパイラルのように通過する4つのループ、およびレイヤーを通過する1つのループが必要です。

public void printSpiralForm(int[][] a, int length)
{

  for( int i = 0 , j = length-1 ; i < j ; i++ , j-- )
  {

    for( int k = i ; k < j ; k++ )
    {
      System.out.print( a[i][k] + " " ) ;
    }

    for( int k = i ; k < j ; k++ )
    {
      System.out.print(a[k][j] + " ");
    }

    for( int k = j ; k > i ; k-- )
    {
      System.out.print(a[j][k] + " ") ;
    }

    for( int k = j ; k > i ; k-- )
    {
      System.out.print( a[k][i] + " " ) ;
    }

  }

  if ( length % 2 == 1 )
  {
    System.out.println( a[ length/2 ][ length/2 ] ) ;
  }

}
2
Billz

文字のマトリックスが指定されている場合、すべての文字を次の順序で印刷するメソッドを実装します。最初に外側の円、次に次の円というように。

public static void printMatrixInSpiral(int[][] mat){

    if(mat.length == 0|| mat[0].length == 0){
        /* empty matrix */
        return;
    }

    StringBuffer str = new StringBuffer();
    int counter = mat.length * mat[0].length;
    int startRow = 0;
    int endRow = mat.length-1;
    int startCol = 0;
    int endCol = mat[0].length-1;
    boolean moveCol = true;
    boolean leftToRight = true;
    boolean upDown = true;

    while(counter>0){

        if(moveCol){

            if(leftToRight){

                /* printing entire row left to right */                 
                for(int i = startCol; i <= endCol ; i++){                       
                    str.append(mat[startRow][i]);
                    counter--;
                }
                leftToRight = false;
                moveCol = false;
                startRow++;
            }
            else{

                /* printing entire row right to left */
                for(int i = endCol ; i >= startCol ; i--){
                    str.append(mat[endRow][i]);
                    counter--;
                }
                leftToRight = true;
                moveCol = false;
                endRow--;       
            }
        }
        else
        {
            if(upDown){                 

                /* printing column up down */
                for(int i = startRow ; i <= endRow ; i++){                      
                    str.append(mat[i][endCol]);
                    counter--;
                }
                upDown = false;
                moveCol = true;
                endCol--;
            }
            else
            {

                /* printing entire col down up */
                for(int i = endRow ; i >= startRow ; i--){
                    str.append(mat[i][startCol]);
                    counter--;
                }
                upDown = true;
                moveCol = true;
                startCol++;
            }
        }
    }
    System.out.println(str.toString());
}
2
Maya Raveh

1つの解決策には、右、左、上、下の方向、および対応する制限(インデックス)が含まれます。最初の行が印刷され、方向が(右から)下に変わると、行は上限を増やして破棄されます。最後の列が印刷され、方向が左に変わると、列は右側の制限をデクリメントして破棄されます...詳細は自明のCコードで確認できます。

#include <stdio.h>
#define N_ROWS 5
#define N_COLS 3

void print_spiral(int a[N_ROWS][N_COLS])
{
    enum {up, down, left, right} direction = right;
    int up_limit = 0,
        down_limit = N_ROWS - 1,
        left_limit = 0,
        right_limit = N_COLS - 1,
        downcount = N_ROWS * N_COLS,
        row = 0,
        col = 0;

    while(printf("%d ", a[row][col]) && --downcount)
        if(direction == right)
        {
            if(++col > right_limit)
            {
                --col;
                direction = down;
                ++up_limit;
                ++row;
            }
        }
        else if(direction == down)
        {
            if(++row > down_limit)
            {
                --row;
                direction = left;
                --right_limit;
                --col;
            }
        }
        else if(direction == left)
        {
            if(--col < left_limit)
            {
                ++col;
                direction = up;
                --down_limit;
                --row;
            }
        }
        else /* direction == up */
            if(--row < up_limit)
            {
                ++row;
                direction = right;
                ++left_limit;
                ++col;
            }
}

void main()
{
    int a[N_ROWS][N_COLS] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
    print_spiral(a);
}

テストとダウンロードのリンク

2
Apshir

これは私の実装です:

public static void printMatrix(int matrix[][], int M, int N){
    int level = 0;
    int min = (M < N) ? M:N;
    System.out.println();
    while(level <= min/2){
        for(int j = level; j < N - level - 1; j++){
            System.out.print(matrix[level][j] + "\t");
        }
        for(int i = level; i < M - level - 1; i++) {
            System.out.print(matrix[i][N - level - 1] + "\t");
        }
        for(int j = N - level - 1; j > level; j--){
            System.out.print(matrix[M - level - 1][j] + "\t");
        }
        for(int i = M - level - 1; i > level; i-- ){
            System.out.print(matrix[i][level] + "\t");
        }
        level++;
    }
}
1
WonderLi

複雑さ:シングルトラバースO(n)

シングルループ複雑さO(n)の回答を追加してください。私は、マトリックスの左右および左右のトラバース中に、行優先インデックスでそれぞれ1つずつ増減することを観察しました。同様に、上下および上下のトラバースでは、n_cols。したがって、そのためのアルゴリズムを作成しました。たとえば、行優先インデックスのエントリを持つ(3x5)マトリックスを指定すると、印刷出力は次のようになります。1,2,3,4,5,10,15,14,13,12,11,6,7,8,9

             ------->(+1)
          ^ 1  2  3  4  5   |
(+n_cols) | 6  7  8  9  10  | (-n_cols)
          | 11 12 13 14 15  
            (-1)<-------

コードソリューション:

#include <iostream>
using namespace std;

int main() {
    // your code goes here

    bool leftToRight=true, topToBottom=false, rightToLeft=false, bottomToTop=false;
    int idx=0;
    int n_rows = 3;
    int n_cols = 5;
    int cnt_h = n_cols, cnt_v = n_rows, cnt=0;
    int iter=1;
    for (int i=0; i <= n_rows*n_cols + (n_rows - 1)*(n_cols - 1)/2; i++){

        iter++; 
        if(leftToRight){
            if(cnt >= cnt_h){ 
                cnt_h--; cnt=0;
                leftToRight = false; topToBottom = true; 
                //cout  << "Iter: "<< iter << " break_leftToRight"<<endl;
            }else{
                cnt++;
                idx++;
                //cout << "Iter: "<< iter <<" idx: " << idx << " cnt: "<< cnt << " cnt_h: "<< cnt_h<< endl;
                cout<< idx << endl;
            }
        }else if(topToBottom){
            if(cnt >= cnt_v-1){
                cnt_v--; cnt=0;  
                leftToRight = false; topToBottom = false; rightToLeft=true;
                //cout  << "Iter: "<< iter  << " break_topToBottom"<<endl;
            }else{
                cnt++;
                idx+=n_cols;
                //cout  << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_v: "<< cnt_h<< endl;
                cout << idx <<endl;
            }
        }else if(rightToLeft){
            if(cnt >= cnt_h){
                cnt_h--; cnt=0; 
                leftToRight = false; topToBottom = false; rightToLeft=false; bottomToTop=true;
                //cout  << "Iter: "<< iter  << " break_rightToLeft"<<endl;
                //cout<< idx << endl;
            }else{
                cnt++;
                idx--;
                //cout  << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_h: "<< cnt_h<< endl;
                cout << idx <<endl;
            }
        }else if(bottomToTop){
            if(cnt >= cnt_v-1){
                cnt_v--; cnt=0;
                leftToRight = true; topToBottom = false; rightToLeft=false; bottomToTop=false;
                //cout  << "Iter: "<< iter << " break_bottomToTop"<<endl;
            }else{
                cnt++;
                idx-=n_cols;
                //cout  << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_v: "<< cnt_h<< endl;
                cout<< idx << endl;
            }
        }

        //cout << i << endl;
    }


    return 0;
}
1
Darkmoor

一番上の行をスラッシュ->転置->反転->繰り返し。

void slashTransposeFlip(int[][] m){

    if( m.length * m[0].length == 1){ //only one element left
        System.out.print(m[0][0]);
    }else{
        //print the top row
        for(int a:m[0]){System.out.print(a+" ");}

        //slash the top row from the matrix.
        int[][] n = Arrays.copyOfRange(m,1,m.length);

        int[][] temp = n;
        int rows = temp.length;
        int columns = temp[0].length;

        //invert rows and columns and create new array
        n = new int[columns][rows];

        //transpose
        for(int x=0;x<rows;x++)
            for(int y=0;y<columns;y++)
                n[y][x] = temp[x][y];

        //flipping time
        for (int i = 0; i < n.length / 2; i++) {
          int[] t = n[i];
          n[i] = n[n.length - 1 - i];
          n[n.length - 1 - i] = t;
        }

        //recursively call again the reduced matrix.
        slashTransposeFlip(n);
    }
}
1
Sorter

int N = Integer.parseInt(args [0]);

    // create N-by-N array of integers 1 through N
    int[][] a = new int[N][N];
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            a[i][j] = 1 + N*i + j;

    // spiral
    for (int i = N-1, j = 0; i > 0; i--, j++) {
          for (int k = j; k < i; k++) System.out.println(a[j][k]);
          for (int k = j; k < i; k++) System.out.println(a[k][i]);
          for (int k = i; k > j; k--) System.out.println(a[i][k]);
          for (int k = i; k > j; k--) System.out.println(a[k][j]);
   }

   // special case for middle element if N is odd
   if (N % 2 == 1) System.out.println(a[(N-1)/2][(N-1)/2]);
}

}

Python3で問題を解決しました。ほとんどすべてのEdgeケースを通過しています。

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
Shagun Pruthi

この質問はこれに関連しています: PHPでのマトリックス配置の問題

提示された答えはうまくいくように見えますが、理解するのは複雑です。これを解決する非常に簡単な方法は、分割して征服することです。つまり、Edgeを読み取った後、それを削除すると、次の読み取りがはるかに簡単になります。 PHP以下の完全なソリューションをご覧ください。

#The source number matrix
$source[0] = array(1, 2, 3, 4);
$source[1] = array(5, 6, 7, 8);
$source[2] = array(9, 10, 11, 12);
$source[3] = array(13, 14, 15, 16);
$source[4] = array(17, 18, 19, 20);

#Get the spiralled numbers
$final_spiral_list = get_spiral_form($source);
print_r($final_spiral_list);


function get_spiral_form($matrix)
{
    #Array to hold the final number list
    $spiralList = array();

    $result = $matrix;
    while(count($result) > 0)
    {
        $resultsFromRead = get_next_number_circle($result, $spiralList);
        $result = $resultsFromRead['new_source'];
        $spiralList = $resultsFromRead['read_list'];
    }

    return $spiralList;
}


function get_next_number_circle($matrix, $read)
{
    $unreadMatrix = $matrix;

    $rowNumber = count($matrix);
    $colNumber = count($matrix[0]);

    #Check if the array has one row or column
    if($rowNumber == 1) $read = array_merge($read, $matrix[0]);
    if($colNumber == 1) for($i=0; $i<$rowNumber; $i++) array_Push($read, $matrix[$i][0]);
    #Check if array has 2 rows or columns
    if($rowNumber == 2 || ($rowNumber == 2 && $colNumber == 2)) 
    {
        $read = array_merge($read, $matrix[0], array_reverse($matrix[1]));
    }

    if($colNumber == 2 && $rowNumber != 2) 
    {
        #First read left to right for the first row
        $read = array_merge($read, $matrix[0]);
        #Then read down on right column
        for($i=1; $i<$rowNumber; $i++) array_Push($read, $matrix[$i][1]);
        #..and up on left column
        for($i=($rowNumber-1); $i>0; $i--) array_Push($read, $matrix[$i][0]);
    }



    #If more than 2 rows or columns, pick up all the Edge values by spiraling around the matrix
    if($rowNumber > 2 && $colNumber > 2)
    {
        #Move left to right
        for($i=0; $i<$colNumber; $i++) array_Push($read, $matrix[0][$i]);
        #Move top to bottom
        for($i=1; $i<$rowNumber; $i++) array_Push($read, $matrix[$i][$colNumber-1]);
        #Move right to left
        for($i=($colNumber-2); $i>-1; $i--) array_Push($read, $matrix[$rowNumber-1][$i]);
        #Move bottom to top
        for($i=($rowNumber-2); $i>0; $i--) array_Push($read, $matrix[$i][0]);
    }

    #Now remove these Edge read values to create a new reduced matrix for the next read
    $unreadMatrix = remove_top_row($unreadMatrix);  

    $unreadMatrix = remove_right_column($unreadMatrix); 
    $unreadMatrix = remove_bottom_row($unreadMatrix);   
    $unreadMatrix = remove_left_column($unreadMatrix);  

    return array('new_source'=>$unreadMatrix, 'read_list'=>$read);
}


function remove_top_row($matrix)
{
    $removedRow = array_shift($matrix);
    return $matrix;
}

function remove_right_column($matrix)
{
    $neededCols = count($matrix[0]) - 1;
    $finalMatrix = array();
    for($i=0; $i<count($matrix); $i++) $finalMatrix[$i] = array_slice($matrix[$i], 0, $neededCols);
    return $finalMatrix;
}

function remove_bottom_row($matrix)
{
    unset($matrix[count($matrix)-1]);
    return $matrix;
}

function remove_left_column($matrix)
{
    $neededCols = count($matrix[0]) - 1;
    $finalMatrix = array();
    for($i=0; $i<count($matrix); $i++) $finalMatrix[$i] = array_slice($matrix[$i], 1, $neededCols);
    return $finalMatrix;
}
0
Al Zziwa
function spiral(a) {
  var s = [];
  while (a.length) {
    // concat 1st row, Push last cols, rotate 180 (reverse inner/outer)...
    s = s.concat(a.shift());
    a = a
      .map(function(v) {
        s.Push(v.pop());
        return v.reverse();
      })
      .reverse();
  }
  return s;
}
var arr = [
  [1, 2, 3, 4], 
  [12, 13, 14, 5], 
  [11, 16, 15, 6], 
  [10, 9, 8, 7]
];
console.log(spiral(arr));// -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
arr = [
  [0, 1, 2, 3, 4],
  [15, 16, 17, 18, 5],
  [14, 23, 24, 19, 6],
  [13, 22, 21, 20, 7],
  [12, 11, 10, 9, 8]
];
console.log(spiral(arr));// -> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
0
Rick Edwards

これは私が考えることができる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
whizvids

これが私の解決策です。私が間違っている場合は修正してください。

class Spiral:

def spiralOrder(self, A):
    result = []
    c = []
    c.append(A[0])
    b = A[1:]
    while len(b) > 0:
        b = self.rotate(b)
        c.append(b[0])
        b = b[1:]
    for item in c:
        for fitem in item:
            print fitem,
            result.append(fitem)
    return result

def rotate(self,a):
    b = []
    l = Zip(*a)
    for i in xrange(len(l)-1,-1,-1):
        b.append(list(l[i]))
    return b

if __== '__main__':
  a = [[1, 2, 3,3], [4, 5, 6,6], [7, 8, 9,10]]
  s = Spiral()
s.spiralOrder(a)
0
Ketan

2-Dマトリックスを印刷するには、マトリックスを長方形および/または小さな長方形が大きな長方形に収まる線の構成と見なし、各レイヤーで左上の要素から開始する長方形を形成するマトリックスの境界を取ります;一度これを行うと、小さな長方形の次のレイヤーに進みます。長方形がない場合は、印刷する線、水平または垂直にする必要があります。サンプルマトリックスHTHを使用してコードを貼り付けました。

#include <stdio.h>

int a[2][4] = { 1, 2 ,3, 44,
                8, 9 ,4, 55 };

void print(int, int, int, int);

int main() {

int row1, col1, row2, col2;

row1=0;
col1=0;
row2=1;
col2=3;


while(row2>=row1 && col2>=col1)
{
    print(row1, col1, row2, col2);

    row1++;
    col1++;
    row2--;
    col2--;
}

return 0;
}


void print(int row1, int col1, int row2, int col2) {

int i=row1;
int j=col1;

/* This is when single horizontal line needs to be printed */
if( row1==row2 && col1!=col2) {
    for(j=col1; j<=col2; j++)
        printf("%d ", a[i][j]);
    return;
}

/* This is when single vertical line needs to be printed */
if( col1==col2 && row1!=row2) {
    for(i=row1; j<=row2; i++)
        printf("%d ", a[i][j]);
    return;
}


/* This is reached when there is a rectangle to be printed */

for(j=col1; j<=col2; j++)
    printf("%d ", a[i][j]);

for(j=col2,i=row1+1; i<=row2; i++)
    printf("%d ", a[i][j]);

for(i=row2,j=col2-1; j>=col1; j--)
    printf("%d ", a[i][j]);

for(j=col1,i=row2-1; i>row1; i--)
    printf("%d ", a[i][j]);

}
0
Cleonjoys

らせんは、水平および垂直セグメントの順序付けられたセットで構成されていると想像できます。 次の各水平セグメントは前の水平セグメントよりも1つの要素が短く、次の各垂直セグメントは前の垂直セグメントよりも1つの要素が短いであることがわかります。各次のセグメントは、前のセグメントが終了するセルに隣接するセルで始まります。時計回りにらせんを構成すると仮定します。最初の水平セグメントの長さは、特定のマトリックスの列数に等しくなります。最初の垂直セグメントの長さは、指定されたマトリックスの行数から1を引いたものに等しくなります。これらの観測を使用すると、追加のメモリやO(NxM)実行時間の再帰なしに、NxM行列を走査できます。

public static void VisitBySpiral<T>(T[,] matrix, Action<T> onVisit)
{
    var spiralWidth = matrix.GetLength(1);
    var spiralHeight = matrix.GetLength(0);
    var row = 0;
    var column = 0;
    var step = +1;
    while (spiralWidth > 0 && spiralHeight > 0)
    {
        var horizontalSteps = spiralWidth;
        while (horizontalSteps-- > 0)
        {
            onVisit(matrix[row, column]);
            if (horizontalSteps > 0)
            {
                column += step;
            }
        }
        // Move to the cell where next vertical segment starts.
        row += step;
        --spiralHeight;

        var verticalSteps = spiralHeight;
        while (verticalSteps-- > 0)
        {
            onVisit(matrix[row, column]);
            if (verticalSteps > 0)
            {
                row += step;
            }
        }
        --spiralWidth;
        step *= -1;
        // Move to the cell where next horizontal segment starts.
        column += step;
    }
}
0
Leonid Vasilev

これはJava任意のm x n行列の実装です。ここで、rows =行数およびColumn =列数

public static void printSpiral(int rows, int columns, int a[][])
    {
        int i, k = 0, l = 0;

        /*  k - starting row index
            l - starting column index
        */

        while (k < rows && l < columns)
        {
            /* Print the first row from the remaining rows */
            for (i = l; i < columns; ++i)
            {
                System.out.println(a[k][i]);
            }
            k++;

            /* Print the last column from the remaining columns */
            for (i = k; i < rows; ++i)
            {
                System.out.println(a[i][columns-1]);
            }
            columns--;

            /* Print the last row from the remaining rows */
            if ( k < rows)
            {
                for (i = columns-1; i >= l; --i)
                {
                    System.out.println(a[rows-1][i]);
                }
                rows--;
            }

            /* Print the first column from the remaining columns */
            if (l < columns)
            {
                for (i = rows-1; i >= k; --i)
                {
                    System.out.println(a[i][l]);
                }
                l++;    
            }        
        }
    }
0
anand mishra
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
atjoshi

Iteratorを使用した私のアプローチを次に示します。これはほぼ同じ問題を解決することに注意してください。ここに完全なコードがあります: 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
RD.

誰かが興味があるなら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);
    }
  }
}
0
sadakurapati

http://www.technicalinterviewquestions.net/2009/03/print-2d-array-matrix-spiral-order.html

ここに上記の答えの最良の説明があります:)ダイアグラムとともに:)

0
Priyanka

関連するテストケースを含むC#の作業コード。 n x mマトリックス。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MatrixSpiralPrint
{
    class Matrix
    {
        int[,] mat;
        public Matrix(int[,] matrix)
        {
            mat = matrix;
        }
        void printHelper(int x)
        {
            Console.Write(string.Format("{0} ", x));
        }
        // print the top right of the matrix and 
        // recursively call the print bottom left on the submatrix.
        void printTopRight(int colStart, int rowStart, int colEnd, int rowEnd)
        {
            int i = 0, j = 0;

            // print Top row.
            for (i = colStart; i <= colEnd; i++)
            {
                printHelper(mat[rowStart, i]);
            }

            // print Right column.
            for (j = rowStart + 1; j <= rowEnd; j++)
            {
                printHelper(mat[j, colEnd]);
            }

            // Recursion base case: see if more layers need to be printed.
            if (colEnd - colStart > 0 && rowStart!=rowEnd)
            {
                // print the bottom left of the sub matrix.
                printBottomLeft(colStart, rowStart + 1, colEnd - 1, rowEnd);
            }
        }

        // print the bottom left peel of the matrix and 
        // recursively call the print top right on the submatrix.
        void printBottomLeft(int colStart, int rowStart, int colEnd, int rowEnd)
        {
            int i = 0, j = 0;

            // print Bottom row in reverse order.
            for (i = colEnd; i >= colStart; i--)
            {
                printHelper(mat[rowEnd, i]);
            }

            // print Left column in reverse order.
            for (j = rowEnd - 1; j >= rowStart; j--)
            {
                printHelper(mat[j, colStart]);
            }

            // Recursion base case: see if more layers need to be printed.
            if (colEnd - colStart > 0)
            {
                // print the top right of the sub matrix.
                printTopRight(colStart + 1, rowStart, colEnd, rowEnd - 1);
            }
        }

        void printMatrix()
        {
            int rowLength = mat.GetLength(0);
            int colLength = mat.GetLength(1);
            Console.WriteLine("Test Case");
            for (int i = 0; i < rowLength; i++)
            {
                for (int j = 0; j < colLength; j++)
                {
                    Console.Write(string.Format("{0} ", mat[i, j]));
                }
                Console.Write(Environment.NewLine + Environment.NewLine);
            }

        }
        public void printSpiral()
        {
            var maxRowIndex = mat.GetUpperBound(0);
            var maxColIndex = mat.GetUpperBound(1);
            printMatrix();
            Console.WriteLine("Spiral Print");
            printTopRight(0, 0, maxColIndex, maxRowIndex);
            Console.WriteLine("\n---------------------------------");
        }

    } 
    class Program
    {

        static void Main(string[] args)
        {
            var matrix = new int[,] {
                { 1,2,3,4,5},
                { 6,7,8,9,10},
                { 11,12,13,14,15},
                { 16,17,18,19,20},
                { 21,22,23,24,25}
            };
            var mat = new Matrix(matrix);
            mat.printSpiral();

            matrix = new int[,] {
                { 1,2,3,4},
                { 5,6,7,8},
                { 9,10,11,12}
            };
            mat = new Matrix(matrix);
            mat.printSpiral();

            matrix = new int[,] {
                { 1,2,3},
                { 4,5,6},
                { 7,8,9},
                { 10,11,12},
            };
            mat = new Matrix(matrix);
            mat.printSpiral();

            matrix = new int[,] {
                { 1,2 }
            };
            mat = new Matrix(matrix);
            mat.printSpiral();

            matrix = new int[,] {
                { 1},
                { 2}
            };
            mat = new Matrix(matrix);
            mat.printSpiral();
        }
    }
}

承認された回答はどのn x mマトリックス。このコードは、受け入れられた回答で@codaddictによって投稿されたコードを使用してC#に移植されます。再帰ベースケースを修正しました。

0
Abdul Rauf

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
MattMacdonald

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
bantini
//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
Shivendra
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--;
    }

}
0
// Program to print a matrix in spiral order

#include <stdio.h>
int main(void) {
    // your code goes here
    int m,n,i,j,k=1,c1,c2,r1,r2;;
    scanf("%d %d",&m,&n);
    int a[m][n];
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    r1=0;
    r2=m-1;
    c1=0;
    c2=n-1;

    while(k<=m*n)
                {
                    for(i=c1;i<=c2;i++)
                    {
                        k++;
                        printf("%d ",a[r1][i]);
                    }

                    for(j=r1+1;j<=r2;j++)
                    {
                        k++;
                        printf("%d ",a[j][c2]);
                    }

                    for(i=c2-1;i>=c1;i--)
                    {
                        k++;
                        printf("%d ",a[r2][i]);
                    }

                    for(j=r2-1;j>=r1+1;j--)
                    {
                        k++;
                        printf("%d ",a[j][c1]);
                    }

                 c1++;
                 c2--;
                 r1++;
                 r2--;
                }
    return 0;
}
0
user3719609
#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;
}
0
Naeem Ul Hassan

行x列が指定された2D配列行列の完全な純粋なCプログラム。

#include <stdio.h>
void  printspiral(int *p,int r, int c) {    
    int i=0,j=0,m=1,n=0;
    static int firstrun=1,gCol;
    if (!p||r<=0||c<=0)
        return ;
    if(firstrun) {
        gCol=c;
        firstrun=0;
    }
    for(i=0,j=0;(0<=i && i<c)&&(0<=j && j<r);i+=m,j+=n) {                                                                               
        printf(" %d",p[i+j*gCol]);                                                                                                      
        if (i==0 && j==1 && (i+1)!=c) break;                                                                                            
        else if (i+1==c && !j) {m=0;n=1;}                                                                                               
        else if (i+1==c && j+1==r && j) {n=0;m=-1;}                                                                                     
        else if (i==0 && j+1==r && j) {m=0;n=-1;}                                                                                       
    }                                                                                                                                   
    printspiral(&p[i+j*gCol+1],r-2,c-2);                                                                                                
    firstrun=1;                                                                                                                         
    printf("\n");                                                                                                                       
}                                                                                                                                       
int main() {                                                                                                                            
    int a[3][3]={{0,1,2},{3,4,5},{6,7,8}};                                                                                              
    int b[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};                                                                                      
    int c[4][3]={{0,1,2},{3,4,5},{6,7,8},{9,10,11}};                                                                                    
    int d[3][1]={{0},{1},{2}};                                                                                                          
    int e[1][3]={{0,1,2}};                                                                                                              
    int f[1][1]={{0}};                                                                                                                  
    int g[5][5]={{0,1,2,3,4},{5,6,7,8,9},{10,11,12,13,14},{15,16,17,18,19},{20,21,22,23,24}};
    printspiral(a,3,3);                                                                                                                 
    printspiral(b,3,4);                                                                                                                 
    printspiral(c,4,3);                                                                                                                 
    printspiral(d,3,1);                                                                                                                 
    printspiral(e,1,3);                                                                                                                 
    printspiral(f,1,1);                                                                                                                 
    printspiral(g,5,5);
    return 0;                                                                                                                           
}
0
Balamurugan A