2016-10-14 3 views
1

행렬 더하기, 빼기 및 곱하기를 수행하는 프로그램을 만들었습니다. 더하기와 빼기 부분을 처리했지만 곱셈에 도달하면 올바른 값을 출력하는 데 문제가 있습니다. 아래의 곱하기 함수를 사용하여 코드를 배치했습니다. 곱셈 기능에 행렬 곱셈 - C

#define _CRT_SECURE_NO_WARNINGS 

#include <stdio.h> 
#include <stdlib.h> 

typedef struct { 

int *elements; 
int rows; 
int columns; 

} matrix; 

void main() { 

     matrix a, b, c; 

     void read_matrix(matrix *); 
     void deallocate(matrix *); 
     void print(matrix); 
     matrix add(matrix, matrix); 
     matrix subtract(matrix, matrix); 
     matrix multiply(matrix, matrix); 

     read_matrix(&a); 
     read_matrix(&b); 
     /* 
     c = add(a, b); 
     printf("The answer of Matrix (a + b) is \n\n"); 
     print(a); 
     printf("\n +\n\n"); 
     print(b); 
     printf("\n =\n\n"); 
     print(c); 
     printf("\n"); 

     deallocate(&c); 
     c = subtract(a, b); 
     printf("The answer of Matrix (a - b) is \n\n"); 
     print(a); 
     printf("\n -\n\n"); 
     print(b); 
     printf("\n =\n\n"); 
     print(c); 
     printf("\n"); 

     deallocate(&c); 
     */ 
     c = multiply(a, b); 
     printf("The answer of Matrix (a * b) is \n\n"); 
     print(a); 
     printf("\n *\n\n"); 
     print(b); 
     printf("\n =\n\n"); 
     print(c); 
     printf("\n"); 

} 

void read_matrix(matrix *z) { 

     int d1, d2, allc, i, x, y, j, val; 
     int res; 

     printf("\nWhat is the first dimension of the array? "); 
     res = scanf("%d", &d1); 

     if (res != 1) { 
      fprintf(stderr, "Something went wrong with your first dimension!"); 
        return; 
     } 

     printf("What is the second dimension of the array? "); 
     res = scanf("%d", &d2); 
     if (res != 1) { 
      fprintf(stderr, "Something went wrong with your second dimension!"); 
      return; 
     } 

     printf("Matrix Dimension is %dx%d\n", d1, d2); 

     allc = d1*d2; 

     (*z).elements = (int *)calloc(allc, sizeof(int)); 
     (*z).rows = d1; 
     (*z).columns = d2; 

     x = 0; 
     j = 0; 

     printf("\n"); 

     for (i = 0; i < d1; i++) { 

      x++; 

      for (y = 0; y < d2; y++) { 
       printf("Enter the value for row %d column %d: ", x, y + 1); 
       res = scanf("%d", &val); 
       if (res != 1) { 
        fprintf(stderr, "Something went wrong while reading value %d\n", x); 
        return; 
       } 

       (*z).elements[j++] = val; 
      } 

     } 
    } 

    void deallocate(matrix *c) { 

     free((*c).elements); 
     (*c).elements = NULL; 
     (*c).rows = 0; 
     (*c).columns = 0; 
    } 

    void print(matrix z) { 

     int i, j, x; 
     x = 0; 

     for (i = 0; i < z.rows; i++) { 

      printf("[ "); 

      for (j = 0; j < z.columns; j++) { 

       printf("%-4d", z.elements[x++]); 
      } 
      printf("]\n"); 
     } 
    } 

    matrix multiply(matrix a, matrix b) { 

     matrix c; 

     int a1, a2, b1, b2, allc, i, j, x, y, z, alc, addval, val; 

     i = 0; 
     j = 0; 
     alc = 0; 
     val = 0; 
     addval = 0; 

     a1 = a.rows; 
     a2 = a.columns; 
     b1 = b.rows; 
     b2 = b.columns; 

     allc = (a1 * b2); 

     c.elements = (int *)calloc(allc, sizeof(int)); 
     c.columns = a1; 
     c.rows = b2; 

     if (a2 != b1) { 
      printf("\n\nThe inner dimensions of your matrices do not match! Multiplication cannot be done!\n\n"); 
      exit(1); 
     } 


     for (x = 0; x < c.rows; x++) { 

      for (y = 0; y < c.rows; y++) { 

       for (z = 0; z < c.rows; z++) { 

        i = (i * c.rows); 

        addval = (a.elements[j]) * (b.elements[i]); 

        val += addval; 

        j++; 
        i++; 
       } 
       c.elements[alc] = val; 
       printf("VAL IS: %d\n\n", val); 

       val = 0; 

       i = 0; 
       alc++; 
      } 
     } 

     printf("\n\n"); 

     return c; 
    } 

