C 언어로 행렬 곱셈

CBeginner
지금 연습하기

소개

이 실습에서는 C 언어로 두 행렬을 곱하는 방법을 배웁니다. 이 실습은 다음 단계를 포함합니다.

차원 및 요소 읽기: 사용자 입력으로부터 두 행렬의 차원과 요소를 읽는 방법을 배웁니다. 이 단계는 행렬 곱셈을 위해 행렬이 호환되는지 확인합니다.

행렬 곱셈: 곱셈 행렬의 각 요소는 입력 행렬의 대응하는 행과 열을 곱하여 계산되는 행렬 곱셈 알고리즘을 구현합니다.

곱셈 행렬 출력: 마지막으로 결과 곱셈 행렬을 표시합니다.

이 실습을 마치면 C 언어에서 행렬 곱셈에 대한 확실한 이해를 얻고 다양한 응용 분야에 적용할 수 있게 됩니다.

차원 및 요소 읽기

이 단계에서는 C 언어로 행렬 곱셈을 위해 행렬 차원과 요소를 읽는 방법을 배웁니다. 사용자가 두 행렬의 크기와 값을 입력할 수 있도록 프로그램을 만들 것입니다.

먼저 행렬 곱셈 프로그램을 위한 새로운 C 파일을 생성합니다.

cd ~/project
nano matrix_multiply.c

이제 행렬 차원을 읽는 다음 코드를 추가합니다.

#include <stdio.h>

#define MAX_SIZE 100

int main() {
    int rows1, cols1, rows2, cols2;

    // 첫 번째 행렬의 차원 읽기
    printf("Enter dimensions of first matrix (rows columns): ");
    scanf("%d %d", &rows1, &cols1);

    // 두 번째 행렬의 차원 읽기
    printf("Enter dimensions of second matrix (rows columns): ");
    scanf("%d %d", &rows2, &cols2);

    // 행렬 곱셈이 가능한지 확인
    if (cols1 != rows2) {
        printf("Matrix multiplication not possible!\n");
        return 1;
    }

    printf("행렬 차원은 곱셈에 유효합니다.\n");

    return 0;
}

프로그램을 컴파일하고 실행합니다.

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

예시 출력:

Enter dimensions of first matrix (rows columns): 2 3
Enter dimensions of second matrix (rows columns): 3 2
행렬 차원은 곱셈에 유효합니다.

코드를 자세히 살펴보겠습니다.

  • MAX_SIZE를 100 으로 정의하여 행렬 차원을 제한합니다.
  • scanf()를 사용하여 사용자 입력으로부터 행렬 차원을 읽습니다.
  • 첫 번째 행렬의 열과 두 번째 행렬의 행을 비교하여 행렬 곱셈이 가능한지 확인합니다.
  • 차원이 호환되지 않으면 프로그램은 오류 메시지를 출력합니다.

이제 행렬 요소를 읽도록 코드를 수정해 보겠습니다.

#include <stdio.h>

#define MAX_SIZE 100

