中缀表达式转后缀表达式
用栈把中缀(Infix)表达式转换成后缀(postfix)表达式 ,例如
- 8 + 4 - 6 * 2 用后缀表达式表示为:8 4 + 6 2 * -
- 2 * ( 3 + 5 ) + 7 / 1 - 4 用后缀表达式表示为:2 3 5 + * 7 1 / + 4 -
Java:
import java.util.Stack;
public class InfixToPostfix {
static Stack<Character> theStack = new Stack<>();
static String output = "";
public static void main(String[] args) {
String input = "2*(3+5*2)+7/1-4";
System.out.println("Infix is " + input);
System.out.println("Postfix is " + doTrans(input));
}
// 中缀表达式转后缀表达式
public static String doTrans(String input) {
for(int i = 0;i < input.length();i++) {
char ch = input.charAt(i);
switch(ch) {
case '+':
case '-':
gotOper(ch, 1);
break;
case '*':
case '/':
gotOper(ch, 2);
break;
case '(':
theStack.push(ch);
break;
case ')':
while( !theStack.isEmpty() ) {
char opTop = theStack.pop();
if( opTop == '(') //如果遇到 ( 括号就结束了
break;
else //否则把运算符添加到 output 后面
output = output + " " + opTop;
}
break;
default: // 遇到数字添加在 output 后面即可
output = output + " " + ch;
break;
}
}
// 把栈中最后的运算符添加在 output 后面
while( !theStack.isEmpty() )
output = output + " " + theStack.pop();
return output;
}
//处理运算符
public static void gotOper(char opThis, int prec1) {
//判断栈是否为空,不为空进行操作
while( !theStack.isEmpty() ) {
char opTop = theStack.pop();
//如果栈顶是 ( 不做操作 因为括号优先
if(opTop == '(') {
theStack.push(opTop);
break;
} else {
int prec2;
//判断栈顶是 +- 还是 */
if(opTop == '-' || opTop == '+')
prec2 = 1;
else
prec2 = 2;
//如果栈顶是 +- ,当前字符是 */ ,+- 栈顶优先级低,继续保留在栈里面
if(prec2 < prec1) {
theStack.push(opTop);
break;
//否则,栈顶与当前字符一样,或者栈顶是 */ ,当前字符是 +- ,栈顶优先级高,添加在 output 后面
} else
output = output + " " + opTop;
}
}
//将当前字符放在栈中
theStack.push(opThis);
}
}
/* Code Running Results
Infix is 2*(3+5*2)+7/1-4
Postfix is 2 3 5 2 * + * 7 1 / + 4 -
*/
上面Java直接使用工具包中的Stack,下面C语言使用自己编写的栈
C语言:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STACK_INIT_SIZE 100 // 存储空间初始化分配量
#define STACKINCREMENT 10 // 存储空间分配增量
#define OVERFLOW -2
#define OK 1
#define ERROR 0
typedef int Status;
typedef char SElemType;
typedef struct{
SElemType * base; // 在栈构造之前和销毁之后,base 的值为 NULL
SElemType * top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}SqStack;
static char input[] = "2*(3+5)+7/1-4"; // 静态的中缀表达式
static char output[100]; // 静态的后缀表达式
static int outputlength = 0; // 静态的后缀表达式字符串长度
void gotOper(SqStack &S, char opThis, int prec1); // 声明函数
void gotParen(SqStack &S);
Status InitStack(SqStack &S, int max)
{
// 构造一个空栈
S.base = (SElemType *)malloc(max*sizeof(SElemType));
if(!S.base)
exit(OVERFLOW); // 存储分配失败
S.top = S.base;
S.stacksize = max;
return OK;
}
Status GetTop(SqStack S, SElemType &e)
{
// 若栈不空,则用 e 返回 S 的栈顶元素,并返回 OK ,否则返回 ERROR
if(S.top == S.base)
return ERROR;
e = *(S.top-1);
return OK;
}
Status Push(SqStack &S, SElemType e)
{
// 插入元素 e 为新的栈顶元素
if(S.top - S.base >= S.stacksize){ // 栈满了,追加存储空间
S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
if(!S.base)
exit(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
return OK;
}
Status Pop(SqStack &S, SElemType &e)
{
// 若栈不空,则删除 S 的栈顶元素, 用 e 返回其值,并返回 OK ,否则返回 ERROE
if(S.top == S.base)
return ERROR;
e = *(--S.top);
return OK;
}
Status IsEmpty(SqStack S)
{
// 若栈为空返回 OK, 否则返回 ERROR
if(S.top == S.base)
return OK;
return ERROR;
}
int main()
{
SqStack stack;
InitStack(stack, strlen(input)); // 初始化栈
for(int i = 0;i < strlen(input);i++){ // 得到后缀表达式
char ch = input[i];
switch(ch){
case '+':
case '-':
gotOper(stack, ch, 1);
break;
case '*':
case '/':
gotOper(stack, ch, 2);
break;
case '(':
Push(stack, ch);
break;
case ')':
gotParen(stack);
break;
default: // 遇到数字添加在 output 后面即可
output[outputlength++] = ch;
break;
}
}
while(!IsEmpty(stack)){ // 把栈中最后的运算符添加在 output 后面
char popchar;
Pop(stack, popchar);
output[outputlength++] = popchar;
}
printf("Infix is : %s\n", input);
printf("Postfix is : ");
for(int i = 0;i < outputlength;i++)
printf("%c ", output[i]);
return 0;
}
void gotParen(SqStack &S) // 处理回圆括号
{
while(!IsEmpty(S)){
char opTop;
Pop(S, opTop);
if(opTop == '(') // 如果遇到 ( 括号就结束了
break;
else{ // 否则把运算符添加到 output 后面
output[outputlength++] = opTop;
}
}
}
void gotOper(SqStack &S, char opThis, int prec1) // 处理运算符
{
while(!IsEmpty(S)){ // 判断栈是否为空,不为空进行操作
char opTop;
Pop(S, opTop);
if(opTop == '('){ // 如果栈顶是 ( 不做操作 因为括号优先
Push(S, opTop);
break;
}else{
int prec2;
if(opTop == '-' || opTop == '+') // 判断栈顶是 +- 还是 */
prec2 = 1;
else
prec2 = 2;
// 如果栈顶是 +- ,当前字符是 */ ,+- 栈顶优先级低,继续保留在栈里面
if(prec2 < prec1) {
Push(S, opTop);
break;
//否则,栈顶与当前字符一样,或者栈顶是 */ ,当前字符是 +- ,栈顶优先级高,添加在 output 后面
} else {
output[outputlength++] = opTop;
}
}
}
Push(S, opThis); //将当前字符放在栈中
}
/* Code Running Results
input: 2*(3+5)+7/1-4
output: 2 3 5 + * 7 1 / + 4 -
*/