用栈求算术表达式的值
- 题目:1 将中缀表达式转换为后缀表达式
- 2 求后缀表达式的值
#include<stdio.h>
#define MaxSize 100
struct
{
char data[MaxSize];
int top; //栈顶指针
}op; //定义运算符栈
struct
{
float data[MaxSize];
int top;
}st; //定义数值栈
void trans(char exp[],char postexp[])
{
int i = 0;
int j = 0;
char ch;
op.top = -1; //栈顶指针初始化为-1
ch = exp[i];
i++;
while (ch != '\0')
{
switch (ch)
{
case '(': //判定为左括号 直接入栈
op.top++;
op.data[op.top] = ch;
break;
case ')':
while (op.data[op.top] != '(')
{
postexp[j] = op.data[op.top];
op.top--;
j++;
}
op.top--; //左括号也出栈 但不输出
break;
case '+':
case '-':
//为 + 或者 - 时候,优先级不大于栈顶任何运算符的优先级 直到 )
while (op.top != -1 && op.data[op.top] != '(')
{
postexp[j] = op.data[op.top];
j++;
op.top--;
}
op.top++;
op.data[op.top] = ch;
break;
case '*':
case '/':
//为 * 或者是 / 时, 其优先级不大于栈顶为 * 或者为 /的优先级 直到 (
while (op.top != -1 && op.data[op.top] != '('
&& (op.data[op.top] == '*' || op.data[op.top] == '/'))
{
//将栈顶运算符弹出并输出
postexp[j] = op.data[op.top];
j++;
op.top--;
}
//该运算符的优先级大于栈顶运算符的优先级 直接压栈
op.top++;
op.data[op.top] = ch;
break;
case ' ': //过滤掉空格
break;
default:
while (ch >= '0' && ch <= '9') //判定为数字
{
postexp[j] = ch;
j++;
ch = exp[i];
i++;
}
i--;
postexp[j] = '#'; //用#标识一个数值串结束
j++;
break;
}
ch = exp[i];
i++;
}
while (op.top != -1) //此时exp扫描完毕 栈不空时出栈并存放到postexp
{
postexp[j] = op.data[op.top];
j++;
op.top--;
}
postexp[j] = '\0'; //添加结束标识符
}
//后缀表达式的求值过程
float Compvalue(char postexp[])
{
char ch;
float d;
int i = 0;
ch = postexp[i];
i++;
st.top = -1;
while (ch != '\0')
{
switch (ch)
{
case '+':
st.data[st.top - 1] = st.data[st.top - 1] + st.data[st.top];
st.top = st.top - 1;
break;
case '-':
st.data[st.top - 1] = st.data[st.top - 1] - st.data[st.top];
st.top = st.top - 1;
break;
case '*':
st.data[st.top - 1] = st.data[st.top] * st.data[st.top - 1];
st.top = st.top - 1;
break;
case '/':
if (st.data[st.top] != 0)
{
st.data[st.top - 1] = st.data[st.top - 1] / st.data[st.top];
st.top = st.top - 1;
}
else
{
printf("除数为0.\n");
return 0.0;
}
break;
default:
d = 0;
while (ch >= '0' && ch <= '9')
{
d = d * 10 + ch - '0';
ch = postexp[i];
i++;
}
st.top++;
st.data[st.top] = d;
break;
}
ch = postexp[i];
i++;
}
return st.data[st.top];
}
int main()
{
int i = 0;
char exp[] = {"(2*2)*1+3*2/1"};
char postexp[MaxSize];
trans(exp,postexp);
while (postexp[i] != '\0')
{
printf("%c",postexp[i]);
i++;
}
printf("\n");
printf("运算结果为:%f.\n", Compvalue(postexp));
system("pause");
return 0;
}
后缀表达式求值如下:
while(从postexp中间读取字符ch,ch != '\0')
{
若ch为数字,将后继的所有数字构成一个整数存放到数值栈st中
若ch为 "+",则从数值栈st中退栈两个运算数,相加后进栈st中
若ch为 "-",则从数值栈st中退栈两个运算数,相减后进栈st中
若ch为 "*",则从数值栈st中退栈两个运算数,相乘后进栈st中
若ch为 "/",则从数值栈st中退栈两个运算数,相除后进栈st中(若除数为0,则提示错误)
}
-
运行结果
-
参考资料:
1 《新编数据结构习题与解析》