int main() {
    int rows1, cols1, rows2, cols2;
    int matrix1[MAX_SIZE][MAX_SIZE];
    int matrix2[MAX_SIZE][MAX_SIZE];

    // 첫 번째 행렬의 차원 읽기
    printf("Enter dimensions of first matrix (rows columns): ");
    scanf("%d %d", &rows1, &cols1);

    // 두 번째 행렬의 차원 읽기
    printf("Enter dimensions of second matrix (rows columns): ");
    scanf("%d %d", &rows2, &cols2);

    // 행렬 곱셈이 가능한지 확인
    if (cols1 != rows2) {
        printf("Matrix multiplication not possible!\n");
        return 1;
    }

    // 첫 번째 행렬의 요소 읽기
    printf("Enter elements of first matrix:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    // 두 번째 행렬의 요소 읽기
    printf("Enter elements of second matrix:\n");
    for (int i = 0; i < rows2; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    printf("행렬이 성공적으로 읽혔습니다.\n");

    return 0;
}

프로그램을 컴파일하고 실행합니다.

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

예시 출력:

Enter dimensions of first matrix (rows columns): 2 3
Enter dimensions of second matrix (rows columns): 3 2
Enter elements of first matrix:
Enter element [0][0]: 1
... (생략)
행렬이 성공적으로 읽혔습니다.

행렬 행렬 곱셈

이 단계에서는 첫 번째 행렬의 행과 두 번째 행렬의 열을 곱하여 행렬 곱셈을 수행하는 방법을 배웁니다. 이전 코드를 기반으로 행렬 곱셈 알고리즘을 구현할 것입니다.

matrix_multiply.c 파일을 업데이트하여 행렬 곱셈 기능을 추가합니다.

cd ~/project
nano matrix_multiply.c

이전 코드를 다음 구현으로 바꿉니다.

#include <stdio.h>

#define MAX_SIZE 100

int main() {
    int rows1, cols1, rows2, cols2;
    int matrix1[MAX_SIZE][MAX_SIZE];
    int matrix2[MAX_SIZE][MAX_SIZE];
    int result[MAX_SIZE][MAX_SIZE];

    // 첫 번째 행렬의 차원 읽기
    printf("Enter dimensions of first matrix (rows columns): ");
    scanf("%d %d", &rows1, &cols1);

    // 두 번째 행렬의 차원 읽기
    printf("Enter dimensions of second matrix (rows columns): ");
    scanf("%d %d", &rows2, &cols2);

    // 행렬 곱셈이 가능한지 확인
    if (cols1 != rows2) {
        printf("Matrix multiplication not possible!\n");
        return 1;
    }

    // 첫 번째 행렬의 요소 읽기
    printf("Enter elements of first matrix:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    // 두 번째 행렬의 요소 읽기
    printf("Enter elements of second matrix:\n");
    for (int i = 0; i < rows2; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    // 행렬 곱셈
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols2; j++) {
            result[i][j] = 0;
            for (int k = 0; k < cols1; k++) {
                result[i][j] += matrix1[i][k] * matrix2[k][j];
            }
        }
    }

    // 결과 행렬 출력
    printf("\nResult Matrix:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("%d ", result[i][j]);
        }
        printf("\n");
    }

    return 0;
}

프로그램을 컴파일하고 실행합니다.

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

예시 출력:

Enter dimensions of first matrix (rows columns): 2 3
... (생략)
Result Matrix:
58 64
139 154

행렬 곱셈 알고리즘을 자세히 살펴보겠습니다.

  • 바깥쪽 두 루프 (i 와 j) 는 결과 행렬을 반복합니다.
  • 안쪽 루프 (k) 는 첫 번째 행렬의 행 i 와 두 번째 행렬의 열 j 의 내적을 계산합니다.
  • result[i][j]는 대응하는 요소의 곱의 합으로 계산됩니다.
  • 중첩된 루프는 결과 행렬의 각 요소가 올바르게 계산되도록 합니다.

행렬 곱셈에 대한 주요 사항:

  • 첫 번째 행렬의 열 개수는 두 번째 행렬의 행 개수와 같아야 합니다.
  • 결과 행렬의 차원은 (첫 번째 행렬의 행) × (두 번째 행렬의 열) 입니다.

곱셈 결과 행렬 출력

이 마지막 단계에서는 행렬 곱셈 프로그램을 개선하여 더욱 강력한 출력 기능과 오류 처리를 추가하고, 행렬을 출력하는 함수를 만들어 사용자 경험을 향상시킬 것입니다.

다음 개선된 구현으로 matrix_multiply.c 파일을 업데이트합니다.

cd ~/project
nano matrix_multiply.c

이전 코드를 다음 종합적인 버전으로 바꿉니다.

#include <stdio.h>

#define MAX_SIZE 100

// 행렬을 출력하는 함수
void printMatrix(int matrix[MAX_SIZE][MAX_SIZE], int rows, int cols, const char* matrixName) {
    printf("\n%s 행렬:\n", matrixName);
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%5d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int rows1, cols1, rows2, cols2;
    int matrix1[MAX_SIZE][MAX_SIZE];
    int matrix2[MAX_SIZE][MAX_SIZE];
    int result[MAX_SIZE][MAX_SIZE];

    // 첫 번째 행렬의 차원 읽기
    printf("Enter dimensions of first matrix (rows columns): ");
    scanf("%d %d", &rows1, &cols1);

    // 두 번째 행렬의 차원 읽기
    printf("Enter dimensions of second matrix (rows columns): ");
    scanf("%d %d", &rows2, &cols2);

    // 행렬 곱셈 가능 여부 확인
    if (cols1 != rows2) {
        printf("행렬 곱셈이 불가능합니다!\n");
        printf("첫 번째 행렬의 열 (%d) 은 두 번째 행렬의 행 (%d) 과 같아야 합니다.\n", cols1, rows2);
        return 1;
    }

    // 첫 번째 행렬의 요소 읽기
    printf("Enter elements of first matrix:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    // 두 번째 행렬의 요소 읽기
    printf("Enter elements of second matrix:\n");
    for (int i = 0; i < rows2; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    // 입력 행렬 출력
    printMatrix(matrix1, rows1, cols1, "첫 번째 입력");
    printMatrix(matrix2, rows2, cols2, "두 번째 입력");

    // 행렬 곱셈
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols2; j++) {
            result[i][j] = 0;
            for (int k = 0; k < cols1; k++) {
                result[i][j] += matrix1[i][k] * matrix2[k][j];
            }
        }
    }

    // 결과 행렬 출력
    printMatrix(result, rows1, cols2, "곱셈 결과");

    return 0;
}

프로그램을 컴파일하고 실행합니다.

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

예시 출력:

... (생략)
첫 번째 입력 행렬:
    1     2     3
    4     5     6

두 번째 입력 행렬:
    7     8
    9    10
   11    12

곱셈 결과 행렬:
   58    64
  139   154

이 버전의 주요 개선 사항:

  • 일관된 서식으로 행렬을 출력하는 printMatrix() 함수를 만들었습니다.
  • 행렬 곱셈 호환성에 대한 더욱 설명적인 오류 메시지를 추가했습니다.
  • 곱셈 결과 행렬을 보여주기 전에 입력 행렬을 출력합니다.
  • 정렬된 행렬 출력을 위해 %5d를 사용합니다.
  • 읽기 쉬운 출력 형식을 제공합니다.

출력 함수 설명:

  • printMatrix()는 행렬, 차원 및 이름을 매개변수로 받습니다.
  • 중첩된 루프를 사용하여 각 요소를 출력합니다.
  • %5d 형식 지정자는 각 숫자가 정렬을 위해 5 개의 공간을 차지하도록 합니다.
  • 가독성을 위해 각 행 뒤에 줄 바꿈을 추가합니다.

요약

이 실습에서는 C 언어로 행렬 차원과 요소를 읽고 행렬 곱셈을 수행하는 방법을 배웁니다. 먼저 두 행렬의 차원을 읽고 곱셈에 적합한지 확인하는 방법을 배우고, 그런 다음 두 행렬의 요소를 읽어 2 차원 배열에 저장하는 방법을 배웁니다. 마지막으로 실제 행렬 곱셈을 수행하고 결과 곱셈 행렬을 출력하는 방법을 배웁니다.