교재에 나온 mmult가 틀린 점이 있어 이를 수정하여 동작시킨 코드입니다.

'2008년 2학기 자료구조 - Flow Chart - mmult'

 

#include "stdio.h"
#include "stdlib.h"
#define MAX_TERMS 101 // 최대 항의 수 + 1
#define MAX_COL 50 // 최대 열의 수 + 1
#define COMPARE(x, y) (((x) < (y)) ? -1 : ((x) == (y))? 0 : 1)

// global 변수
typedef struct {
          int col;
          int row;
          int value;
} term;

int pos = 0;

// 함수의 선언
void fast_transpose(term a[], term b[]);
void insert(int col, int row, int value, term a[]);
//void sparse_matrix(int row, int col, int matrix[][3], term a[]);
void sparse_matrix(int matrix[][3], term a[]);
void print_matrix(int row, int col);
void storeSum(term d[], int *totalD, int row, int column, int *sum);
void my_print_matrix(term b[]);
void mmult(term a[], term b[], term d[]);

int main(void)
{
// 입력값
    int matrix[][3] = {
        {6,6,8},{0,0,15},{0,4,91},{1,1,11},
        {2,1,3},{2,5,28},{3,0,22},{3,2,-6},
        {5,0,-15}
    };
/*
    int matrix1[][3] = {
        {3,3,4},{0,0,1},{0,2,2},{1,2,3},
        {2,1,4}
    };

    int matrix2[][3] = {
        {3,2,4},{0,0,1},{0,1,2},{1,0,3},
        {2,1,4}
    };*/
    term a[MAX_TERMS], b[MAX_TERMS], d[MAX_TERMS];

    sparse_matrix(matrix, a);
          //sparse_matrix(matrix1, a);
          //sparse_matrix(matrix2, b);
          // 초기에 입력된 행렬을 보여준다
//          print_matrix(row, col, a);

          // 행렬을 원소쌍으로 바꾼다
          //sparse_matrix(row, col);
            my_print_matrix(a);
          // 행렬의 빠른전치
          fast_transpose(a, b);

          my_print_matrix(b);
          // 전치행렬의 원소를 보여준다

          mmult(a, b, d);

            my_print_matrix(d);
          //for (i = 0; i <= b[0].value; i++)
          //        printf("row = %d col = %d value = %d \n", b[i].row, b[i].col, b[i].value);

    return 0;
}

void my_print_matrix(term b[])
{
    int i;
    for (i = 0; i <= b[0].value; i++)
                  printf("row = %d col = %d value = %d \n", b[i].row, b[i].col, b[i].value);

    printf("\n\n");
}
/*
void print_matrix(int row, int col)
{
          int i, j;

          printf("\n %d x %d Matrix \n", row, col);

          for (i = 0; i < row; i++)
          {
                    putchar('[');

                    for (j = 0; j < col; j++)
                              printf("%4d", matrix[i][j]);

                    putchar(']');
                    putchar('\n');
          }
          putchar('\n');
}*/

void sparse_matrix(int matrix[][3], term a[])
{
          int i, j = matrix[0][2], count = 0;

          /*
          for (i = 0; i < row; i++)
          {
                    for (j = 0; j < col; j++)
                    {
                              if (matrix[i][j] == 0)
                                        continue;

                              insert(i, j, matrix[i][j], a);
                              count++;
                    }
          }
          */
          for(i = 0 ; i <= j ; i++)
          {
              insert(matrix[i][1], matrix[i][0], matrix[i][2], a);
          }
          // 0이 아닌 항의 총 갯수를 저장한다
          //a[0].value = count;
          pos = 0;
}

void fast_transpose(term a[], term b[])
{
          // a를 전치시켜 b에 저장
          int row_terms[MAX_COL];
          int starting_pos[MAX_COL];
          int num_cols = a[0].col;
          int num_terms = a[0].value;
          int i, sp;

          b[0].row = num_cols;
          b[0].col = a[0].row;
          b[0].value = num_terms;
                    // 0 이 아닌 행렬         
          if ( num_terms > 0 )
          {
                    for (i = 0; i <= num_cols; i++)
                              row_terms[i] = 0;

                    for (i = 1; i <= num_terms; i++)
                              row_terms[a[i].col]++;

                    starting_pos[0] = 1;

                    for (i = 1; i < num_cols; i++)
                              starting_pos[i] = starting_pos[i - 1] + row_terms[i - 1];

                    for (i = 1; i <= num_terms; i++)
                    {
                              sp = starting_pos[a[i].col]++;

                              b[sp].row = a[i].col;
                              b[sp].col = a[i].row;
                              b[sp].value = a[i].value;
                    }
          }
}