은, 루프 트리플 중첩은 새로운 배열의 차원에 대한 항목의 정확한 숫자를 인쇄하기에 충분한 시간을 통해 갈 예정이다. 행렬 곱셈을 수행하는 방법을 알고 있지만 올바르게 표현했는지 확신 할 수 없습니다.

예제의 출력은 다음과 같습니다

What is the first dimension of the array? 3 
What is the second dimension of the array? 3 
Matrix Dimension is 3x3 

Enter the value for row 1 column 1: 1 
Enter the value for row 1 column 2: 2 
Enter the value for row 1 column 3: 3 
Enter the value for row 2 column 1: 4 
Enter the value for row 2 column 2: 5 
Enter the value for row 2 column 3: 6 
Enter the value for row 3 column 1: 7 
Enter the value for row 3 column 2: 8 
Enter the value for row 3 column 3: 9 

What is the first dimension of the array? 3 
What is the second dimension of the array? 3 
Matrix Dimension is 3x3 

Enter the value for row 1 column 1: 1 
Enter the value for row 1 column 2: 2 
Enter the value for row 1 column 3: 3 
Enter the value for row 2 column 1: 4 
Enter the value for row 2 column 2: 5 
Enter the value for row 2 column 3: 6 
Enter the value for row 3 column 1: 7 
Enter the value for row 3 column 2: 8 
Enter the value for row 3 column 3: 9 


The answer of Matrix (a * b) is 

[ 1 2 3 ] 
[ 4 5 6 ] 
[ 7 8 9 ] 

    * 

[ 1 2 3 ] 
[ 4 5 6 ] 
[ 7 8 9 ] 

    = 

[ 216847534336951265054271] 
[ 1641572693-138635672036124672] 
[ 1352368309-50514195286739134] 

Press any key to continue . . . 
+0

x, y 및 z는 모두 카운팅 행입니다. 적어도 그 중 하나는 열을 계산해야합니다. 그리고'i'는'c.rows'를 곱한 다음 루프를 통과 할 때마다 증가합니다. 'printf'를 사용하여'i'의 값을 출력하면 원하는 것이 전혀 없음을 알 수 있습니다. – user3386109

+0

주제 끄기 :'print' 함수에서''% -4d "'를''% -3d"'로 바꿀 것입니다. 그것은 어떤 사람들이 3 자리 이상일 때 함께 묶어 버리는 것을 막을 것입니다. – user3386109

답변

0

아래는 행렬 곱셈을 수행 코드의 내 재 작업입니다. 문제는 multiply() 함수에서 발생했습니다. 변수 j을 단지 증가시킴으로써 a 행렬을 걷는 것이 운명이라는 것을 알 수 있습니다. 행렬 a의 모든 요소가 여러 번 곱셈에 참여합니다.

포인터를 전달하고 행렬 구조를 값으로 직접 전달/반환하는 대신 모든 루틴을 매트릭스 구조로 전달하도록 루틴을 변경했습니다. 나는 이것이 더 일관성 있고 쉽게 따르기 쉽다고 생각하지만, 당신이 그것을 이와 같이 유지한다면, 당신은 당신의 다른 매트릭스 수학 루틴을 동일하게 작동시킬 필요가 있음을 의미합니다.

#include <stdio.h> 
#include <stdlib.h> 

typedef struct { 
    int *elements; 
    int rows; 
    int columns; 
} matrix; 

