[1번 문제]
/*
행과 열의 요소를 바꾸는 전치(transpose) 행렬을 출력하는 함수를 작성하시오
*/
#include <stdio.h>
void transpose(int m[][3], int row);
void print_matrix(int m[][3], int row_size, int col_size);
int main(void)
{
int m[3][3] = { {3, 8, 6}, { 4, 1, 7 }, { 5, 2, 9 } };
printf("변환 전\n");
print_matrix(m, 3, 3);
printf("변환 후\n");
transpose(m, 3);
return 0;
}
void transpose(int m[][3], int row)
{
int temp[3][3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
temp[j][i] = m[i][j];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
m[i][j] = temp[i][j];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
printf("%2d ", m[i][j]);
printf("\n");
}
}
void print_matrix(int m[][3], int row_size, int col_size)
{
int i, j;
for (i = 0; i < row_size; i++)
{
for (j = 0; j < col_size; j++)
printf("%2d ", m[i][j]);
printf("\n");
}
}
[2번 문제]
/*
임의의 행과 열을 갖는 두 행렬의 곱을 계산하는 함수를 작성하시오.
예를 들어 3*5의 행렬과 5*4의 행렬을 곱하여 3*4의 행렬을 출력합니다
*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void print_matrix(int **m, int row_size, int col_size);
void multiply_matrix(int **ma, int **mb, int row1, int col1, int row2, int col2);
int main(void)
{
int **a, **b;
int row1, row2=1, col1=0, col2;
srand((unsigned)time(NULL)); //시드값
while (col1 != row2)
{
printf("첫 번째 행렬의 행과 열을 입력: ");
scanf("%d %d", &row1, &col1);
printf("\n두 번째 행렬의 행은 첫 번째 행렬의 열과 동일해야합니다\n");
printf("일치하지 않으면 재입력\n\n");
printf("두 번째 행렬의 행과 열을 입력: ");
scanf("%d %d", &row2, &col2);
}
a = (int**)malloc(sizeof(int*)*row1);
for (int i = 0; i < row1; i++)
{
a[i] = (int*)malloc(sizeof(int)*col1);
}
b = (int**)malloc(sizeof(int*)*row2);
for (int i = 0; i < row2; i++)
{
b[i] = (int*)malloc(sizeof(int)*col2);
}
for (int i = 0; i < row1; i++)
{
for (int j = 0; j < col1; j++)
{
a[i][j] = rand() % 10;
}
}
printf("\na 배열 출력\n");
print_matrix(a, row1, col1);
for (int i = 0; i < row2; i++)
{
for (int j = 0; j < col2; j++)
{
b[i][j] = rand() % 10;
}
}
printf("b 배열 출력\n");
print_matrix(b, row2, col2);
multiply_matrix(a, b, row1, col1, row2, col2);
//메모리 해제
for (int i = 0; i < row1; i++)
{
free(a[i]);
}
for (int i = 0; i < row2; i++)
{
free(b[i]);
}
free(a);
free(b);
return 0;
}
void multiply_matrix(int **ma, int **mb, int row1, int col1, int row2, int col2)
{
int **mab;
mab = (int**)malloc(sizeof(int*)*row1);
for (int i = 0; i < row1; i++)
{
mab[i] = (int*)malloc(sizeof(int)*col2);
}
for (int i = 0; i < row1; i++)
{
for (int j = 0; j < col2; j++)
{
mab[i][j] = 0;
for (int k = 0; k < col1; k++)//첫 번째 행렬의 열과 두 번째 행렬의 행이 일치해야하는 이유
{
mab[i][j] += ma[i][k] * mb[k][j];
}
}
}
printf("aXb 행렬 출력\n");
print_matrix(mab, row1, col2);
//메모리 해제
for (int i = 0; i < row1; i++)
{
free(mab[i]);
}
free(mab);
}
void print_matrix(int **m, int row_size, int col_size)
{
int i, j;
for (i = 0; i < row_size; i++)
{
for (j = 0; j < col_size; j++)
printf("%3d ", m[i][j]);
printf("\n");
}
}
[3번 문제]
/*
역행렬을 계산하는 함수를 작성한다
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void inverse_matrix(double m[][2], double inverse[][2]);
void print_matrix(double m[][2]);
int main(void)
{
double m[2][2], result[2][2];
srand((unsigned)time(NULL)); //시드 값 설정
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
m[i][j] = rand() % 10 + 1;
}
printf("기존 행렬\n");
print_matrix(m);
inverse_matrix(m, result);
printf("역행렬\n");
print_matrix(result);
return 0;
}
void inverse_matrix(double m[][2], double result[][2])
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
if (i == j) //(0, 0), (1, 1)
result[i][j] = m[1 - i][1 - j] / (m[0][0] * m[1][1] - m[0][1] * m[1][0]); //1/(ad-bc)*a, 1/(ad-bc)*d
else
result[i][j] = -m[i][j] / (m[0][0] * m[1][1] - m[0][1] * m[1][0]); //1/(ad-bc)*(-b), 1/(ad-bc)*(-c)
}
}
}
void print_matrix(double m[][2])
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
printf("%2lf ", m[i][j]);
printf("\n");
}
}
[4번 문제]
/*
일반적인 행렬을 희소(sparse)행렬로 변환하는 함수를 작성합니다
sparse 행렬이란 행렬의 요소 중 0인 요소을 생략하므로써 메모리를 절약한다
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct _sparse
{
int col;
int row;
int value; //0이 아닌 데이터의 수
}SprMtrx;
SprMtrx *getSparse(int A[][6], int col, int row, int *cnt)
{
int i, j;
SprMtrx *S;
for (i = 0; i < col; i++)
{
for (j = 0; j < row; j++)
{
if (A[i][j])
(*cnt)++; //0이 아닌 데이터 개수 구하기
}
}
//초기값 때문에 공간이 1개 더 필요하다
S = (SprMtrx*)malloc(sizeof(SprMtrx)*((*cnt) + 1));
//시작값 행, 열, 데이터 개수 집어넣기
S[0].col = col;
S[0].row = row;
S[0].value = *cnt;
//sparse matrix의 각 원소에 값 할당
*cnt = 1;
for (i = 0; i < col; i++)
{
for (j = 0; j < row; j++)
{
if (A[i][j])
{
S[*cnt].col = i;
S[*cnt].row = j;
S[(*cnt)++].value = A[i][j];
}
}
}
return S;
}
int main(void)
{
int cnt = 0;
int A[6][6];
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
A[i][j] = rand() % 2; //최대한 0이 많이 나오게 50%의 확률로 0이 나오게끔 했습니다
}
}
printf("기존 행렬\n");
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
printf("%2d ", A[i][j]);
}
printf("\n");
}
printf("희소 행렬로 변환\n\n");
SprMtrx *S = getSparse(A, sizeof(A) / (sizeof(int) * 6), 6, &cnt);
//출력
for (int i = 0; i < cnt; i++)
{
printf("%d\t%d\t%d\n", S[i].col, S[i].row, S[i].value);
}
return 0;
}
[5번 문제]
/*
희소행렬에 대한 합과 차를 구하는 함수를 작성합니다
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct _sparse
{
int col;
int row;
int value; //0이 아닌 데이터의 수
}SprMtrx;
SprMtrx *getSparse(int A[][5], int col, int row, int *cnt)
{
int i, j;
SprMtrx *S;
for (i = 0; i<col; i++)
{
for (j = 0; j<row; j++)
{
if (A[i][j])
(*cnt)++; //0 아닌 데이터 개수 구하기
}
}
//초기값 때문에 공간 하나 더 필요
S = (SprMtrx*)malloc(sizeof(SprMtrx)*((*cnt) + 1));
//시작값 행 열 데이터 개수 넣기
S[0].col = col;
S[0].row = row;
S[0].value = *cnt;
//sparse matrix의 각 원소에 값 할당하기
*cnt = 1;
for (i = 0; i<col; i++)
{
for (j = 0; j<row; j++)
{
if (A[i][j])
{
S[*cnt].col = i;
S[*cnt].row = j;
S[(*cnt)++].value = A[i][j];
}
}
}
return S;
}
void Add(int A[][5], int B[][5], int result[][5])
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
result[i][j] = A[i][j] + B[i][j];
}
}
void Subtract(int A[][5], int B[][5], int result[][5])
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
result[i][j] = A[i][j] - B[i][j];
}
}
void print_matrix(int A[][5])
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
printf("%2d ", A[i][j]);
printf("\n");
}
}
int main(void)
{
int cnt1 = 0, cnt2=0;
int cnt3 = 0;
int A[5][5], B[5][5]; //행렬 두개 선언
int result1[5][5] = { 0, }, result2[5][5] = { 0, }; //덧셈, 뺄셈 결과
srand((unsigned)time(NULL));
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
A[i][j] = rand() % 2;
}
printf("A 행렬 출력\n");
print_matrix(A);
printf("\n");
/*
SprMtrx *S3 = getSparse(A, sizeof(A) / (sizeof(int) * 5), 5, &cnt3);
for (int i = 0; i < cnt3; i++)
{
printf("%d\t%d\t%d\n", S3[i].col, S3[i].row, S3[i].value);
}
printf("\n\n");
*/
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
B[i][j] = rand() % 2;
}
printf("\nB 행렬 출력\n");
print_matrix(B);
printf("\n행렬 덧셈\n");
Add(A, B, result1);
print_matrix(result1);
SprMtrx *S1 = getSparse(result1, 5, 5, &cnt1);
printf("\n희소행렬 덧셈\n");
//출력
for (int i = 0; i < cnt1; i++)
{
printf("%d\t%d\t%d\n", S1[i].col, S1[i].row, S1[i].value);
}
printf("\n행렬 뺄셈\n");
Subtract(A, B, result2);
print_matrix(result2);
SprMtrx *S2 = getSparse(result2, 5, 5, &cnt2);
printf("\n희소행렬 뺄셈\n");
//출력
for (int i = 0; i < cnt2; i++)
{
printf("%d\t%d\t%d\n", S2[i].col, S2[i].row, S2[i].value);
}
return 0;
}
[6번 문제]
/*
희소행렬에 대한 전치행렬을 출력하는 함수를 작성합니다
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct _sparse
{
int col;
int row;
int value; //0이 아닌 데이터의 수
}SprMtrx;
SprMtrx *getSparse(int A[][6], int col, int row, int *cnt)
{
int i, j;
SprMtrx *S;
for (i = 0; i < col; i++)
{
for (j = 0; j < row; j++)
{
if (A[i][j])
(*cnt)++; //0이 아닌 데이터 개수 구하기
}
}
//초기값 때문에 공간이 1개 더 필요하다
S = (SprMtrx*)malloc(sizeof(SprMtrx)*((*cnt) + 1));
//시작값 행, 열, 데이터 개수 집어넣기
S[0].col = col;
S[0].row = row;
S[0].value = *cnt;
//sparse matrix의 각 원소에 값 할당
*cnt = 1;
for (i = 0; i < col; i++)
{
for (j = 0; j < row; j++)
{
if (A[i][j])
{
S[*cnt].col = i;
S[*cnt].row = j;
S[(*cnt)++].value = A[i][j];
}
}
}
return S;
}
SprMtrx *transposeSM(SprMtrx *S, int cnt)
{
int index = 1;
SprMtrx *Ts = (SprMtrx*)malloc(sizeof(SprMtrx)*cnt);
//우선 첫줄을 바꾸고
Ts[0].row = S[0].col;
Ts[0].col = S[0].row;
Ts[0].value = S[0].value;
//열을 기준으로
for (int i = 0; i < S[0].row; i++)
{
for (int j = 1; j < cnt; j++) //1번원소부터 마지막까지 비교하여
{
//해당 열값이랑 원소가 가지고 잇는 열값이 같으면 전치행렬에 대입
if (i == S[j].row)
{
Ts[index].col = S[j].row;
Ts[index].row = S[j].col;
Ts[index++].value = S[j].value;
}
}
}
return Ts;
}
int main(void)
{
int cnt = 0;
int A[6][6];
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
A[i][j] = rand() % 2; //최대한 0이 많이 나오게 50%의 확률로 0이 나오게끔 했습니다
}
}
printf("기존 행렬\n");
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
printf("%2d ", A[i][j]);
}
printf("\n");
}
//희소행렬로 변환
SprMtrx *S = getSparse(A, sizeof(A) / (sizeof(int) * 6), 6, &cnt);
printf("전치행렬로 변환\n");
SprMtrx *T = transposeSM(S, cnt);
//출력
for (int i = 0; i < cnt; i++)
{
printf("%d\t%d\t%d\n", T[i].col, T[i].row, T[i].value);
}
return 0;
}
개발환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
[참고] 명품 C언어 프로젝트 안기수 저, http://blog.naver.com/PostView.nhn?blogId=zkd1750&logNo=90191709059&parentCategoryNo=&categoryNo=22&viewDate=&isShowPopularPosts=true&from=search
*4번, 6번은 참고한 블로그에서 그대로 가져왔고 5번은 4번 문제에서 정의한 함수를 이용해서 풀었습니다
'C > 명품 C언어 프로젝트(안기수 저)' 카테고리의 다른 글
명품 C언어 프로젝트 4.5장 연습문제 (0) | 2017.07.14 |
---|---|
명품 C언어 프로젝트 4.4장 연습문제 (0) | 2017.07.11 |
명품 C언어 프로젝트 4.2장 연습문제 (2) | 2017.07.06 |
명품 C언어 프로젝트 4.1장 연습문제 (0) | 2017.07.05 |
명품 C언어 프로젝트 3.8장 연습문제 (0) | 2017.07.01 |