数据结构实验需要使用后缀表达式进行计算的设计
自己写的可以实现简单的‘+-*/’运算以及包括‘() [] {} 指数 小数 2e3’等的运算,用于交作业,功能很少,代码如下
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <stdbool.h> #include <math.h> //定义操作数的最大位数 #define MAX 64 typedef struct element { char data[MAX]; struct element * pre; struct element * next; } ELE; //用来判断是否是操作符 bool is_op(char *op); //判断优先级 bool is_high(char *op); //操作符进入操作符栈 void push_op_to_opstack(char op); //压入后缀表达式操作符即计算 void push_op_to_expression(char *op); //压入后缀表达式操作数 void push_num_to_expression(void); //操作符栈下标 static int OP_INDEX = 0; //操作符栈 char op_stack[MAX]; //表达式的头 ELE * expression_header = NULL; //尾节点 ELE * tail_expression = NULL; //新节点 ELE * node; int main(void) { //为表达式头节点分配内存并初始化 expression_header = (ELE *)malloc(sizeof(ELE)); if (expression_header == NULL) { printf("Error "); return 0; } else { expression_header->data[0] = '#'; expression_header->next = NULL; expression_header->pre = NULL; } push_num_to_expression(); //所有的操作符出栈 while(OP_INDEX > 0) { push_op_to_expression(&op_stack[OP_INDEX-1]); OP_INDEX--; } printf("计算结果%s ",tail_expression->data); return 0; } //判断是不是操作符 bool is_op(char *op) { if ((*op) == '+' || (*op) == '-'|| (*op) == '*' || (*op) == '/' || (*op) == '(' || (*op) == ')' || (*op) == '[' || (*op) == ']' || (*op) == '{' || (*op) == '}' || (*op) == '^' || (*op) == '=' || (*op) == ' ') return true; return false; } //判断操作符的优先级 bool is_high(char *op) { if (OP_INDEX == 0) return false; //只需要将规则写入这里 if ((op_stack[OP_INDEX-1] == '+') && (*op == '+' || *op == '-')) return true; if ((op_stack[OP_INDEX-1] == '-') && (*op == '+' || *op == '-')) return true; if ((op_stack[OP_INDEX-1] == '*') && (*op == '+' || *op == '-' || *op == '*' || *op == '/')) return true; if ((op_stack[OP_INDEX-1] == '/') && (*op == '+' || *op == '-' || *op == '*' || *op == '/')) return true; if ((op_stack[OP_INDEX-1] == '^') && (*op == '+' || *op == '-' || *op == '*' || *op == '/' || *op == '^')) return true;//最大的规则 if (*op == ')' || *op == ']' || *op == '}' || *op == '=') return true; return false; } //操作符进入操作符栈 void push_op_to_opstack(char op) { if (OP_INDEX == 0) { op_stack[OP_INDEX] = op; OP_INDEX++; return; } else { //判断优先级 while (is_high(&op)) { if (op_stack[OP_INDEX-1] == '(' || op_stack[OP_INDEX-1] == '[' || op_stack[OP_INDEX-1] == '{') break; //当前操作符栈顶的操作符进入后缀表达式 push_op_to_expression(&op_stack[OP_INDEX-1]); //当前操作符指针减1 OP_INDEX--; } //如果是括号,或者是中括号,就将之前的括号或中括号去掉 if (op == ')' || op == ']' || op == '}' || op == '=') { OP_INDEX--; return; } //读入的操作符入栈 op_stack[OP_INDEX] = op; //指针自加一 OP_INDEX++; return; } } //将操作符压入栈中,即进行计算 //其实不用压栈,直接将弹出的操作符加入后最表达式队列进行计算 void push_op_to_expression(char *op) { double last_number; double first_number; if (*op == '=') return; last_number = atof(tail_expression->data); //释放内存 tail_expression = tail_expression->pre; free(tail_expression->next); tail_expression->next = NULL; first_number = atof(tail_expression->data); switch ((*op)) { case '+': first_number += last_number; break; case '-': first_number -= last_number; break; case '*': first_number *= last_number; break; case '/': first_number /= last_number; break; case '^': first_number = pow(first_number, last_number); break; default: printf("输入有误 "); exit(0); break; } //将计算的结果存回字符数组 sprintf(tail_expression->data, "%f", first_number); } void push_num_to_expression(void) { char c; int i; do { i = 0; node = (ELE *)malloc(sizeof(ELE)); if (node == NULL) { printf("Error "); return; } //将链表连接 if (expression_header->next == NULL) { expression_header->next = node; node->pre = expression_header; node->next = NULL; tail_expression = node; } else { tail_expression->next = node; node->pre = tail_expression; node->next = NULL; tail_expression = node; } //开始输入 do { c = getchar(); if (c == ' ') c = '='; //如果是操作符 if (is_op(&c)) { if (i == 0) { //如果第一个是操作符,删除此节点 //操作符入栈 tail_expression = node->pre; free(tail_expression->next); tail_expression->next = NULL; push_op_to_opstack(c); break; } //添加结束符 node->data[i] = '