栈的应用:表达式求值

中缀表达式转后缀表达式:

思路:
	1)初始或两个栈:运算符栈s1和存储中间结果的栈s2;
	2)从左至右扫描中缀表达式;
	3)遇到操作数时,直接压s2;
	4)遇到运算符时,与s1栈顶元素比较优先级;
		1、如果s1为空,或者栈顶运算符为"(",则直接入栈;
		2、否则,若优先级比栈顶运算符的高,也压入s1;
		3、否则,将s1栈顶的运算符弹出并压入到s2中,再次转到4.1与s1新的栈顶运算符进行比较;
	5)遇到括号时:
		1、如果是“(”,则直接压入s1
		2、如果时”)“,则依次弹出s1的栈顶运算符,并压入s2,直到遇到左括号为止,此时将一对括号丢弃。
	6)重复2-5,直到表达式的最右边
	7)将s1剩余的运算符依次弹出并压入s2
	8)依次弹出s2中的元素并输出,结果的逆序为中缀表达式对应的后缀表达式

将运算表达式转成中缀表达式

  public static List<String> tosuffiExpression(String s) {
	        List<String> list = new ArrayList<String>();
	        int index = 0;//相当于指针,用于遍历字符串
	        String str;//用于拼接字符
	        char ch;//存放字符
	
	        do {
				// ch = s.charAt(index);
	            if ((ch = s.charAt(index)) < 48 || (ch = s.charAt(index)) > 57) {
	                //说明不是数字,直接存入集合
	                list.add(ch + "");
	                index++;
	            } else {//如果是数字,需要考虑多位数的情况
	                str = "";
	                while (index < s.length() && (ch = s.charAt(index)) >= 48 && (ch = s.charAt(index)) <= 57) {
	                    str += ch;
	                    index++;
	                }
	                list.add(str);
	            }
	        } while (index < s.length());
	        return list;
	    }
中缀表达式转换成后缀表达式
		public static List<String> parseSuffixExpreesionList(List<String> list) {
		    Stack<String> s1 = new Stack<String>();//运算符栈
		    //没有pop直接使用List<>替代
		    //Stack<String> s2 = new Stack<String>();//中间结果栈
		    List<String> s2 = new ArrayList<>();//存放中间结果
		    //遍历中缀表达式
		    for (String item : list) {
		        if (item.matches("\\d+")) {
		            s2.add(item);
		        } else if ("(".equals(item)) {
		            s1.push(item);
		        } else if (")".equals(item)) {
		            while (!s1.peek().equals("(")) {
		                s2.add(s1.pop());
		            }
		            s1.pop();//弹出小括号
		        } else {//优先级
		            while (s1.size() != 0 &&Operation.getValue(s1.peek())>=Operation.getValue(item)) {
		                s2.add(s1.pop());
		            }
		            s1.push(item);
		        }
		    }
		    while (s1.size()!=0){
		        s2.add(s1.pop());
		    }
		    return s2;
		}

用逆波兰表达式计算出后缀表达式的值

思路:
1、对集合进行遍历
2、遇到数字,直接入栈
3、遇到符号,从栈中取出两个数字进行计算,然后把结果放入栈中。
代码实现:
				 public static int calculate(List<String> list) {
		        Stack<String> stack = new Stack<String>();
		
		        for (String item : list) {
		//            正则表达式判断取出来的数据是否为整数
		            if (item.matches("\\d+")) {
		                stack.push(item);
		            } else {
		                int num1 = Integer.parseInt(stack.pop());
		                int num2 = Integer.parseInt(stack.pop());
		                int num = 0;
		                if ("+".equals(item)) {
		                    num = num1 + num2;
		                } else if ("-".equals(item)) {
		                    num = num2 - num1;
		                } else if ("*".equals(item)) {
		                    num = num1 * num2;
		                } else if ("/".equals(item)) {
		                    num = num2 / num1;
		                } else {
		                    throw new RuntimeException("运算符有误");
		                }
		                stack.push(String.valueOf(num));
		            }
		        }
		        return Integer.parseInt(stack.pop());
		    }
		}
		
		//返回操作符的优先级
		class Operation {
		
		    private static int ADD = 1;
		    private static int SUB = 1;
		    private static int MUL = 2;
		    private static int DIV = 2;
		
		    public static int getValue(String operation) {
		        int result = 0;
		        switch (operation) {
		            case "+":
		                result = ADD;
		                break;
		            case "-":
		                result = SUB;
		                break;
		            case "*":
		                result = MUL;
		                break;
		            case "/":
		                result = DIV;
		                break;
		            case "(":
		                break;
		            default:
		                System.out.println("不存在该运算符:"+operation);
		                break;
		        }
		        return result;
		    }
		}
posted @ 2020-05-11 21:23  爱敲代码的小游子  阅读(6)  评论(0)    收藏  举报