Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 프로그래밍으로 행렬을 지그재그(Zig-Zag) 방식으로 출력하는 방법

지그재그(Zig-Zag) 방식의 행렬 출력이란?

행렬 mat[row][col]이 주어졌을 때, 아래 이미지처럼 지그재그 형태로 행렬의 모든 요소를 순서대로 출력해야 합니다. 지그재그 순회란 왼쪽 상단에서 출발하여 대각선을 따라 이동하다가 행렬의 경계에 도달할 때마다 방향을 바꾸어 나가는 방식을 말합니다.

C 프로그래밍으로 행렬을 지그재그(Zig-Zag) 방식으로 출력하는 방법

따라서 위 행렬에 대한 출력 결과는 다음과 같습니다.

Output: 10 20 40 70 50 30 60 80 90

문제 해결 접근 방식

이 문제는 비교적 단순한 접근 방식으로 해결할 수 있습니다. 핵심 아이디어는 다음과 같습니다.

  • 행렬을 대각선(diagonal) 단위로 순회합니다.
  • 하나의 대각선 순회가 끝날 때마다 이동 방향을 전환합니다.
  • boolean 타입의 flag 변수를 사용하여 현재 진행 방향(오른쪽 위 또는 왼쪽 아래)을 추적합니다.

알고리즘

START
STEP 1 -> k = 3, l = 3 선언 및 초기화
STEP 2 -> 행렬 mat[][3] 선언
STEP 3 -> row = 0, col = 0, flag = false 선언 및 초기화
STEP 4 -> mn = MINIMUM(k, l) 설정
STEP 5 -> FOR len = 1 TO len <= mn, ++len 반복
    FOR i = 0 TO i < len, ++i 반복
        mat[row][col] 출력
        IF i + 1 == len THEN
            BREAK
        END IF
        IF flag THEN
            row 1 증가, col 1 감소
        ELSE
            row 1 감소, col 1 증가
        END IF
    END FOR
    IF len == mn THEN
        BREAK
    END IF
    IF flag THEN
        row 1 증가, flag = FALSE
    ELSE
        col 1 증가, flag = TRUE
    END IF
END FOR
STEP 6 -> IF row == 0 THEN
    IF col == k - 1 THEN
        row 1 증가
    ELSE
        col 1 증가
    END IF
    flag = 1
ELSE
    IF row == l - 1 THEN
        col 1 증가
    ELSE
        row 1 증가
    END IF
    flag = 0
END IF
STEP 7 -> MAX = MAXIMUM(k, l) - 1 설정
STEP 8 -> FOR diag = MAX; diag > 0; --diag 반복
    IF diag > mn THEN
        len = mn
    ELSE
        len = diag
    END IF
    FOR i = 0 TO i < len, ++i 반복
        mat[row][col] 출력
        IF i + 1 == len THEN
            BREAK
        END IF
        IF flag THEN
            row 1 증가, col 1 감소
        ELSE
            col 1 증가, row 1 감소
        END IF
        IF row == 0 OR col == k - 1 THEN
            IF col == k - 1 THEN
                row 1 증가
            ELSE
                col 1 증가
            END IF
            flag = true
        ELSE IF col == 0 OR row == l - 1 THEN
            IF row == l - 1 THEN
                col 1 증가
            ELSE
                row 1 증가
            END IF
            flag = false
        END IF
    END FOR
STOP

C 언어 구현 예제

#include <stdio.h>
#include <stdbool.h>
#define C 3
#define min(a, b) a>b?b:a
#define max(a, b) a>b?a:b
int main(){
    int k = 3, l = 3;
    int mat[][3] = {
        { 10, 20, 30 },
        { 40, 50, 60 },
        { 70, 80, 90 }
    };
    int row = 0, col = 0;
    bool flag = false;
    int i, j, len, diag;
    int MAX;
    int mn = min(k, l); // 최솟값을 구하는 매크로
    for ( len = 1; len <= mn; ++len) {
        for ( i = 0; i < len; ++i) {
            printf("%d ", mat[row][col]); // 지그재그 형식으로 행렬 출력
            if (i + 1 == len)
                break;
            if (flag)
                ++row, --col;
            else
                --row, ++col;
        }
        if (len == mn)
            break;
        if (flag)
            ++row, flag = false;
        else
            ++col, flag = true;
    }
    if (row == 0) {
        if (col == k - 1)
            ++row;
        else
            ++col;
        flag = 1;
    } else {
        if (row == l - 1)
            ++col;
        else
            ++row;
        flag = 0;
    }
    MAX = max(k, l) - 1; // 최댓값 확인
    for ( len, diag = MAX; diag > 0; --diag) { // 대각선 방향으로 이동하는 루프
        if (diag > mn)
            len = mn;
        else
            len = diag;
        for ( i = 0; i < len; ++i) {
            printf("%d ", mat[row][col]);
            if (i + 1 == len)
                break;
            if (flag)
                ++row, --col;
            else
                ++col, --row;
        }
        if (row == 0 || col == k - 1) {
            if (col == k - 1)
                ++row;
            else
                ++col;
            flag = true;
        }
        else if (col == 0 || row == l - 1) {
            if (row == l - 1)
                ++col;
            else
                ++row;
            flag = false;
        }
    }
    return 0;
}

실행 결과

이 프로그램을 실행하면 다음과 같은 출력이 생성됩니다.

10 20 40 70 50 30 60 80 90

마무리

이 알고리즘은 행렬의 각 요소를 정확히 한 번씩만 방문하므로 시간 복잡도는 O(row × col)입니다. 또한 별도의 저장 공간 없이 flag 변수 하나만으로 이동 방향을 제어하기 때문에 공간 복잡도 역시 O(1)로 매우 효율적입니다. 이러한 지그재그 순회 기법은 이미지 처리, 대각선 기반 데이터 스캔 등 다양한 분야에서 폭넓게 응용될 수 있으므로, 대각선 인덱스 계산과 경계 조건 처리 로직을 잘 이해해 두는 것이 좋습니다.