void insert(int col, int row, int value, term a[])
{
          a[pos].col = col;
          a[pos].row = row;
          a[pos].value = value;

          pos++;
}

void mmult(term a[], term b[], term d[])
{
int i, j, column, totalB = b[0].value, totalD = 0;
int rowsA = a[0].row, colsA = a[0].col, totalA = a[0].value;
int colsB = b[0].col, rowBegin = 1, row = a[1].row, sum = 0;
term newB[MAX_TERMS];
if (colsA != b[0].row)
{
fprintf(stderr, "Incompatible matrices\n");
exit(EXIT_FAILURE);
}
fast_transpose(b, newB);

a[totalA+1].row = rowsA;
newB[totalB+1].row = colsB;
//newB[totalB+1].col = 0;

for (i = 1 ; i <= totalA ; )
{
    column = newB[1].row;
    for (j = 1 ; j <= totalB+1; )
    {
        if (a[i].row != row)
        {
            storeSum(d, &totalD, row, column, &sum);
            i = rowBegin;
            for (; newB[j].row == column ; j++)
                ;
            column = newB[j].row;
        }
        else if (newB[j].row != column)
        {
            storeSum(d, &totalD, row, column, &sum);
            i = rowBegin;
            column = newB[j].row;
        }
        else switch (COMPARE(a[i].col, newB[j].col))
        {
            case -1:
                i++; break;
            case 0:
                sum += (a[i++].value * newB[j++].value);
                break;
            case 1:
                j++;
        }
    }
    for (; a[i].row == row ; i++)
        ;
    rowBegin = i; row = a[i].row;
}
d[0].row = rowsA;
d[0].col = colsB;
d[0].value = totalD;
}

void storeSum(term d[], int *totalD, int row, int column, int *sum)
{
    if (*sum)
        if (*totalD < MAX_TERMS)
        {
            d[++*totalD].row = row;
            d[*totalD].col = column;
            d[*totalD].value = *sum;
            *sum = 0;
        }
        else
        {
            fprintf(stderr, "Numbers of terms in product exceeds %d\n", MAX_TERMS);
            exit(EXIT_FAILURE);
        }
}

크리에이티브 커먼즈 라이선스
Creative Commons License

글에 잘못된 점, 다른 점, 부족한 점이 있다면 지적해주세요.
댓글, 트랙백, 메일 모두 고맙습니다.

트랙백 주소 :: http://nosyu.pe.kr/trackback/1722

