나선형 순서로 2 차원 배열 인쇄
5x5 2 차원 배열을 나선형 순서로 어떻게 인쇄합니까?
나선형 순서로 모든 크기의 배열을 인쇄 할 수있는 공식이 있습니까?
아이디어는 행렬을 일련의 레이어, 오른쪽 상단 레이어 및 왼쪽 하단 레이어로 취급하는 것입니다. 매트릭스를 나선형으로 인쇄하기 위해이 매트릭스에서 레이어를 벗겨 내고 벗겨진 부분을 인쇄 한 다음 남은 부분의 인쇄물을 재귀 적으로 호출 할 수 있습니다. 재귀는 인쇄 할 레이어가 더 이상 없을 때 종료됩니다.
입력 매트릭스 :
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");
}
- 상단 행 팝
- 조옮김 및 거꾸로 뒤집기 (시계 반대 방향으로 90도 회전과 동일)
- 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)))
나는 아무도 사용이없는 것을 볼 하나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 # 그리고 다음과 같은 그리드의 경우 : OOOOOOO OOOOOOO OOOOOOO OOOOOOO OOOOOOO 우리는 다음과 같은 표시를합니다. OOOOOO # # OOOO # O O # OO # OO O # OOO # O # OOOOO #
포인트는 왼쪽 상단 부분에하지 않는 한 우리는 징후는 점에서 장소, 즉 볼 수 가장 가까운 수평 경계까지의 거리와 가장 가까운 수직 경계가 동일는 반면, 왼쪽 상단 부분, 까지의 거리 상단 테두리는 왼쪽 테두리까지의 거리보다 하나 더 많으며, 지점이 수평 중앙에있는 경우 오른쪽 상단에 우선 순위가 부여되고 지점이 수직 중앙에있을 경우 왼쪽 상단에 우선 순위가 부여됩니다.
이것은 (최소 취함으로써, 아주 쉽게 간단한 함수에서 실현 될 수 curRow
와 height-1-curRow
의), 다음 최소 ( curCol
와 width-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);
}
출력되는 내용 :
12 34 8 12 16 15 14 1314 5678 11 10 12 34 8 12 11 10 9 5 6 7
세 가지 흥미로운 방법이 있습니다.
나선형으로 읽는 것은 경계를 향해 움직이고 경계 또는 그 자체에 부딪히는 뱀처럼 취급 될 수 있습니다 (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
재귀 적 접근 방식은 외부 레이어를 인쇄하고 내부 사각형에 대해 동일한 함수를 호출하는 것입니다.
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)
이 프로그램은 모든 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]);
}
}
}
}
}
}
도움이되기를 바랍니다.
루비를 배울 때이 문제에 집착했습니다. 이것이 제가 할 수있는 최선이었습니다.
def spiral(matrix)
matrix.empty? ? [] : matrix.shift + spiral(matrix.transpose.reverse)
end
이 요점 의 개정판을 통해 뒤로 물러나 내 다른 솔루션 중 일부를 확인할 수 있습니다 . 또한 내가 요점을 포크 한 링크를 따라 가면 다른 영리한 솔루션을 찾을 수 있습니다. 여러 가지 우아한 방법, 특히 Ruby에서 해결할 수있는 정말 흥미로운 문제입니다.
자바 스크립트 솔루션 :
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++;
}
}
};
한 가지 솔루션에는 오른쪽, 왼쪽, 위, 아래 방향 및 해당 제한 (인덱스)이 포함됩니다. 첫 번째 행이 인쇄되고 방향이 오른쪽에서 아래로 변경되면 상한을 증가시켜 행이 삭제됩니다. 마지막 열이 인쇄되고 방향이 왼쪽으로 변경되면 오른쪽 한계를 줄여 열이 삭제됩니다. 자세한 내용은 자명 한 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);
}
테스트 및 다운로드 링크
.문자 행렬이 주어지면 모든 문자를 먼저 바깥 쪽 원, 다음 원 순으로 인쇄하는 메서드를 구현합니다.
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());
}
생각:
나선형처럼 횡단하려면 4 개의 다른 방향으로 횡단해야합니다. 나선형의 한 층이 끝나면 매트릭스 내부를 횡단해야합니다. 따라서 총 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 ] ) ;
}
}
간단하게->
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);
}
}
이것은 내 구현입니다.
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++;
}
}
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]);
}
}
Slash Top Row-> Transpose-> Flip-> Repeat.
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);
}
}
복잡성 : 단일 트래버스
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;
}
2D 매트릭스를 인쇄하려면 매트릭스를 직사각형 및 / 또는 작은 직사각형이 큰 직사각형에 맞춰지는 선의 구성으로 간주하고 각 레이어에서 매번 왼쪽 위 요소부터 시작하여 인쇄 할 직사각형을 형성하는 매트릭스의 경계를 선택합니다. ; 일단 이것으로 끝나면 더 작은 직사각형의 다음 레이어로 들어가십시오. 사각형이없는 경우 가로 또는 세로로 인쇄 할 선이어야합니다. 예제 매트릭스 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]);
}
다음은 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*/
}
}
//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);
}
누구든지 관심이 있다면 자바 코드.
입력 :
4
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7
출력 : 1 2 3 4 8 3 4 5 6 7 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);
}
}
}
이것은 내가 생각할 수있는 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);
}
http://www.technicalinterviewquestions.net/2009/03/print-2d-array-matrix-spiral-order.html
위의 답변에 대한 가장 좋은 설명은 다음과 같습니다. :) 다이어그램과 함께 :)
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--;
}
}
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;
}
}
다음은 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();
}
}
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();
}
}
}
주어진 행 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;
}
이 질문은 이것과 관련이 있습니다 : PHP의 매트릭스 배열 문제
제시된 답변은 작동하는 것처럼 보이지만 이해하기 복잡합니다. 이 문제를 해결하는 매우 간단한 방법은 나누고 정복하는 것입니다. 즉, 가장자리를 읽은 후 제거하면 다음 읽기가 훨씬 간단 해집니다. 아래의 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;
}
// 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;
}
이것은 모든 mxn 매트릭스에 대한 Java 구현입니다. 행 = 행 수, 열 = 열 수
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++;
}
}
}
여기 내 해결책이 있습니다. 내가 틀렸다면 수정하십시오.
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 __name__ == '__main__':
a = [[1, 2, 3,3], [4, 5, 6,6], [7, 8, 9,10]]
s = Spiral()
s.spiralOrder(a)
참조 URL : https://stackoverflow.com/questions/726756/print-two-dimensional-array-in-spiral-order
'development' 카테고리의 다른 글
Cordova / ionic 명령 줄에서 ios 에뮬레이터를 선택하는 방법 (0) | 2020.12.26 |
---|---|
Eclipse 오류 :이 프로젝트는 WTP 메타 데이터를 마이그레이션해야합니다. (0) | 2020.12.26 |
Java를 사용하여 zip 파일에 파일 추가 (0) | 2020.12.26 |
Java에서 jar에서 파일을 읽는 방법은 무엇입니까? (0) | 2020.12.26 |
성공적인 비동기 redux 작업시 다른 경로로 전환 (0) | 2020.12.25 |