高深面试题 (中缀表达式转为后缀表达式)

1.表达式a+b*c-(d+e)/f的后缀表达式为?
扫描的方式从左到右 依次进行扫描 参数放到参数栈中 符号 放到符号 栈中

扫描的次数扫描到的值参数栈符号栈解释
第一次aa第一次扫描到的是a 直接放到参数栈中
第二次+a+第二次扫描到的是加号直接放到符号栈中
第三次bba+第三次扫描到的是b依次放到参数栈中
第四次*ba*+第四次扫描到的是*放到符号栈中,因为遇到称号不知到下一个 参数是什么所以先不动
第五次c+*cba第五扫描到的是c放到参数栈中,因为乘的级别 比加高所以需要进入参数栈,乘先出栈然后加好在出栈
第六次-+*cba-第六次扫描到-直接进入符号栈
第七次(+*cba(-第七次扫描到(直接进入符号栈
第八次dd+*cba(-第八次扫描到的是d直接进入参数栈
第九次+d+*cba+(-第九次扫描到的是+号进符号栈
第十次eed+*cba+(-第十次扫描到的是e直接进入参数栈
第十一次)+ed+*cba-第十一次扫描的是) 左右括号配对括号里的符号进参数栈
第十二次/+ed+*cba/-第十二次扫描的是/ 除号进操作符栈
第十三次f-/f+ed+*cba第十三次扫描到的是/级别高进参数栈

依次出栈 倒着来

abc*+de+f/-

在火车上搞了半个小时

定义一个栈对象

package main.com.cs.suffix;

public class MyCharStack {

    //定义栈
    private char[] array;

    //定义栈的最大范围
    private int maxSize;

    //栈顶
    private int top;

    public MyCharStack(int size){
        this.maxSize = size;
        array = new char[size];
        top = -1;
    }

    //压入数据
    public void push(char value){
        if(top < maxSize-1){
            array[++top] = value;
        }
//        throw new RuntimeException("栈大小超出范围");
    }

    //弹出栈顶数据
    public char pop(){
        return array[top--];
    }

    //访问栈顶数据
    public char peek(){
        return array[top];
    }

    //查看指定位置的元素
    public char peekN(int n){
        return array[n];
    }

    //为了便于后面分解展示栈中的内容,我们增加了一个遍历栈的方法(实际上栈只能访问栈顶元素的)
    public void displayStack(){
        System.out.print("Stack(bottom-->top):");
        for(int i = 0 ; i < top+1; i++){
            System.out.print(peekN(i));
            System.out.print(' ');
        }
        System.out.println("");
    }

    //判断栈是否为空
    public boolean isEmpty(){
        return (top == -1);
    }

    //判断栈是否满了
    public boolean isFull(){
        return (top == maxSize-1);
    }
}

定义中缀转后缀方法

package main.com.cs.suffix;

public class InfixToSuffix {
    private MyCharStack s1;//定义运算符栈
    private MyCharStack s2;//定义存储结果栈
    private String input;
     
    //默认构造方法,参数为输入的中缀表达式
    public InfixToSuffix(String in){
        input = in;
        s1 = new MyCharStack(input.length());
        s2 = new MyCharStack(input.length());
    }
    //中缀表达式转换为后缀表达式,将结果存储在栈中返回,逆序显示即后缀表达式
    public MyCharStack doTrans(){
        for(int j = 0 ; j < input.length() ; j++){
            System.out.print("s1(符号)栈元素为:");
            s1.displayStack();
            System.out.print("s2(参数)栈元素为:");
            s2.displayStack();
            char ch = input.charAt(j);
            System.out.println("当前解析的字符:"+ch);
            switch (ch) {
            case '+':
            case '-':
                gotOper(ch,1);
                break;
            case '*':
            case '/':
                gotOper(ch,2);
                break;
            case '(':
                s1.push(ch);//如果当前字符是'(',则将其入栈
                break;
            case ')':
                gotParen(ch);
                break;
            default:
                //1、如果当前解析的字符是操作数,则直接压入s2
                //2、
                s2.push(ch);
                break;
            }//end switch
        }//end for
         
        while(!s1.isEmpty()){
            s2.push(s1.pop());
        }
        return s2;
    }
     
    public void gotOper(char opThis,int prec1){
        while(!s1.isEmpty()){
            char opTop = s1.pop();
            if(opTop == '('){//如果栈顶是'(',直接将操作符压入s1
                s1.push(opTop);
                break;
            }else{
                int prec2;
                if(opTop == '+' || opTop == '-'){
                    prec2 = 1;
                }else{
                    prec2 = 2;
                }
                if(prec2 < prec1){//如果当前运算符比s1栈顶运算符优先级高,则将运算符压入s1
                    s1.push(opTop);
                    break;
                }else{//如果当前运算符与栈顶运算符相同或者小于优先级别,那么将S1栈顶的运算符弹出并压入到S2中
                    //并且要再次再次转到while循环中与 s1 中新的栈顶运算符相比较;
                    s2.push(opTop);
                }
            }
             
        }//end while
        //如果s1为空,则直接将当前解析的运算符压入s1
        s1.push(opThis);
    }
     
    //当前字符是 ')' 时,如果栈顶是'(',则将这一对括号丢弃,否则依次弹出s1栈顶的字符,压入s2,直到遇到'('
    public void gotParen(char ch){
        while(!s1.isEmpty()){
            char chx = s1.pop();
            if(chx == '('){
                break;
            }else{
                s2.push(chx);
            }
        }
    }
 
}

定义测试方法

package test.com.cs;

import main.com.cs.suffix.InfixToSuffix;
import main.com.cs.suffix.MyCharStack;
import org.junit.Test;

import java.util.Scanner;

public class suffix {

    public static void main(String[] args) {

        String input;
        System.out.println("Enter infix:");
        Scanner scanner = new Scanner(System.in);
        input = scanner.next();
        InfixToSuffix in = new InfixToSuffix(input);
        MyCharStack my = in.doTrans();
        my.displayStack();

    }
}

测试结果

在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中缀表达式转后缀表达式可以通过栈来实现,具体步骤如下: 1. 创建一个空栈和一个空的后缀表达式列表。 2. 从左到右扫描中缀表达式的每个元素,如果是数字,直接将其加入到后缀表达式列表中。 3. 如果是运算符,将其与栈顶元素进行比较,如果栈顶元素优先级高于当前运算符,则将栈顶元素弹出并加入到后缀表达式列表中,直到栈顶元素优先级低于等于当前运算符或者栈为空。然后将当前运算符压入栈中。 4. 如果是左括号,将其压入栈中。 5. 如果是右括号,将栈顶元素弹出并加入到后缀表达式列表中,直到弹出左括号。左右括号不会加入到后缀表达式列表中。 6. 重复步骤2到5,直到扫描完所有元素。 7. 如果栈不为空,将栈中元素依次弹出并加入到后缀表达式列表中。 下面是一个示例,将中缀表达式"3+4*5/(6-2)"转换为后缀表达式: 1. 创建一个空栈和空的后缀表达式列表。 2. 从左到右扫描中缀表达式的每个元素: - 3 是数字,加入到后缀表达式列表中。 - + 是运算符,栈为空,将其压入栈中。 - 4 是数字,加入到后缀表达式列表中。 - * 是运算符,栈顶元素为 +,优先级高于 *,将 + 弹出并加入到后缀表达式列表中,然后将 * 压入栈中。 - 5 是数字,加入到后缀表达式列表中。 - / 是运算符,栈顶元素为 *,优先级低于 /,将 / 压入栈中。 - ( 是左括号,将其压入栈中。 - 6 是数字,加入到后缀表达式列表中。 - - 是运算符,栈顶元素为 (,优先级低于 -,将 - 压入栈中。 - 2 是数字,加入到后缀表达式列表中。 - ) 是右括号,栈顶元素为 -,将 - 弹出并加入到后缀表达式列表中,然后将 / 弹出并加入到后缀表达式列表中,然后将左括号弹出并丢弃。 3. 扫描完所有元素,栈中元素为 *,将其弹出并加入到后缀表达式列表中。 4. 后缀表达式为"3 4 5 * 6 2 - / + *"。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值