C/명품 C언어 프로젝트(안기수 저)

명품 C언어 프로젝트 4.3장 연습문제

꾸준함. 2017. 7. 9. 14:55

[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번 문제에서 정의한 함수를 이용해서 풀었습니다

반응형