C言語関係掲示板

過去ログ

No.470.行列A,Bの積ABが定義できるときABを計算

[戻る] [ホームページ]
No.3398

教えて下さい!!!!!!!
投稿者---雅史(2002/11/10 16:09:30)


多次元配列の問題です。

1、二つの行列A,Bを入力し、AとBの積ABが定義できるときABを計算するプログラムです。

僕の考えは行列Aが何行か入力し次に何列か。同様にBも、次に行列AのA列と行列BのB行が同じときに計算するのですが、全然わかりません。

No.3400

Re:教えて下さい!!!!!!!
投稿者---aki(2002/11/10 20:37:00)


「教えてください」という題名の投稿にレスをつけるのは
少し気が引けます。そういう投稿を認めることになるので。
「掲示板ご利用上の注意」を読んでください。

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

typedef struct {
    int x;
    int y;
    double *elm;
} Matrix;

void *alloc_elm(int x, int y)
{
    void *p = malloc(sizeof(double) * x * y);
    if (p == NULL)
        fprintf(stderr, "out of memory"), exit(1);
    return p;
}
void input(int symbol, Matrix *m)
{
    int x, y;

    printf("type of %c? ", symbol);
    scanf("%d%d", &m->y, &m->x);
    m->elm = alloc_elm(m->x, m->y);

    for (y = 0; y < m->y; y++) {
        printf("%d行目: ", y + 1);
        for (x = 0; x < m->x; x++)
            scanf("%lf", &m->elm[y * m->x + x]);
    }
}

int multi(Matrix *pro, Matrix *a, Matrix *b)
{
    int x, y, i;

    if (a->x != b->y) return 1;

    pro->x = b->x;
    pro->y = a->y;
    pro->elm = alloc_elm(pro->x, pro->y);

    for (y = 0; y < a->y; y++)
        for (x = 0; x < b->x; x++) {
            double v = 0;
            for (i = 0; i < a->x; i++)
                v += a->elm[y * a->x + i] * b->elm[i * b->x + x];
            pro->elm[y * pro->x + x] = v;
        }
    return 0;
}

void print(const Matrix *m)
{
    int x, y;

    for (y = 0; y < m->y; y++) {
        for (x = 0; x < m->x; x++)
            printf("%4g", m->elm[y * m->x + x]);
        putchar('\n');
    }
}

int main(void)
{
    Matrix a, b, pro;

    input('A', &a);
    input('B', &b);
    if (multi(&pro, &a, &b) != 0)
        return printf("A×Bは計算できません\n"), 1;
    print(&pro);
    return 0;
}


No.3402

Re:教えて下さい!!!!!!!
投稿者---aki(2002/11/11 00:20:52)


オブジェクト指向的にしてみました。

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

typedef struct Matrix *Matrix;
typedef const struct Matrix *const_Matrix;

Matrix make_matrix(int symbol);
Matrix multi(const_Matrix a, const_Matrix b);

void print(const_Matrix m);
void delete(Matrix m);

int main(void)
{
    Matrix a = make_matrix('A');
    Matrix b = make_matrix('B');
    Matrix product = multi(a, b);
    if (product == NULL)
        return printf("A×Bは計算できません\n"), 1;
    print(product);

    delete(a); delete(b); delete(product);
    return 0;
}

struct Matrix {
    int x, y;
    double *elm;
};

static Matrix alloc_matrix(int x, int y)
{
    Matrix m = malloc(sizeof(struct Matrix));
    if (m == NULL)
        fprintf(stderr, "out of memory"), exit(1);
    m->x = x;
    m->y = y;
    m->elm = malloc(sizeof(double) * x * y);
    if (m->elm == NULL)
        fprintf(stderr, "out of memory"), exit(1);
    return m;
}

Matrix make_matrix(int symbol)
{
    int x, y, xx, yy;
    Matrix m;

    printf("type of %c? ", symbol);
    scanf("%d%d", &yy, &xx);
    m = alloc_matrix(xx, yy);

    for (y = 0; y < m->y; y++) {
        printf("%d行目: ", y + 1);
        for (x = 0; x < m->x; x++)
            scanf("%lf", &m->elm[y * m->x + x]);
    }
    return m;
}

Matrix multi(const_Matrix a, const_Matrix b)
{
    int x, y, i;
    Matrix pro;

    if (a->x != b->y) return NULL;

    pro = alloc_matrix(b->x, a->y);

    for (y = 0; y < pro->y; y++)
        for (x = 0; x < pro->x; x++) {
            double v = 0;
            for (i = 0; i < a->x; i++)
                v += a->elm[y * a->x + i] * b->elm[i * b->x + x];
            pro->elm[y * pro->x + x] = v;
        }
    return pro;
}

void print(const_Matrix m)
{
    int x, y;

    for (y = 0; y < m->y; y++) {
        for (x = 0; x < m->x; x++)
            printf("%4g", m->elm[y * m->x + x]);
        putchar('\n');
    }
}

void delete(Matrix m)
{
    free(m->elm);
}


No.3403

Re:教えて下さい!!!!!!!
投稿者---かずま(2002/11/11 01:29:52)


> オブジェクト指向的にしてみました。

alloc_matrix で malloc を 2回呼んでいるので、
delete でも free を 2回呼んだほうがよいのでは。
void delete(Matrix m)
{
    free(m->elm);
    free(m);
}


No.3405

Re:教えて下さい!!!!!!!
投稿者---aki(2002/11/11 11:43:35)


>alloc_matrix で malloc を 2回呼んでいるので、
>delete でも free を 2回呼んだほうがよいのでは。
>
>void delete(Matrix m)
>{
>    free(m->elm);
>    free(m);
>}

あ、そうでした。