【发布时间】:2020-07-06 15:07:42
【问题描述】:
我有一个大问题。我的老师告诉我,我必须写一个程序。对于向量、矩阵、标量等的运算,我必须使用逆波兰表示法。例如,当你计算时,你写 4+5-6。在 RPN 中,你会这样写,这样 45+6-。 https://www.prodevelopertutorial.com/given-an-expression-in-reverse-polish-notation-evaluate-it-and-get-the-output-in-c/ 我必须将输出写入文件并显示在屏幕上
但我的程序会困难得多。
- 我不会在计算中使用数字,而是向量、标量、矩阵。
- 我必须从文件中读取值
- 我必须使用快捷方式; V 是向量,S 是标量,M 是矩阵
- 此外,我必须使用更多的操作,而不仅仅是简单的操作 还有
+ adding
- subtraction
* multiplication
/ division
T transpose of an array
. scalar product
x vector product
D determinant
R inverse matrix
这是我的数据文件
S scalar1 3
S scalar2 5
V vector1 3
2 4 7
V vector2 3
3 6 1
M matrix_A 3 3
1 2 3
4 5 6
7 8 9
M matrix_B 3 3
9 8 7
6 5 4
3 2 1
您看到我必须创建具有快捷方式 M/V/S、元素名称、维度(矩阵的 dimX 和 Y)和值的结构。 稍后我会在这个数据文件中添加类似的操作
matrix_A
matric_B
*
这是我的 io 函数文件 operation_io.c
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME 20
#define MAX_ARRAY_DIM 50
typedef struct Vector {
char keyWordV;
char name[MAX_NAME];
int dim;
double data[MAX_ARRAY_DIM];
} Vector;
typedef struct Scalar {
char keyWordS;
char name[MAX_NAME];
double data;
} Scalar;
typedef struct Matrix {
char keyWordM;
char name[MAX_NAME];
int dimX;
int dimY;
double data[MAX_ARRAY_DIM][MAX_ARRAY_DIM];
} Matrix;
typedef struct Element {
char type;
union {
Scalar s;
Vector v;
Matrix m;
} elem;
} Element;
void readScalar(FILE *file, Scalar* s) {
fscanf(file, " %s ", &s->name[0]);
fscanf(file, "%10lf", &s->data);
}
void writeScalar(FILE *file, Scalar* s) {
fprintf(file, "S");
fprintf(file, " %s \n", s->name);
fprintf(file, "%10.2lf \n", s->data);
}
void showScalar(Scalar* s) {
printf("S");
printf(" %s \n", s->name);
printf("%10.2lf \n", s->data);
}
void readVector(FILE *file, Vector* v) {
fscanf(file, " %s %d ", &v->name[0], &v->dim);
for (int j = 0; j < v->dim; ++j) {
fscanf(file, "%10lf", &v->data[j]);
}
}
void writeVector(FILE *file, Vector* v) {
fprintf(file, "V");
fprintf(file, " %s %d \n", v->name, v->dim);
for (int j = 0; j < v->dim; ++j) {
fprintf(file, "%10.2lf ", v->data[j]);
}
fprintf(file, "\n");
}
void showVector(Vector* v) {
printf("V");
printf(" %s %d \n", v->name, v->dim);
for (int j = 0; j < v->dim; ++j) {
printf("%10.2lf ", v->data[j]);
}
printf("\n");
}
void readMatrix(FILE *file, Matrix* m) {
fscanf(file, " %s %d %d", &m->name[0], &m->dimX, &m->dimY);
for (int i = 0; i < m->dimX; ++i)
for (int j = 0; j < m->dimY; ++j)
fscanf(file, "%10lf", &m->data[i][j]);
}
void writeMatrix(FILE *file, Matrix* m) {
fprintf(file, "M");
fprintf(file, " %s %d %d \n", m->name, m->dimX, m->dimY);
for (int i = 0; i < m->dimX; ++i)
{
for (int j = 0; j < m->dimY; ++j)
{
fprintf(file, "%10.2lf", m->data[i][j]);
}
fprintf(file, "\n");
}
}
void showMatrix(Matrix* m) {
printf("M");
printf(" %s %d %d \n", m->name, m->dimX, m->dimY);
for (int i = 0; i < m->dimX; ++i)
{
for (int j = 0; j < m->dimY; ++j)
{
printf("%10.2lf", m->data[i][j]);
}
printf("\n");
}
}
void readElement(FILE *file, Element* e) {
char type;
fscanf(file, " %c ", &type);
switch (type) {
case 'S':
e->type = 'S';
readScalar(file, &e->elem.s);
writeScalar(file, &e->elem.s);
showScalar(&e->elem.s);
break;
case 'V':
e->type = 'V';
readVector(file, &e->elem.v);
writeVector(file, &e->elem.v);
showVector(&e->elem.v);
break;
case 'M':
e->type = 'M';
readMatrix(file, &e->elem.m);
writeMatrix(file, &e->elem.m);
showMatrix(&e->elem.m);
break;
default:
fputs("Error: unknown token!\n", stderr);
exit(1);
}
}
void policz(FILE *file, Element* e1, Element* e2, Element* e3)
{
char type1, type2, type3;
fscanf(file, " %c ", &type1);
fscanf(file, " %c ", &type2);
fscanf(file, " %c ", &type3);
}
int isOperator(char ch){
if(ch == '+'|| ch == '-'|| ch == '*'|| ch == '/' || ch == '^')
return 1;//character is an operator
return -1;//not an operator
}
int isOperand(char ch){
if(ch == 'S' || ch == 'V' || ch == 'M')
return 1;//character is an operand
return -1;//not an operand
}
#define MAX_D 256
double stack[MAX_D];
int depth;
void die(const char *msg)
{
fprintf(stderr, "%s", msg);
abort();
}
void push(double v)
{
if (depth >= MAX_D) die("stack overflow\n");
stack[depth++] = v;
}
double pop()
{
if (!depth) die("stack underflow\n");
return stack[--depth];
}
float operation(int a, int b, char op){ //bede dopiero pisal funkcje
//Perform operation
if(op == '+')
return 1;
else if(op == '-')
return 1;
else if(op == '*')
return 1;
else if(op == '/')
return 1;
else
return 1; //return negative infinity
}
operation_io.h
#ifndef WEKTORY
#define WEKTORY
typedef struct Scalar Scalar;
typedef struct Vector Vector;
typedef struct Matrix Matrix;
typedef struct Element Element;
void readScalar(FILE *file, Scalar* s);
void writeScalar(FILE *file, Scalar* s);
void showScalar(Scalar* s);
void readVector(FILE *file, Vector* v);
void writeVector(FILE *file, Vector* v);
void showVector(Vector* v);
void readMatrix(FILE *file, Matrix* m);
void writeMatrix(FILE *file, Matrix* m);
void showMatrix(Matrix* m);
void readElement(FILE *file, Element* e);
void die(const char *msg);
void push(double v);
double pop();
float operation(int a, int b, char op);
#endif
这是我的主程序。 main.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "operation_io.h"
#define MAX_NAME 20
#define MAX_ARRAY_DIM 50
typedef struct Vector {
char keyWordV;
char name[MAX_NAME];
int dim;
double data[MAX_ARRAY_DIM];
} Vector;
typedef struct Scalar {
char keyWordS;
char name[MAX_NAME];
double data;
} Scalar;
typedef struct Matrix {
char keyWordM;
char name[MAX_NAME];
int dimX;
int dimY;
double data[MAX_ARRAY_DIM][MAX_ARRAY_DIM];
} Matrix;
typedef struct Element {
char type;
union {
Scalar s;
Vector v;
Matrix m;
} elem;
} Element;
int main (int argc, char *argv[])
{
FILE *wz, *wc;
if (argc != 3) {
printf("Wrong arguments number\n");
printf("I should run this way:\n");
printf("%s source\n",argv[0]);
exit(1);
}
if( (wz= fopen(argv[1],"r")) == NULL) {
printf("Open error %s\n", argv[1]);
exit(1);
}
if( (wc= fopen(argv[2], "w")) == NULL) {
printf("Open error %s\n", argv[2]);
exit(2);
}
Element elements[10];
for (int i = 0; i < 6; i++) {
readElement(wz, &elements[i]);
}
fclose(wz);
fclose(wz);
return 0;
}
带有算术运算的我的文件。 operation_m.c 是空的,因为我没有开始编写这些函数,因为我有问题。 我想使用这样的算法https://rosettacode.org/wiki/Parsing/RPN_calculator_algorithm#C 但是我的情况比较复杂,因为我没有使用数字而且我有更多的操作(不仅是+、-、*、=)
我现在有 3 个问题
- 我的书写功能不工作,但我的屏幕显示功能工作正常。
- 我不知道,我的程序如何知道我使用矩阵、向量或标量? 例如我有
matrix_A
matrix_B
*
我的程序如何知道名称 matrix_A 和 matrix_B 表示 2 个矩阵的乘法并使用函数 multMatrices()(我还没有编写此函数,但我会编写)。我有个主意。我想用快捷方式连接名称。所以我的程序会发现我想乘以矩阵而不是标量和矩阵。我在这里有我的对象 - 元素数组
Element elements[10];
for (int i = 0; i < 6; i++) {
readElement(wz, &elements[i]);
}
所以我必须知道如何从这个数组中使用一个合适的元素,那么该怎么做呢?
- 在这个算法中,我没有一元运算https://rosettacode.org/wiki/Parsing/RPN_calculator_algorithm#C,但在我的程序中,我会有矩阵的转置等。所以我必须在 switch case 中添加一些可能???
【问题讨论】:
-
警告
456+-是4-(5+6)不是4+5-6 -
how my program will know that I use matrix, vector or scalar? For example I have matrix_A matrix_B *你需要一个字典来从它的名字中找到一个元素 -
您可以通过检查堆栈了解
*应该应用于哪些对象。如果栈顶的两项是矩阵,那么*就是矩阵运算。如果堆栈顶部的两个对象不兼容,则会抛出错误。 -
printf(...); exit(1);是一个错误。它应该是fprintf(stderr, ...); exit(1);或printf(...); exit(0);
标签: arrays c matrix struct rpn