中缀表达式转后缀表达式

该博客介绍了如何使用栈将中缀表达式转换为后缀表达式,分别给出了Java和C语言的实现。示例中,如输入'2*(3+5)+7/1-4',输出的后缀表达式为'2352*+*71/+4-'。算法主要处理运算符的优先级和括号匹配。
摘要由CSDN通过智能技术生成

中缀表达式转后缀表达式

  用栈把中缀(Infix)表达式转换成后缀(postfix)表达式 ,例如

  1. 8 + 4 - 6 * 2 用后缀表达式表示为:8 4 + 6 2 * -
  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 -
*/
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值