검색어 입력폼

[C언어] 행렬의 곱셈 프로그램

저작시기 2007.05 |등록일 2007.05.29 파일확장자압축파일 (zip) | 5페이지 | 가격 800원

소개글

// 단순한 두 행렬의 곱셈 프로그램

void multi_matrix(int m1[], int m2[], int m3[], int m, int n, int l); // 행렬을 곱하는 함수.
void print_matrix(int ma[], int m, int n); // 행렬을 출력하는 함수.
void Get_matrix(int ma[], int m, int n); // 행렬을 생성하는 함수.

int main()
{
int m1[12], m2[8], m3[6]; // 행렬 두개 및 결과행렬을 위한 변수.
Get_matrix(m1, 3, 4);
Get_matrix(m2, 4, 2);
print_matrix(m1, 3, 4);
print_matrix(m2, 4, 2);
multi_matrix(m1, m2, m3, 3, 4, 2);
print_matrix(m3, 3, 2);
return 0;
}


Ⅰ. 문제의 제기
행렬의 곱셈은 첫 행렬의 열의 개수와 두 번째 행렬의 행의 개수가 같을 때만 정의된다. 그 결과로 나오는 행렬은 A행렬이 m*n, B행렬이 n*l 일 때, m*l이 된다. 이러한 규칙에 따라 행렬의 곱셈 프로그램을 제작해본다. 특히, 곱셈의 공식을 표현할 방법, 행렬을 어떠한 방식으로 받아오고 제어할 것인지, 저장 방식에서 배열은 2차원으로 할 것인지 1차원으로 할 것인지, 파라미터로 넘겨주는 과정에서 함수의 재사용성을 극대화하기 위해서는 어떠한 방식을 취해야 하는지를 중심으로 검토하여 본다.
※ 작성된 프로그램의 전체 소스 #붙임1 (multi.cpp)

Ⅱ. 문제해결의 방식 및 알고리즘 구현
1. 프로그램 설명
행렬의 곱셈 프로그램은 배열을 이용하여 두 개의 행렬을 생성하고, 그 두 행렬을 곱한 결과를 출력하여 주는 것으로서, 함수들을 이용하여 구현한다.

2. 문제해결 접근 방식
(1) 행렬의 곱셈 공식을 표현할 방법
행렬의 곱셈은 앞서 설명한 바에 따라 첫 행렬의 열의 개수와 두 번째 행렬의 행의 개수가 같아야 한다. 곱셈을 공식으로 표현하자면-2*3, 3*2 행렬을 이용- 아래와 같다.

공식에 따르면 첫 행렬의 행 값들과 두 번째 행렬의 열 값들을 곱한 결과를 합한 것이 결과행렬에 들어가게 되는 것이다. 따라서 프로그램을 위해서는 결과행렬의 현재 행/열을 제어할 for문이 필요할 것이며, 그 와 동시에 첫 번째 행렬의 행(두 번째 행렬의 열)을 제어할 for문이 필요할 것이다. 따라서 3중 루프로 구현되어야 한다. 또한 곱한 결과를 계속해서 더해줘야 하므로 결과행렬의 현재 행/열은 한번의 초기화가 필요할 것이다. 초기화는 한번만 해주어야 하는데, 그 이유는 계산이 시작되면 계속해서 곱한 결과를 더해주어야 하기 때문이다.

(2) 배열을 이용한 행렬의 표현 방법
행렬은 2차원 배열과 그 구조가 동일하다. 따라서 2차원 배열을 이용하면 간단하다. 이때 함수를 이용하면 2차원 배열은 두 개의 주소-행의 시작과 열의 시작 주소-를 가지고 있기 때문에 두 개의 포인터를 넘겨주던가, 열 값을 항상 지정해 주어야 하는 불편함이 따른다. 물론 C언어-확장자가 c인 소스-에서는 2차원 배열로 선언하여도 1차원 배열로 함수에서 받아서 사용할 수 있으므로(warning은 있다.) 크게 제한이 없으나 지금은 C++(확장자가 cpp)로 구현하기 때문에 포인터의 사용에 조심해야한다. 따라서 초기 배열을 선언은 1차원으로 한다. 크기는 행과 열을 곱한 만큼으로 잡아주고 시작한다. 함수에서도 1차원 배열로 받아오며, 이때 행/열의 값을 파라미터로 받아와 함수 내에서는 2차원 배열과 동일하게 사용한다. 2차원 배열과 동일하게 사용하는 방법은 배열은 연속된 메모리공간에 표현된 자료구조라는 점에 착안하여 행을 제어하는 변수와 열을 제어하는 변수를 놓고, 행을 제어하는 변수에 열 값을 곱해주어 행을 임의적으로 가르치게 한다. 여기에 열을 제어하는 변수를 더해주기만 하면 2차원 배열과 동일한 효과를 볼 수 있다. 따라서 2*3행렬에서 k행, j열은 k*3+j로 인덱스를 표현할 수 있을 것이다. 이 방식을 이용하면 함수에서의 이동이 자유롭고 행렬의 크기가 바뀌어도 다시 함수를 정의하지 않아서 재사용 측면에서 용이하다. 그리고 행렬을 생성하고 출력 곱셈하는 단계에서도 2차원 배열과 같이 for문의 카운터를 이용하여 충분히 제어할 수 있게 되는 것이다.


3. 알고리즘 구현
(1) 간략한 알고리즘
앞서 살펴본 문제 해결 방식에 따라 알고리즘을 작성하면, 우선 for문을 제어할 변수 3개가 필요하며, 행렬을 위한 배열 3개가 필요하다. 제어 변수를 m, n, l, 행렬을 a[m*n], b[n*l], c[m*l]이라고 한다. 두 개의 행렬을 생성하면 곱셈을 시작하는데 3개의 for문으로 이루어진 루프 안에서 계산을 한다. 첫 for문은 결과행렬 c의 행을 위해 m까지 수행되며, 두 번째 for문은 결과행렬 열을 위해 l까지 수행된다. 두 번째 for문이 시작되면 결과행렬의 현재 행/열 값을 0으로 초기화하고 다음 for문으로 들어간다. 3번째 for문은 a행렬의 열, b행렬의 행 값을 위한 것이며, 여기서 계산이 이루어 진다. 이와 같은 내용을 간단히 나타내면 아래와 같다.
ⅰ. 첫 번째 for문 카운터가 m보다 같거나 크면 멈춘다.
ⅱ. 두 번째 for문 카운터가 l보다 같거나 크면 ⅰ로 돌아가고, 그렇지 않으면 c의 현재위치를 0으로 초기화 한다.
ⅲ. 세 번째 for문 카운터가 n보다 같거나 크면 ⅱ로 돌아가고, 그렇지 않으면 ⅳ로 간다.
ⅳ. a의 현재 행/열 값과 b의 현재 행/열 값을 곱하여 c의 현재 행/열 값에 더한다.

(2) 알고리즘에 따른 플로우 차트의 작성
위 알고리즘의 내용을 플로우 차트로 작성하면 아래와 같다.

컴파일 실행환경

C언어

압축파일내 파일목록

MMA.dsw
MMA.ncb
MMA.plg
MMA.dsp
multi.cpp
Untitled-1 copy.jpg
MMA.opt
Untitled-2 copy.jpg
행렬곱셈.hwp
Debug/vc60.idb
Debug/vc60.pdb
Debug/MMA.ilk
Debug/MMA.exe
Debug/MMA.pdb
Debug/MMA.pch
Debug/multi.obj
다운로드 맨위로