C课程设计矩阵的加减乘混合运算_c课程设计矩阵运算
C课程设计矩阵的加减乘混合运算由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“c课程设计矩阵运算”。
矩阵混合运算
指导教师:
浙江理工大学
班级:
学号:
姓名:
矩阵混合运算 目 录
一、程序要求
二、输入输出范例
三、程序结构分析及关键函数说明
四、程序代码与说明
五、运行结果与分析
六、设计日志及心得体会
一、程序要求及范例
·定义矩阵(维数小于5×5)的加减法和乘法 ·计算输入的若干矩阵的加减法运算和乘法混合运算
·矩阵数目不定,混合运算顺序不定,矩阵数值不定,均有键盘输入控制
·若输入有错,可以随时更改任一矩阵数值
·当输入矩阵不能满足矩阵运算时,提示矩阵维数错误
二、输入输出范例
·输入:
-首先输入每个矩阵的数值,输入矩阵格式如[1 1 1;2 2 2]-输入几个矩阵的混合运算 ·输出:
-输出计算结果
·输入范例: A=[1 1 1;2 2 2] B=[1 0;0 1;1 1] C=[1 0;0 1] D=C+A*B或者D=A*B+C ·输出b->data[i][j];
}
}
return 1;
} }
3.乘运算函数
该程序设计的核心问题是矩阵的乘法运算的逻辑性的编写,在进行矩阵相乘前要判断两矩阵是否能够相乘,即判断内积是否相等,如果能就按照矩阵的相乘方式进行运算,若不能则提示错误并返回,具体的程序段如下:
int multiplyMatrix(Matrix *c, Matrix *a, Matrix *b){
int i, j, k;
if(a->cols!= b->rows){ printf(“矩阵维数输入错误!”);
return 0;
}
else
{
c->rows = a->rows;
c->cols = b->cols;
for(i = 0;i rows;i++)
{
for(j = 0;j cols;j++)
{
c->data[i][j] = 0;
for(k = 0;k cols;k++)
{
c->data[i][j] += a->data[i][k]*b->data[k][j];
}
}
}
return 1;
} }
四、程序代码与说明
#include #include #include #include #define MAX_DIM 6 #define MAX_CHAR 128 typedef struct //结构体定义矩阵 { float data[MAX_DIM][MAX_DIM];//二维数组表示矩阵 int rows;//行 int cols;//列 } Matrix;typedef struct _ListNode //定义一个头结点 { char name[MAX_CHAR];Matrix *mat;struct _ListNode *next;//指向下一个结点 } ListNode;
typedef struct { ListNode *head;//定义一个指向头结点的指针 } MList;enum TYPE {OP, MAT};//枚举类型
typedef struct _Token //定义Token标识符 判断表达式 { union //联合体 取值为 op 和 mat中结构最大的值 { char op;Matrix *mat;};enum TYPE type;//联合体的类型 } Token;typedef struct _Stack //定义栈 { Token **arr;//用数组存储标识符 int n;//数组里标识符的个数 int cap;//数组的大小 } Stack;
Stack* initStack(int cap);//初始化,定义一个空栈 void freeStack(Stack *pStack);//释放栈的空间
void reszieStack(Stack *pStack, int newCap);//重定义栈的大小 void push(Stack *pStack, Token *pToken);//入栈操作 Token* pop(Stack *pStack);//出栈 Token* top(Stack *pStack);//栈顶
int getIndex(char ch);//不同标识符对应不同的操作 char priorMap[9][9] = { {'>', '>', '', '>'}, {'>', '>', '', '>'}, {'>', '>', '>', '>', '', '>'}, {'>', '>', '>', '>', '', '>'}, {'>', '>', '>', '>', '>', '>', '', '>'}, {'>', '>', '>', '>', '>', '>', '', '>'}, {'', '>', '>', '>', '>', '>', '&', '>', '>'}, {'
int addMatrix(Matrix *c, Matrix *a, Matrix *b);//矩阵的加法
int subtractMatrix(Matrix *c, Matrix *a, Matrix *b);//矩阵的减法 int multiplyMatrix(Matrix *c, Matrix *a, Matrix *b);//矩阵的乘法 void printMatrix(Matrix *mat);//输出结果 ListNode *newNode(char name[], Matrix *mat);MList *newMList();void freeNode(ListNode *node);void freeMList(MList *ml);void addNode(MList *ml, ListNode *node);ListNode *parseMat(char line[]);void printLNode(ListNode *node);Matrix *findByName(MList *ml, char name[]);int main(){ printf(“矩阵的混合运算n”);
2]n“);
char line[MAX_CHAR];char name[MAX_CHAR];char *pch;MList *ml = newMList();Matrix *newMat = NULL;
printf(”矩阵范例A=[1 1 1;2 2 printf(“请按范例格式输入n”);
while(1){ fgets(line, MAX_CHAR, stdin);//输入一串字符 if(strlen(line)== 1 && line[0] == 'n'){ continue;} pch = strchr(line, '[');if(pch!= NULL){ ListNode *node = parseMat(line);addNode(ml, node);} else { pch = strchr(line, '=');*pch = ' ';char *expr = pch+1;Stack *pStackVals = initStack(16);Stack *pStackOps = initStack(16);Token *pToken = NULL, *pTokenA = NULL, *pTokenB = NULL;pToken =(Token *)malloc(sizeof(Token));pToken->op = '#';pToken->type = OP;push(pStackOps, pToken);int len = strlen(expr);expr[len++] = '#';int b=0, e=0, cnt;char ch;while(b!= len){ ch = expr[b];if(ipace(ch))//判断是否为空格 { b++;} else if(isalpha(ch))//矩阵 {
cnt = 0;e = b;while(isalpha(expr[e])){ name[cnt++] = expr[e++];
} name[cnt] = ' ';b = e;Matrix *mat = findByName(ml, name);pToken =(Token *)malloc(sizeof(Token));pToken->type = MAT;pToken->mat = mat;push(pStackVals, pToken);
} else // 操作符 { while(1){ char cmp = priorMap[getIndex(top(pStackOps)->op)][getIndex(ch)];if(cmp == 'type = OP;pToken->op = ch;push(pStackOps, pToken);break;} else if(cmp == '='){ free(pop(pStackOps));break;} else if(cmp == '>'){ pToken = pop(pStackOps);switch(pToken->op){ case '+': pTokenB = pop(pStackVals);pTokenA = pop(pStackVals);newMat = newMatrix(0, 0);addMatrix(newMat, pTokenA->mat, pTokenB->mat);free(pTokenA);free(pTokenB);pToken =(Token *)malloc(sizeof(Token));pToken->type = MAT;pToken->mat = newMat;
push(pStackVals, pToken);break;case '-': pTokenB = pop(pStackVals);pTokenA = pop(pStackVals);newMat = newMatrix(0, 0);subtractMatrix(newMat, pTokenA->mat, pTokenB->mat);free(pTokenA);free(pTokenB);pToken =(Token *)malloc(sizeof(Token));pToken->type = MAT;pToken->mat = newMat;push(pStackVals, pToken);break;case '*': pTokenB = pop(pStackVals);pTokenA = pop(pStackVals);newMat = newMatrix(0, 0);multiplyMatrix(newMat, pTokenA->mat, pTokenB->mat);free(pTokenA);free(pTokenB);pToken =(Token *)malloc(sizeof(Token));pToken->type = MAT;pToken->mat = newMat;push(pStackVals, pToken);break;
} } } b++;} } newMat = top(pStackVals)->mat;freeStack(pStackVals);freeStack(pStackOps);break;} } ListNode *resNode = newNode(line, newMat);printLNode(resNode);freeMList(ml);
return 0;} Matrix *newMatrix(int rows, int cols){ Matrix *mat =(Matrix *)malloc(sizeof(Matrix));mat->rows = rows;mat->cols = cols;return mat;} void freeMatrix(Matrix *mat){ free(mat);mat = NULL;} int addMatrix(Matrix *c, Matrix *a, Matrix *b){ int i, j;if(a->rows!= b->rows || a->cols!= b->cols)// error to add { printf(“矩阵维数输入错误!”);return 0;} else { c->rows = a->rows;c->cols = a->cols;for(i = 0;i rows;i++){ for(j = 0;j cols;j++){ c->data[i][j] = a->data[i][j] + b->data[i][j];} } return 1;} } int subtractMatrix(Matrix *c, Matrix *a, Matrix *b){ int i, j;if(a->rows!= b->rows || a->cols!= b->cols)// error to add { “);return 0;
printf(”矩阵维数输入错误!
} else { c->rows = a->rows;c->cols = a->cols;for(i = 0;i rows;i++){ for(j = 0;j cols;j++){ c->data[i][j] = a->data[i][j]-b->data[i][j];}
} return 1;} } int multiplyMatrix(Matrix *c, Matrix *a, Matrix *b){ int i, j, k;if(a->cols!= b->rows){ return 0;} else { c->rows = a->rows;c->cols = b->cols;for(i = 0;i rows;i++){ for(j = 0;j cols;j++){ c->data[i][j] = 0;for(k = 0;k cols;k++){ c->data[i][j] += a->data[i][k]*b->data[k][j];}
} } return 1;} } void printMatrix(Matrix *mat)
{ int i, j;for(i = 0;i rows;i++){ for(j = 0;j cols;j++){ printf(“t%.2f”, mat->data[i][j]);} printf(“n”);} } void printLNode(ListNode *node){ printf(“%s=n”, node->name);printMatrix(node->mat);} ListNode *newNode(char name[], Matrix *mat){ ListNode *node =(ListNode*)malloc(sizeof(ListNode));strcpy(node->name, name);node->mat = mat;node->next = NULL;
return node;} MList *newMList(){ MList *ml =(MList *)malloc(sizeof(MList));ml->head = NULL;
return ml;} void freeNode(ListNode *node){ if(node == NULL){ return;} freeMatrix(node->mat);free(node);} void freeMList(MList *ml){
if(ml == NULL){ return;} ListNode *currNode, *temp;currNode = ml->head;while(currNode!= NULL){ temp = currNode;freeNode(temp);currNode = currNode->next;} free(ml);} void addNode(MList *ml, ListNode *node){ node->next = ml->head;ml->head = node;} ListNode *parseMat(char line[]){ char tmp[MAX_CHAR];Matrix *mat = newMatrix(0, 0);char *pch, *pch1, *pstop;pch = strchr(line, '=');*pch = ' ';ListNode *node = newNode(line, mat);char *data = pch+2;pstop = strchr(data, ']');*pstop = ' ';pch = strtok(data, “;”);while(pch!= NULL){ strcpy(tmp, pch);pch1 = strtok(tmp, “ ”);mat->cols = 0;while(pch1!= NULL){ mat->data[mat->rows][mat->cols++] = atof(pch1);pch1 = strtok(NULL, “ ”);
} mat->rows++;
if(pch+strlen(pch)== pstop){ break;} pch = strtok(pch+strlen(pch)+1, “;”);} return node;} Matrix *findByName(MList *ml, char name[]){ ListNode *currNode = ml->head;while(currNode!= NULL){ if(strcmp(name, currNode->name)== 0){ return currNode->mat;} currNode = currNode->next;} return NULL;} Stack* initStack(int cap){ int i;Stack *pStack =(Stack *)malloc(sizeof(Stack));pStack->cap = cap;pStack->n = 0;pStack->arr =(Token **)malloc(cap * sizeof(Token *));for(i = 0;i arr[i] = NULL;} return pStack;} void freeStack(Stack *pStack){ int i;if(pStack->arr!= NULL){ for(i = 0;i n;i++){ free(pStack->arr[i]);}
free(pStack->arr);} free(pStack);} void reszieStack(Stack *pStack, int newCap){ int i;Token **temp =(Token **)malloc(newCap * sizeof(Token *));for(i = 0;i n;i++){ temp[i] = pStack->arr[i];} free(pStack->arr);pStack->arr = temp;pStack->cap = newCap;} void push(Stack *pStack, Token *pToken){ if(pStack->n == pStack->cap){ reszieStack(pStack, 2 * pStack->cap);} pStack->arr[pStack->n++] = pToken;} Token* pop(Stack *pStack){ Token *pToken = pStack->arr[--pStack->n];if(pStack->n > 0 && pStack->n == pStack->cap / 4){ reszieStack(pStack, pStack->cap / 2);} return pToken;} Token* top(Stack *pStack){ Token *pToken = pStack->arr[pStack->n-1];return pToken;} int getIndex(char ch)//在前面的映射中获取操作符的索引 { int index;switch(ch){ case '+':
index = 0;break;case '-': index = 1;break;case '*': index = 2;break;case '/': index = 3;break;case '^': index = 4;break;case '!': index = 5;break;case '(': index = 6;break;case ')': index = 7;break;case '#': index = 8;break;} return index;}
五、运行结果
六、心得与体会
刚开始觉得这个大作业实现并不困难,要求小于五行五列,用一个宏定义就可以解决。然后二维数组A[i][j]本身就是一个i行i列的矩阵,进行矩阵加法和减法的时候,用i=j判断维数,然后再用两个for循环将各行行列的元素相加减。进行矩阵乘法的时候,判断两个矩阵的内积是否相等,再各行各列的元素相乘放入新的一个矩阵就行。但是实际编程的过程中,遇到的包括但不限于如下问题:1.要求输入任意个数的矩阵如何做到。2.上述讲的思路仅仅局限于单独加减或单独相乘,如何做到混合运算。3.按范例输入的时候空格如何处理?4.输入矩阵错误的时候,如何做到修改矩阵(单单用二维数组无法直接修改数组元素)?
程序=数据结构+算法,通过这次作业我深深体会到了编程的特点。在翻阅了《数据结构与算法》严蔚敏版后,我用两个栈,一个存放操作符(+,-,*),另一个存放矩阵(用struct定义矩阵),再用指针指向栈顶元素,使用完后释放栈内存,这样就可以解决问题1.再用ipace函数跳过空格,解决了问题3.对于问题2,的解决,因为照范例的输入,我输入的应该是一个字符串(若用二维数组的方法输入,输入的仅仅是数值,达不到demo的要求),所以我创建了一个list然后用指针指向头结点,然后isalpha可以用来判断矩阵的名称,然后依赖头结点来判断字符串的输入(operator or martrix),分别放入两个栈中。再者就是用switch语气,与混合运算的要求十分的契合。
这次作业让我认识了编程不能仅仅满足于课堂上的知识点,所谓师父领进门修行在个人,上面提到的数据结构,ipace function,isalpha function,都不是简简单单的认真听课能掌握的,多动手,多实践,遇到问题可能通过强大的互联网结合自己所学与思考来解决。