댓글을 달아 주세요

  1. 이승호 2008/10/20 21:49  댓글주소  수정/삭제  댓글쓰기

    굉장하시군요.
    많이 배우고 갑니다. ^^
    커피라도 한잔 사드리고 싶은데요^^;

    • NoSyu 2008/10/21 07:34  댓글주소  수정/삭제

      반갑습니다.
      조금 읽기 힘드시죠?
      댓글에도 적었지만 사실 이 소스는 대충 확인만 한 후 시험 후 수정하여 올릴 생각이었습니다.
      그래도 필요하시다기에 그냥 올려버렸네요.
      도움이 되셨다니 다행입니다.
      커피...는 제가 못 마시는터라...^^;;;;OTL.....
      마음만 받는 것으로 하면 괜찮겠지요?^^

  2. 떠돌 2008/10/21 10:47  댓글주소  수정/삭제  댓글쓰기

    구조체랑.....2차 행렬을 보는 순간 치가 떨렸습니다..ㄷㄷㄷㄷ; ^^;

    • NoSyu 2008/10/21 23:51  댓글주소  수정/삭제

      ㄷㄷㄷㄷ
      그럼 전에 보셨던 사진과 비교하시면 어느 쪽이 더욱...?^^;;;;

    • 떠돌 2008/10/22 09:08  댓글주소  수정/삭제

      이제 소스도 거의 못보는 레벨이라.. 그러고 보니 프로그램 손 뗀지는 1년이 넘는군요;;;;

    • NoSyu 2008/10/22 12:29  댓글주소  수정/삭제

      역시 관리자가 되시면 코딩은 밑에서 척척..?
      잘 모르겠네요.;;;;

    • 떠돌 2008/10/22 13:43  댓글주소  수정/삭제

      이직을 하게 되면서 이젠 코딩도 스크립트 노가다도 없음다 ㅋㅋㅋ 요즘엔 일본어와 시름중이죠 ^^;

    • NoSyu 2008/10/22 15:26  댓글주소  수정/삭제

      아.. 이직이군요.^^
      일본어 공부라.... 일본어가 처음에 배우기는 쉽지만 제대로 쓰기에는 상당히 어렵다고 하더니...;;;;

    • 떠돌 2008/10/22 15:26  댓글주소  수정/삭제

      ㅋㅋㅋ 일본어는 뭐 불편함 없이 쓰니까요 ^^; 번역이나 통역이 어려워서 글져 ㅠㅠ

    • NoSyu 2008/10/22 15:28  댓글주소  수정/삭제

      역시 대단하시군요.^^
      (아.. 일본에 사셨으니...^^;;;;)
      번역과 통역은 정말 새롭게 창조하는 것이라 참으로 힘듭니다.ㅜㅜ
      (그보다 빛의 속도로 댓글을 적어주시다니...
      그러고보니 저도 그렇네요.^^;;;)

  3. 이승호 2008/10/21 12:36  댓글주소  수정/삭제  댓글쓰기

    감동이네요^^;
    혹시 성함이 어떻게 되시는지요?
    전 전자과 3학년 04학번 이승호입니다. ^^;
    이번에 복학하였지요. 하여튼 정말 감사히 잘보겠습니다. :)

    • NoSyu 2008/10/21 23:52  댓글주소  수정/삭제

      아.. 이름을 밝히기는 조금....
      (이라고 해도 이미 블로그 어딘가에 다 적었으니...;;;;)
      일단.. 같은 학번이네요.^^(학년은 다르지만...;;;)
      내일이 시험이네요. 시험 같이 잘 보기를....^^

  4. 맹구 2008/10/21 17:43  댓글주소  수정/삭제  댓글쓰기

    Nosyu님께 많은 도움을 받고 있습니다. 항상 고마워요!

    그런데 포스팅된 코드 중에 경계조건을 설정하는 부분에서 주석 처리하신 부분
    (//newB[totalB+1].col = 0)은 주석처리 하지 않아야 제대로 동작하지 않나요?

    switch 문 안에서 비교될때 값이 있어야 할 것 같아서 그렇게 생각했는데..

    • NoSyu 2008/10/21 23:55  댓글주소  수정/삭제

      반갑습니다.
      도움이 되신다니 다행이네요.^^

      저 boundary check가 문제였습니다.
      왜 저것을 해야하는가 의심스러웠는데 실제로 저것이 있으면 이상한 결과를 내놓습니다.
      하지만 주석으로 처리하여 진행하니 문제없이 되더군요.
      그 이유를 저도 정확히 찾지 않았습니다만, 여튼 저것이 문제라는 것은 알았습니다.

      switch 문 안에서 비교할 때 나머지 boundary 설정으로도 충분하더군요.^^

    • NoSyu 2008/10/21 23:55  댓글주소  수정/삭제

      아 그렇군요

      전에 분석해봤을 때 그렇게 했던 거 같았는데 실제 돌려보면 또 다른가보네요
      꽥..헛공부했구만 ㅠㅠ

    • NoSyu 2008/10/22 15:25  댓글주소  수정/삭제

      그러고보니 오늘 시험에 나왔더군요.
      일단 답을 여기에 맞게 적었습니다만, 조금 당황했습니다.OTL....
      틀리면 골이 아플텐데....;;;;;

      하지만 실제로 그렇게 나왔으니.... 어렵습니다.ㅜ

  5. 이옥환 2008/10/22 01:51  댓글주소  수정/삭제  댓글쓰기

    성대생이신가요?
    웬지 숙제에서 교수님까지 유추가...가능해보입니다.

    .....

    자전거에 빠져계신 교수님....

    • NoSyu 2008/10/22 08:35  댓글주소  수정/삭제

      반갑습니다.
      네.. 성균관대 학부생입니다.^^
      자전거에 빠져계신... 유명하신 교수님입니다.^^

[로그인][오픈아이디란?]