【数据结构】如何利用栈将中缀表达式转换为后缀表达式

如何实现栈

如何在将中缀表达式转换为后缀表达式之前使用栈来判定括号是否匹配

两种表达式

中缀 后缀
A+B AB+
A+B*C ABC*+
(A+B)*C-D AB+C * D-

重要性质

  • 中缀表达式1+2 * 4和后缀表达式124 * +中,数字顺序是一样的,只有算术符号顺序不一样
  • 只需一个栈就可以把中缀转后缀,利用栈把表达式中的运算符次序从中序改为后序。栈中只存放运算符和左括号,由于后缀表达式中不存在括号,所以输出的时候将不输出括号。

算法

a)创建一个栈
b)while(字符串未结束)
 		 if(t是操作数) 输出t
 		 else if(t是右括号)
 		 		出栈并输出该符号,直至一个匹配的左括号出栈(但左括号不输出)
 		 	   else
 		 	   		当栈非空且t的优先级不大于栈顶元素时,出栈并输出
 		 t入栈
c)当栈非空的时候,出栈并输出所有字符 		 	   	

Java版本实现

 //中缀转后缀算法
    static String MinddleTurnToBack(String curString) {
        LLStack stack = new LLStack();
        String result = "" ;
        System.out.print("中缀表达式转换为后缀表达式:");
        for(int i = 0; i < curString.length(); i++) {
            char t = curString.charAt(i);
            if(isNumber(t)) {
                //数字直接输出
                System.out.print(t);
                result = result + t;
            }else if((t == ')' || t == ']' || t == '}')) {
                //当栈顶不是‘(’时,出栈并输出
                while(!stack.isEmpty() && stack.top() != '(' && stack.top() != '[' && stack.top() != '{'){
                    result += stack.top();
                    System.out.print((char)stack.pop());

                }
                //直到栈顶是‘(’
                if (!stack.isEmpty())
                    stack.pop();

            }else {//操作符或‘(’
                //当栈非空且t的优先级不大于栈顶元素时,出栈并输出然后t入栈
                while(!stack.isEmpty() && isPriority((char)stack.top(), t)) {
                    result += stack.top();
                    System.out.print((char)stack.pop());
                }
                stack.push(t);
            }
        }
        while(!stack.isEmpty()) {
            result += stack.top();
            System.out.print((char)stack.pop());
        }
        System.out.println();
        return result;
    }

栈的实现

package com.wuyi.notecode;


class LLNode{
    private char data;
    private LLNode next = null;

    public LLNode(char d){
        data = d;
    }
    public int getData() {
        return data;
    }
    public void setData(char data) {
        this.data = data;
    }
    public LLNode getNext() {
        return next;
    }
    public void setNext(LLNode next) {
        this.next = next;
    }
}
public class LLStack {
    private LLNode  head;

    boolean isEmpty() {
        return head == null;
    }

    int size() {
        int count = 1;
        LLNode cur = head;
        if(isEmpty())  return 0;
        while(cur.getNext() !=null ) {
            cur = cur.getNext();
            count++;
        }
        return count;
    }

    int top() {
        if(isEmpty())
            new Exception("栈空");
        return head.getData();
    }

    void push(char d) {
        if(isEmpty()) {
            head =new LLNode(d);
        }else {
            LLNode node = new LLNode(d);
            node.setNext(head);
            head = node;
        }
    }

    int pop() {
        if(isEmpty())
            new Exception("栈空");
        LLNode del = head;
        head = head.getNext();
        return del.getData();
    }
    void display() {
        if(isEmpty()) {
            System.out.println("栈空");
        }else {
            LLNode cur = head;
            System.out.print("栈内元素:");
            while(cur != null) {
                System.out.print(cur.getData() + "->");
                cur = cur.getNext();
            }
            System.out.println();
        }
    }

    void deleteStack() {
        head  = null;
    }

