优先级:*,\ > +, -
如果输入运算符的优先级低于或等于栈顶的操作符优先级,则栈内元素进入输入队列,输入运算符入栈。
一个简单的例子
- 输入:3+4
通过这个例子可以看出两条规则:
- 当读入一个数字时直接入输出队列
- 当输入结束后,运算符队列中所有操作符入输出队列
[编辑]
更详细的例子
输入 | 动作 | 输出 (逆波兰表示法) | 运算符栈 | 提示 |
---|---|---|---|---|
3 | 将符号加入输出队列 | 3 | ||
+ | 将符号压入操作符堆栈 | 3 | + | |
4 | 将符号加入输出队列 | 3 4 | + | |
* | 将符号压入操作符堆栈 | 3 4 | * + | *号的优先级高于+号 |
2 | 将符号加入输出队列 | 3 4 2 | * + | |
/ | 将堆栈中元素弹出,加入输出队列 | 3 4 2 * | + | /号和*号优先级相同 |
将符号压入操作符堆栈 | 3 4 2 * | / + | /号的优先级高于+号 | |
( | 将符号压入操作符堆栈 | 3 4 2 * | ( / + | |
1 | 将符号加入输出队列 | 3 4 2 * 1 | ( / + | |
− | 将符号压入操作符堆栈 | 3 4 2 * 1 | − ( / + | |
5 | 将符号加入输出队列 | 3 4 2 * 1 5 | − ( / + | |
) | 将堆栈中元素弹出,加入输出队列 | 3 4 2 * 1 5 − | ( / + | 循环直到找到(号 |
将堆栈元素弹出 | 3 4 2 * 1 5 − | / + | 括号匹配结束 | |
^ | 将符号压入操作符堆栈 | 3 4 2 * 1 5 − | ^ / + | ^号的优先级高于/号 |
2 | 将符号加入输出队列 | 3 4 2 * 1 5 − 2 | ^ / + | |
^ | 将符号压入操作符堆栈 | 3 4 2 * 1 5 − 2 | ^ ^ / + | ^号为从右至左求值 |
3 | 将符号加入输出队列 | 3 4 2 * 1 5 − 2 3 | ^ ^ / + | |
END | 将栈中所有数据加入输出队列 | 3 4 2 * 1 5 − 2 3 ^ ^ / + |
// main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"
int GetPriority(char ch)
{
switch(ch)
{
case '+':
return 0;
case '-':
return 0;
case '*':
return 1;
case '/':
return 1;
default:
return -1;
}
}
int IsNumber(char ch)
{
return (ch >= '0' && ch <= '9');
}
int main()
{
char expression[100];
printf("please input the expression:\n");
scanf("%s", expression);
OperatorStack *stack = (OperatorStack*)malloc(sizeof(OperatorStack));
stack->size = 0;
int n = 0;
for(n=0; n<strlen(expression); n++)
{
if(IsNumber(expression[n]))
{
printf("%c", expression[n]);
}
else
{
if(expression[n] == '(')
{
Push(stack, expression[n]);
}
else if(expression[n] == ')')
{
while(GetTop(stack) != '(')
{
printf("%c", Pop(stack));
}
Pop(stack);
}
else
{
// operators: +, -, *, /
if(IsEmpty(stack))
{
Push(stack, expression[n]);
}
else
{
while(!IsEmpty(stack) && GetPriority(GetTop(stack)) >= GetPriority(expression[n]))
{
printf("%c", Pop(stack));
}
Push(stack, expression[n]);
}
}
}
}
while(!IsEmpty(stack))
{
printf("%c", Pop(stack));
}
printf("\n");
return 0;
}
// stack.h
#ifndef _OPERATOR_STACK_H_
#define _OPERATOR_STACK_H_
#define STACK_LENGTH 100
typedef struct OperatorStack
{
char operator_stack[STACK_LENGTH];
int size;
}OperatorStack;
int Push(OperatorStack *stack, char ch);
char Pop(OperatorStack *stack);
int IsEmpty(OperatorStack *stack);
char GetTop(OperatorStack *stack);
#endif
// stack.c
#include "stack.h"
int Push(OperatorStack *stack, char ch)
{
if(stack->size >= STACK_LENGTH)
{
// Error: stack is full
return 0;
}
stack->operator_stack[stack->size] = ch;
stack->size++;
return 1;
}
char Pop(OperatorStack *stack)
{
if(stack->size <= 0)
{
return -1;
}
stack->size--;
return stack->operator_stack[stack->size];
}
char GetTop(OperatorStack *stack)
{
if(stack->size == 0)
{
return -1;
}
return stack->operator_stack[stack->size - 1];
}
int IsEmpty(OperatorStack *stack)
{
return stack->size == 0;
}