void read_matrix(matrix *z) { 

    int d1, d2, val; 

    printf("\nWhat is the first dimension of the array? "); 
    int result = scanf("%d", &d1); 

    if (result != 1) { 
     fprintf(stderr, "Something went wrong with your first dimension!\n"); 
     exit(1); 
    } 

    printf("What is the second dimension of the array? "); 
    result = scanf("%d", &d2); 
    if (result != 1) { 
     fprintf(stderr, "Something went wrong with your second dimension!\n"); 
     exit(1); 
    } 

    printf("Matrix Dimension is %dx%d\n", d1, d2); 

    z->elements = calloc(d1 * d2, sizeof(int)); 
    z->rows = d1; 
    z->columns = d2; 

    int x = 0; 
    int j = 0; 

    printf("\n"); 

    for (int i = 0; i < d1; i++) { 

     x++; 

     for (int y = 0; y < d2; y++) { 
      printf("Enter the value for row %d column %d: ", x, y + 1); 
      result = scanf("%d", &val); 
      if (result != 1) { 
       fprintf(stderr, "Something went wrong while reading value (%d, %d)\n", x, y + 1); 
       exit(1); 
      } 

      z->elements[j++] = val; 
     } 
    } 
} 

void deallocate(matrix *c) { 

    free(c->elements); 

    c->elements = NULL; 
    c->rows = 0; 
    c->columns = 0; 
} 

void print(matrix *z) { 

    int x = 0; 

    for (int i = 0; i < z->rows; i++) { 

     printf("[ "); 

     for (int j = 0; j < z->columns; j++) { 

      printf("%-4d", z->elements[x++]); 
     } 

     printf("]\n"); 
    } 
} 

void multiply(matrix *a, matrix *b, matrix *c) { 

    if (a->columns != b->rows) { 
     fprintf(stderr, "The inner dimensions of your matrices do not match! Multiplication cannot be done!\n"); 
     exit(1); 
    } 

    c->elements = calloc(a->rows * b->columns, sizeof(int)); 
    c->columns = b->columns; 
    c->rows = a->rows; 

    int alc = 0; 

    for (int x = 0; x < a->rows; x++) { 

     for (int y = 0; y < b->columns; y++) { 

      int value = 0; 

      for (int z = 0; z < b->rows; z++) { 

       value += a->elements[z + x * a->columns] * b->elements[y + z * b->columns]; 
      } 

      c->elements[alc++] = value; 
     } 
    } 
} 

int main() { 

    matrix a, b, c; 

    read_matrix(&a); 
    read_matrix(&b); 

    multiply(&a, &b, &c); 

    printf("The answer of Matrix (a * b) is \n\n"); 
    print(&a); 
    printf("\n *\n\n"); 
    print(&b); 
    printf("\n =\n\n"); 
    print(&c); 
    printf("\n"); 

    deallocate(&a); 
    deallocate(&b); 
    deallocate(&c); 

    return 0; 
} 
+0

semi-opaque에 대한 또 다른 합리적인 솔루션 (함수 호출에 의해서만 액세스 됨) 구조체는 구조체의 크기 1 배열 인 구조체를 typedef하는 것입니다. GMP는'mpz_t'를 사용하여이 작업을 수행하기 때문에 포인터를 명시 적으로 받아들이고 포인터를 전달할 필요가없고 기본 구조체의 스택 할당을 단순화하면서 (대부분) 매끄러운 암시 적 통과 별 의미론을 전달할 수 있습니다. – ShadowRanger

+0

답변 해 주셔서 감사합니다! 모든 기능과 파트너는 내 교수가 실험실을 요청한 것입니다. 내가 변할 수 있다면 나는 또한 가질 것입니다. 답변 감사합니다! –

+0

@ T.Gon 게시물에 감사를 표시하는 메커니즘에는 여러 가지가 있습니다. 게시물 (질문에 투표해야 함)이 유용하다고 생각하면 (도움이 될만한? 조명?), * upvote * (10 명). 해답이 문제를 해결하거나 해결책을 찾는데 가장 도움이된다면 * 수락 (15 자)하십시오. 질문에 대한 최선의 답변이 추가 크레딧을받을 자격이 있다고 생각되면 현상금을 시작하십시오 (계정에서 명성을 이전하고 다른 사람에게 명성을 이전하는 것). – greybeard