利用Stack进行四则运算表达式求值

题目一:请利用Stack把字符串中缀表达式编译为后缀表达式,然后再利用栈执行后缀表达式获得计算结果。
题目二:请把带变量的中缀表达式编译为后缀表达式,执行后缀表达式时,传入变量的值并获得计算结果。

  • 中缀表达式转为后缀表达式:
    1.按次序读取中缀表达式的字符。
    2.读到一个操作数的时候,立即放入到输出中。
    3.读到操作符“+”,“-”,“*”,“/”,则从栈中弹出栈元素并输出,直到遇到优先级更低或者“(”的为止操作符为止(该元素不出栈)。
    4.读到操作符“(”,则直接把“(”压入栈中。
    5.读到操作符“)”,则从栈中弹出栈元素并输出,直到遇到第一个“(”为止。其中“(”不再添加到输出中,而是直接舍弃。
    6.当输入为空时,把栈里的操作符全部依次弹出并输出。
  • 根据后缀表达式 计算结果:
    1.按次序读取后缀表达式的每一个字符。
    2.读取到操作数时,把操作数压入栈中。
    3.读取到操作符时,对栈顶的2个操作数做相应运算,要注意操作数的前后顺序。结果压入栈中。
    4.读取完所有的字符后,弹出栈。得到的值就是所求结果。

题目一代码:

import java.util.Deque;
import java.util.LinkedList;
import java.util.*;
public class Main {
	public static void main(String[] args) {
//	--------- stack 中缀表达式编译为后缀表达式 ---------------------
		String exp = "1 + 2 * (9 - 5)";
		SuffixExpression se = compile(exp);
		Float result = se.execute();
		System.out.println(exp + " = " + result + " " + (result == 1 + 2 * (9 - 5) ? "✓" : "✗"));
		
	}
	static SuffixExpression compile(String exp) {
		// TODO:中缀转后缀
//		1.按次序读取中缀表达式的字符。
//		2.读到一个操作数的时候,立即放入到输出中。
//		3.读到操作符“+”,“-”,“*”,“/”,则从栈中弹出栈元素并输出,直到遇到优先级更低或者“(”的为止操作符为止(该元素不出栈)。
//		4.读到操作符“(”,则直接把“(”压入栈中。
//		5.读到操作符“)”,则从栈中弹出栈元素并输出,直到遇到第一个“(”为止。其中“(”不再添加到输出中,而是直接舍弃。
//		6.当输入为空时,把栈里的操作符全部依次弹出并输出。
		Deque<Character> rs= new LinkedList<>();
		char[] cexp = exp.toCharArray();
		String out = "";
		
		for(int i = 0; i < cexp.length; i++) {
			char ch = cexp[i];
			
			if (ch == ' ') continue;
			
			if (ch >= '0' && ch <= '9') {
				out += ch;
				continue;
			}
			
			if (ch == '(') {
				 rs.push(ch);
			}
			
			if (ch == '+' || ch =='-') {
				while(!rs.isEmpty() && (rs.peek() != '(')) {
					out += rs.pop();
				}
				rs.push(ch);
				continue;
			}
			
			if (ch == '*' || ch =='/') {
				while(!rs.isEmpty() && (rs.peek() == '*' || rs.peek() == '/')) {
					out += rs.pop();
				}
				rs.push(ch);
				continue;
			}
			
			if (ch == ')') {
				while(!rs.isEmpty() && rs.peek() != '(') {
					out += rs.pop();
				}
				rs.pop();
				continue;
			}
		}
		while(!rs.isEmpty()) out += rs.pop();
		System.out.println(out);
		return new SuffixExpression(out);
	}
}

class SuffixExpression {
	String exp;
	public SuffixExpression(String exp) {
		this.exp = exp;
	}
	
	public float execute() {
		//TODO:根据后缀表达式 计算结果
//		1.按次序读取后缀表达式的每一个字符。
//		2.读取到操作数时,把操作数压入栈中。
//		3.读取到操作符时,对栈顶的2个操作数做相应运算,要注意操作数的前后顺序。结果压入栈中。
//		4.读取完所有的字符后,弹出栈。得到的值就是所求结果。
		Deque<Float> cs= new LinkedList<>();
		char[] cexp = exp.toCharArray();
		for (int i = 0; i < cexp.length; i++) {
			char ch = cexp[i];
			if (ch>='0' && ch<='9') {
				 cs.push(Float.valueOf(ch - '0'));
				 continue;
			} else {
				cs.push(calculate(ch, cs.pop(), cs.pop()));
			}
		}
		System.out.println(exp);
		return  cs.pop();
	}
	
	public float calculate(char op, Float f1, Float f2) {
		if (op == '+') return f1 + f2;
		else if (op == '-') return f2 -f1;
		else if (op == '*') return f1 * f2;
		else if (op == '/') return f2/f1;
		else return Float.valueOf(-0);
	}
}

题目二代码:

import java.util.*;
public class Main {
    public static void main(String[] args) {
        String exp = "x + 2 * (y - 5)";
        SuffixExpression se = compile(exp);
//        System.out.println(se);
        Map<String, Float> env = Map.of("x", 5f, "y", 6f);// 使用Map保存变量值
        float result = se.execute(env);
        System.out.println(exp + " = " + result + " " + (result == 5 + 2 * (6 - 5) ? "✓" : "✗"));
    }

    static SuffixExpression compile(String exp) {
		// TODO:中缀转后缀
//		1.按次序读取中缀表达式的字符。
//		2.读到一个操作数的时候,立即放入到输出中。
//		3.读到操作符“+”,“-”,“*”,“/”,则从栈中弹出栈元素并输出,直到遇到优先级更低或者“(”的为止操作符为止(该元素不出栈)。
//		4.读到操作符“(”,则直接把“(”压入栈中。
//		5.读到操作符“)”,则从栈中弹出栈元素并输出,直到遇到第一个“(”为止。其中“(”不再添加到输出中,而是直接舍弃。
//		6.当输入为空时,把栈里的操作符全部依次弹出并输出。
		Deque<Character> rs= new LinkedList<>();
		char[] cexp = exp.toCharArray();
		String out = "";
		
		for(int i = 0; i < cexp.length; i++) {
			char ch = cexp[i];
			
			if (ch == ' ') continue;
			
			if (ch >= '0' && ch <= '9') {
				out += ch;
				continue;
			}
			
			if (ch == 'x' || ch == 'y') {
				out +=ch;
				continue;
			}
			
			if (ch == '(') {
				 rs.push(ch);
			}
			
			if (ch == '+' || ch =='-') {
				while(!rs.isEmpty() && (rs.peek() != '(')) {
					out += rs.pop();
				}
				rs.push(ch);
				continue;
			}
			
			if (ch == '*' || ch =='/') {
				while(!rs.isEmpty() && (rs.peek() == '*' || rs.peek() == '/')) {
					out += rs.pop();
				}
				rs.push(ch);
				continue;
			}
			
			if (ch == ')') {
				while(!rs.isEmpty() && rs.peek() != '(') {
					out += rs.pop();
				}
				rs.pop();
				continue;
			}
		}
		while(!rs.isEmpty()) out += rs.pop();
		return new SuffixExpression(out);
	}
}

class SuffixExpression {
	String exp;
	public SuffixExpression(String exp) {
		this.exp = exp;
	}
	
	// 后缀表达式计算
    public float execute(Map<String, Float> env) {

    	//TODO:根据后缀表达式 计算结果
//		1.按次序读取后缀表达式的每一个字符。
//		2.读取到操作数时,把操作数压入栈中。
//		3.读取到操作符时,对栈顶的2个操作数做相应运算,要注意操作数的前后顺序。结果压入栈中。
//		4.读取完所有的字符后,弹出栈。得到的值就是所求结果。
		Deque<Float> cs= new LinkedList<>();
		char[] cexp = this.exp.toCharArray();
		for (int i = 0; i < cexp.length; i++) {
			char ch = cexp[i];
			if (ch>='0' && ch<='9') {
				 cs.push(Float.valueOf(ch - '0'));
				 continue;
			} else if(ch =='x' || ch =='y') {
				String sc = Character.toString(ch);
				cs.push(env.get(sc));//利用key读取变量x, y的值
				continue;
			}
			else{
				cs.push(calculate(ch, cs.pop(), cs.pop()));
			}
		}
		System.out.println(exp);
		return  cs.pop();
    }
    //根据运算符返回计算结果
    public float calculate(char op, float f1, float f2) {
		if (op == '+') return f1 + f2;
		else if (op == '-') return f2 - f1;
		else if (op == '*') return f1 * f2;
		else if (op == '/') return f2 / f1;
		else return Float.valueOf(-0);
	}
}

你可能感兴趣的:(Java,stack,java)