后缀表达式概述:
后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。
转后缀表达式的具体做法:
建立一个栈Stack 。从左到右扫描表达式,如果读到非符号就将它输出,如果读到运算符则进行压栈操作(需要判断符号优先级)。
优先级判断:
如果栈顶符号的优先级大于等于当前符号,则将栈顶符号弹出,直到栈顶符号优先级小于当前符号,再将当前符号压入栈中。
例:
{"+", "/"} 设左侧为栈底,右侧为栈顶,当前符号为 " * "。栈顶符号 " / " 的优先级等于当前符号 " * ",则弹出 " / "。栈顶指针继续往下走,指向了 " + ",当前符号优先级大于 " + " ,则把当前符号压入栈内。
代码实现(C语言):
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 15
typedef int Status;
typedef char ElemType;
typedef struct sqStack
{
ElemType *top;
ElemType *base;
int stackSize;
} sqStack;
Status cls(sqStack *stack);
void clsStack(sqStack *stack);
void sqStackInit(sqStack *stack);
void destroyStack(sqStack *stack);
Status judge(sqStack *stack, ElemType e);
void Push_Pop(sqStack *stack, ElemType e);
Status priority(sqStack *stack, ElemType e);
// 申请一个容量为15的栈
void sqStackInit(sqStack *stack)
{
stack->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
if (!stack->base)
{
printf("栈初始化失败!");
exit(0);
}
stack->top = stack->base;
stack->stackSize = STACK_INIT_SIZE;
}
// 判断符号优先级
Status priority(sqStack *stack, ElemType e)
{
if (stack->top == stack->base)
{
return TRUE;
}
if (e == '+' || e == '-')
{
do
{
-- stack->top;
if (*(stack->top) == '(')
{
stack->top ++;
return TRUE;
}
printf("%c ", *(stack->top));
} while (stack->top != stack->base);
return TRUE;
}
else
{
ElemType previous = *(--stack->top);
if (previous == '+' || previous == '-')
{
stack->top ++;
return TRUE;
}
else
{
if (previous == '(')
{
stack->top ++;
return TRUE;
}
while (stack->top != stack->base){
printf("%c ", *(stack->top));
stack->top --;
if (*(stack->top) == '-' || *(stack->top) == '+' || *(stack->top) == '(')
{
stack->top ++;
return TRUE;
}
} ;
printf("%c ", *(stack->top));
return TRUE;
}
}
}
// 遇到右括号则在栈内找左括号, 并把括号内的符号全部弹出。
Status cls(sqStack *stack)
{
stack->top --;
while (*(stack->top) != '(')
{
printf("%c ", *(stack->top));
stack->top --;
}
return FALSE;
}
// 判断符号
Status judge(sqStack *stack, ElemType e)
{
switch (e)
{
case '(': return TRUE;
case '+': return priority(stack, e);
case '-': return priority(stack, e);
case '*': return priority(stack, e);
case '/': return priority(stack, e);
case ')': return cls(stack);
default:
printf("%c ", e);
}
return FALSE;
}
// 执行压栈和弹栈
void Push_Pop(sqStack *stack, ElemType e)
{
if (judge(stack, e))
{
*(stack->top) = e;
stack->top ++;
}
}
// 清空栈
void clsStack(sqStack *stack)
{
if (stack->top == stack->base)
{
return;
}
do
{
stack->top --;
printf("%c ", *(stack->top));
} while (stack->top != stack->base);
}
void destroyStack(sqStack *stack)
{
free(stack->base);
stack->top = stack->base = NULL;
stack->stackSize = 0;
}
int main(void)
{
char input;
sqStack stack;
sqStackInit(&stack);
printf("输入表达式:");
do
{
scanf("%c", &input);
if (input != '#')
{
Push_Pop(&stack, input);
}
} while (input != '#');
getchar();
clsStack(&stack); // 把栈内的所有符号都弹出
destroyStack(&stack);
return 0;
}
注: 输入表达式时,以字符 " # " 结尾!
运行结果:
>>输入表达式:1+((9-3)/2+1-3/3-1)/2#
>>1 9 3 - 2 / 1 + 3 3 / - 1 - 2 / +
这次的代码写的有点乱,将就一下,下次再写的时候好好整理一下。
代码测试次数不多,如遇bug望告知。