为方便实现计算中缀表达式,我们采用先将中缀表达式转换成后缀表达式,再计算后缀表达式的方式。(如果不会转换,请转http://t.csdn.cn/96UFw)
后缀表达式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。
由于后缀表达式的运算符在两个操作数的后面,那么计算机在解析后缀表达式的时候,只需要从左向右扫描,也就是只需要向前扫描,而不用回头扫描,遇到运算符就将运算符放在前面两个操作符的中间(这里先不考虑乘方类似的单目运算),一直运算到最右边的运算符,那么就得出运算结果了。
要实现对后缀表达式的求值:对整个字符串进行遍①
①将字符串型的数字转换为整型(或者浮点型)。
②遇到数字直接入栈;
③遇到运算符(~),则将栈顶的两个数字出栈,并将b~a的指压入栈中。
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
#define MAX 100
typedef struct SNode* Stack;
struct SNode {
int data;
Stack next;
};
//初始化空栈
Stack Init() {
Stack s = (Stack)malloc(sizeof(SNode*));
s->next = NULL;
return s;
}
//创建新结点
Stack creat_node(int x) {
Stack s = (Stack)malloc(sizeof(SNode*));
s->data = x;
s->next = NULL;
return s;
}
//判断栈空
int Empty(Stack Ptrs) {
return Ptrs->next == NULL;
}
//入栈
void Push(Stack Ptrs, int x) {
Stack s = creat_node(x);
s->next = Ptrs->next;
Ptrs->next = s;
}
//出栈
int Pop(Stack Ptrs) {
if (Empty(Ptrs)) {
printf("堆栈为空");return 0;
}
else {
int t;
Stack temp = Ptrs->next;
Ptrs->next = temp->next;
t = temp->data;
free(temp);
return t;
}
}
//计算后缀表达式
int Calculate(char str[]) {
Stack Ptrs = Init();
int i = 0, sum;
while (str[i] != '\0') {
if (str[i] >= '0' && str[i] <= '9')//1. 将字符串型的数字转换为整型(或者浮点型)。
{
sum = str[i] - '0';
Push(Ptrs, sum);
}
if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')//3. 遇到运算符(#),则将栈中的前两个数字(a和b)出栈,并将b#a的值压入栈中。
{
int a = Pop(Ptrs);
int b = Pop(Ptrs);
if (str[i] == '+')
Push(Ptrs, b + a);
else if (str[i] == '-')
Push(Ptrs, b - a);
else if (str[i] == '*')
Push(Ptrs, b * a);
else if (str[i] == '/')
Push(Ptrs, b / a);
else
printf("error\n");
}
i++;
}
int c = Pop(Ptrs);//栈顶的数字出栈
return c;
}
// 设置符号优先级
int Compare_Priority(char c) {
if (c == '#') {
return 0;
}
else if (c == '+' || c == '-') {
return 1;
}
else if (c == '*' || c == '/') {
return 2;
}
else if (c == '(' || c == ')') {
return 0;
}
else {
return -1;
}
}
int main() {
char op[MAX];int top = -1;
char result[MAX];int top1 = -1;
char str[MAX];
printf("输入中缀表达式,以#做输入结束的标志:");
scanf("%s", &str);
int len = strlen(str);
printf("转化为后缀表达式后计算结果:");
for (int i = 0;i < len;) {
if (Compare_Priority(str[i]) == -1) {
result[++top1] = str[i++];
}
else if (str[i] == '(') {
op[++top] = str[i++];
}
else if (str[i] == ')') {
while (op[top] != '(') {
result[++top1] = op[top--];
}
top--;
i++;
}
else {
if (top == -1 || Compare_Priority(str[i]) > Compare_Priority(op[top])) {
op[++top] = str[i++];
}
else {
while (Compare_Priority(str[i]) <= Compare_Priority(op[top]))
result[++top1] = op[top--];
op[++top] = str[i++];
}
if (str[i] == '#') {
break;
}
}
}
printf("%d", Calculate(result));
}
测试: