Я бы хотел выполнить матричные операции, такие как A * B + C.Матрица читается из файла, отформатированного таким образом:
1 3 4 5
0 1 0 6
0 0 1 7
2 7 0 1
*
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
*
1 2
3 4
Я уже могу читать матрицы и операторы, я не знаю, как выполнять операции.Предположим, что у вас есть: A B + C, поэтому вы должны сначала выполнить (A B), а затем, я думаю, лучшая стратегия состоит в том, что этот результат становится B и, в конечном счете, выполняет B + C.Я не уверен, как перераспределить B и выполнить операции в правильном порядке.Чтобы было проще, я сейчас рассматриваю умножение.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MINA 2 /* if you need a constant, #define one (or more) */
#define MAXC 1024
struct m{
int **data;
size_t row, col;
};
void multiply(struct m *A, struct m *B)
{
int i, j, k;
struct m C;
C.data = malloc(sizeof(int) * A->row);
C.row = A->row;
C.col = B->col;
/*initialize C to 0*/
for ( j = 0; j < C.row; j++) /* for each row */
for ( k = 0; k < C.col; k++) /* for each col */
C.data[j][k] = 0; /* output int */
// Multiplying matrix A and B and storing in C.
for(i = 0; i < A->row; ++i)
for(j = 0; j < B->col; ++j)
for(k=0; k < A->col; ++k)
C.data[i][j] += A->data[i][k] * B->data[k][j];
//free(B->data);
*B = C;
}
void print_matrix(struct m *matrix)
{
int j, k;
for ( j = 0; j < matrix->row; j++) { /* for each row */
for ( k = 0; k < matrix->col; k++) /* for each col */
printf ("%4d", matrix->data[j][k]); /* output int */
putchar ('\n'); /* tidy up with '\n' */
free (matrix->data[j]); /* free row */
}
free (matrix->data); /* free pointers */
}
int main (int argc, char **argv)
{
struct m *matrix; /* pointer to array type */
size_t aidx = 0, maxa = MINA, /* matrix index, max no. allocated */
nrow = 0, ncol = 0, /* current row/col count */
maxrow = MINA, nop = 0; /* alloc'ed rows current array, no. op */
char buf[MAXC], /* buffer to hold each line */
op[MAXC]; /* array to hold operators */
int i;
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* allocate/validate maxa no. of matrix */
if (!(matrix = calloc (maxa, sizeof *matrix))) {
perror ("calloc-matrix");
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line into buf */
int off = 0, n; /* offset from start of line, n for "%n" */
size_t tidx = 0; /* temporary array index */
char *p = buf; /* pointer to advance in sscanf */
int tmp[MAXC / 2 + 1]; /* temporary array, sized for max no. ints */
if (!isdigit(*buf)) { /* if 1st char non-digit, end of array */
op[nop++] = *buf; /* store operator */
if (nrow) /* if rows stored */
matrix[aidx++].row = nrow; /* set final number of rows */
nrow = ncol = 0; /* reset nrow/ncol counters */
maxrow = MINA; /* reset allocate rows */
continue; /* get next line of data */
}
if (aidx == maxa) { /* check if no. of structs need realloc */
void *atmp = realloc (matrix, 2 * maxa * sizeof *matrix); /* realloc */
if (!atmp) { /* validate */
perror ("realloc-matrix");
return 1;
}
matrix = atmp; /* assign new block to matrix */
/* set all new bytes zero (realloc doesn't initialize) */
memset (matrix + maxa, 0, maxa * sizeof *matrix);
maxa *= 2; /* update struct count */
}
/* read all integers in line into tmp array */
while (sscanf (p + off, "%d%n", &tmp[tidx], &n) == 1) {
off += n;
tidx++;
}
if (tidx) { /* if integers stored in tmp */
if (nrow == 0) { /* if first row in array */
/* allocate/validate maxrow pointers */
if (!(matrix[aidx].data = malloc (maxrow * sizeof *matrix[aidx].data))) {
perror ("malloc-matrix[aidx].data");
return 1;
}
matrix[aidx].col = tidx; /* fix no. cols on 1st row */
}
else if (nrow == maxrow) { /* realloc of row ptrs req'd? */
/* always realloc with temp ptr */
void *atmp = realloc (matrix[aidx].data, 2 * maxrow * sizeof *matrix[aidx].data);
if (!atmp) { /* validate every alloc/realloc */
perror ("realloc-matrix[aidx].data");
return 1;
}
matrix[aidx].data = atmp; /* assign realloced block to ptr */
maxrow *= 2; /* update maxrow to current alloc */
}
if (tidx != matrix[aidx].col) { /* validate no. of columns */
fprintf (stderr, "error: invalid number of columns " "matrix[%zu].data[%zu]\n", aidx, nrow);
return 1;
}
if (!(matrix[aidx].data[nrow] = /* allocate storagre for integers */
malloc (tidx * sizeof *matrix[aidx].data[nrow]))) {
perror ("malloc-matrix[aidx].data[nrow]");
return 1;
}
/* copy integers from tmp to row, increment row count */
memcpy (matrix[aidx].data[nrow++], tmp, tidx * sizeof *tmp);
}
} /*end of while (fgets (buf, MAXC, fp)) */
if (nrow) /* handle final array */
matrix[aidx++].row = nrow; /* set final number of rows */
if (fp != stdin) fclose (fp); /* close file if not stdin */
/*Printing the file */
for(i=0; i<aidx; i++){
print_matrix(&matrix[i]);
printf("%c\n",op[i]);
}
printf("=\n");
for(i=0; i<aidx; i++){
if(op[i] =='*')
multiply(&matrix[aidx],&matrix[aidx+1]);
}
print_matrix(&matrix[aidx-1]); /*Print the result */
free (matrix); /* free structs */
return 0;
}