    public static void main(String[] args) {
        LLStack ls = new LLStack();
        ls.push('2');
        ls.push('3');
        System.out.println("栈顶元素:" + ls.top());
        ls.display();
        System.out.println("移除栈顶元素:" + ls.pop());
        ls.push('5');
        System.out.println("删除整个栈");
        ls.deleteStack();
        ls.display();

    }

}


完整测试代码

import java.util.Scanner;

public class StackApplication {
    //括号匹配算法
    static boolean isMatch(LLStack stack,String curString) {
        //字符处理
        for(int i = 0; i < curString.length(); i++) {
            char ch = curString.charAt(i);
            switch(ch) {
                case '(' :
                    stack.push(ch);
                    break;
                case '[' :
                    stack.push(ch);
                    break;
                case '{' :
                    stack.push(ch);
                    break;
                case ')' :
                    if(stack.isEmpty() || stack.top() != '(' ) {
                        System.out.println("括号匹配失败");
                        return false;
                    }else {
                        stack.pop();
                    }
                    break;
                case ']' :
                    if(stack.isEmpty() || stack.top() != '[' ) {
                        System.out.println("括号匹配失败");
                        return false;
                    }else {
                        stack.pop();
                    }
                    break;
                case '}' :
                    if(stack.isEmpty() || stack.top() != '{' ) {
                        System.out.println("括号匹配失败");
                        return false;
                    }else {
                        stack.pop();
                    }
                    break;
            }
        }
        //字符处理后栈非空
        if(!stack.isEmpty()) {
            System.out.println("括号匹配失败");
            return false;
        }
        //System.out.println("括号匹配成功");
        return true;
    }
    //算术符号优先级算法
    static boolean isPriority(char top, char t) {
        /*if(a == '(' || a == '[' || a == '{') return true;
        if(b == '(' || b == '[' || b == '{' ) return true;

        if(b == '*' || b == '/' || b == '%')
            return false;
        else if(a == '*' || a == '/' || a == '%')
            return true;
        else if(b == '+' || b == '-' )
            return false;
        else return true;
*/
        if((t == '+' || t == '-') && (top == '*' || top == '/'))
            return true;
        return false;

    }

    static boolean isNumber(char t){
        //这里为了测试一下字母,所以把字母也加进来了
        if (t >= '0' && t <= '9' || t >= 'a' && t <= 'z' || t >= 'A' && t <= 'Z' )
            return  true;
        return false;
    }
    //中缀转后缀算法
    static String MinddleTurnToBack(String curString) {
        LLStack stack = new LLStack();
        String result = "" ;
        System.out.print("中缀表达式转换为后缀表达式:");
        for(int i = 0; i < curString.length(); i++) {
            char t = curString.charAt(i);
            if(isNumber(t)) {
                //数字直接输出
                System.out.print(t);
                result = result + t;
            }else if((t == ')' || t == ']' || t == '}')) {
                //当栈顶不是‘(’时,出栈并输出
                while(!stack.isEmpty() && stack.top() != '(' && stack.top() != '[' && stack.top() != '{'){
                    result += stack.top();
                    System.out.print((char)stack.pop());

                }
                //直到栈顶是‘(’
                if (!stack.isEmpty())
                    stack.pop();

            }else {//操作符或‘(’
                //当栈非空且t的优先级不大于栈顶元素时,出栈并输出然后t入栈
                while(!stack.isEmpty() && isPriority((char)stack.top(), t)) {
                    result += stack.top();
                    System.out.print((char)stack.pop());
                }
                stack.push(t);
            }
        }
        while(!stack.isEmpty()) {
            result += stack.top();
            System.out.print((char)stack.pop());
        }
        System.out.println();
        return result;
    }

    public static void main(String[] args) {
        LLStack stack = new LLStack();
        Scanner scanner = new Scanner(System.in);
        String curString = "";
        while(true) {
            System.out.println("请输入表达式:");
            curString = scanner.next();
            if(isMatch(stack,curString))
                MinddleTurnToBack(curString);
        }

    }
}



你可能感兴趣的:(数据结构,数据结构实验报告)