运算符号在两数字中间的称为中缀表达式,如5+9,4*9+6等,我们平时计算一般都是用中缀 表达式。运算符号在两数字后面的称为后缀表达式,如59-,46*6+,与前两个中缀表达式作用相同。
用栈实现后缀表达式的求值的基本思想就是先初始化一个空栈,然后输入字符串,遍历字符串,如果是数字,则将数字入栈,如果是运算符号,则将前两次入栈的数出栈作运算,再将结果入栈,最后入栈的数即为表达式的结果。
#include<stdio.h>
#include<stdlib.h>
/* 链栈结构 */
typedef struct StackNode
{
int data;
struct StackNode *next;
}StackNode, *LinkStackPtr;
typedef struct
{
LinkStackPtr top;
int count;
}LinkStack;
int InitStack(LinkStack *S)
{
S->top = (LinkStackPtr)malloc(sizeof(StackNode));
if (!S->top)
return 0;
S->top = NULL;
S->count = 0;
return 1;
}
void Push(LinkStack *S, int e)
{
LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));
s->data = e;
s->next = S->top; /* 把当前的栈顶元素赋值给新结点的直接后继,见图中① */
S->top = s; /* 将新的结点s赋值给栈顶指针,见图中② */
S->count++;
}
/* 若栈S为空栈,则返回TRUE,否则返回FALSE */
int StackEmpty(LinkStack S)
{
if (S.count == 0)
return 1;
else
return 0;
}
/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
int Pop(LinkStack *S, int *e)
{
LinkStackPtr p;
if (StackEmpty(*S))
return 0;
*e = S->top->data;
p = S->top; /* 将栈顶结点赋值给p,见图中③ */
S->top = S->top->next; /* 使得栈顶指针下移一位,指向后一结点,见图中④ */
free(p); /* 释放结点p */
S->count--;
return 1;
}
float jisuan(int x, int y, char z){
switch (z)
{
case '+':return x + y;
case '-':return x - y;
case '*':return x * y;
case '/':return x / y;
default:
break;
}
}
int main(){
int i=0;
int n,m;
int result;
char a[20];
LinkStack s;
InitStack(&s);
gets_s(a);
while (a[i] != '\0'){
if (a[i] >= '0' && a[i] <= '9'){
Push(&s, (int)a[i]-48);
}
else
{
Pop(&s, &n);
Pop(&s, &m);
result = jisuan(m, n, a[i]);
Push(&s, result);
}
i++;
}
Pop(&s, &result);
printf("%d\n", result);
system("pause");
return 0;
}
如果要计算(3+6-4)*6,先将其转为后缀表达式36+4-6*
这段代码也有许多小问题,比如只能计算个位数的运算,除法结果是小数的也有问题。