中缀表达式,后缀表达式,中缀表达式转后缀表达式

一. 后缀表达式求值

后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储。假定待求值的后缀表达式为:6 5 2 3 + 8 * + 3 + *,则其求值过程如下:
  • 1)遍历表达式,遇到的数字首先放入栈中,此时栈如下所示:

  • 2)接着读到“+”,则弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中。

  • 3)读到8,将其直接放入栈中。

  • 4)读到“”,弹出8和5,执行85,并将结果40压入栈中。而后过程类似,读到“+”,将40和5弹出,将40+5的结果45压入栈…以此类推。最后求的值288。
    java实现代码,有点臃肿

import java.util.Stack;

public class Test150_demo_1 {
	//放入的是数字不变,放入的是操作符,拿出栈顶下的第二个数,和第一个数操作完毕,在放入栈中
	 public static int evalRPN(String[] tokens) {
		  Stack<Integer> s = new Stack<Integer>();
		  for(int i=0;i<tokens.length;i++){
			  if(isstr(tokens[i])){  //是字符
				  int num1 = s.pop();
				  int num2 = s.pop();
				  int result = 0;
				  if(tokens[i].equals("+")){
					 result = num2+num1;
				  }
				  if(tokens[i].equals("-")){
					  result = num2-num1;
				  }
				  if(tokens[i].equals("*")){
					  result = num2*num1;
				  }
				  if(tokens[i].equals("/")){
					  result = num2/num1;
				  }
				  s.push(result);
			  }
			  else if(!isstr(tokens[i])){  //是数字
				  s.push(Integer.parseInt(tokens[i]));
			  } 
		  }
			 return s.pop();
		 }
		private static boolean isstr(String tokens) {
			if(tokens=="+"||tokens=="-"||tokens=="*"||tokens=="/"){
				return true;
			}
			return false;
		}
}

二.中缀表达式求值

后缀表达式也叫波兰表达式,而计算机不认识中缀表达式,需要转成后缀表达式进行求值。

中缀表达式转后缀表达式转化规则如下:
中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f + g * +。

转换过程需要用到栈,具体过程如下:
首先规定优先级

( >* = / > + = -

左括号>乘=除>+

只有右括号入栈后才把左括号到右括号之间的内容弹出

  • 1)如果遇到操作数,我们就直接将其输出。

  • 2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。

  • 3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。

  • 4)如果遇到任何其他的操作符,如(“+”, “*”,"( ”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) “的情况下我们才弹出” ( “,其他情况我们都不会弹出” ( "。

  • 放入的操作符和栈顶元素比较优先级 如果优先级大 放入,如果优先级小于栈顶元素,弹出栈顶元素,拿现在的栈顶元素相比,直到放入操作符的优先级大于栈顶元素的优先级,否则,弹出栈顶元素

  • 5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。

public class 中缀表达式转后缀表达式 {
	public static HashMap<String, Integer> map =  new HashMap<String, Integer>();
	public static StringBuffer sb = new StringBuffer();
	public static String transform(String strs[]){
		Stack<String> s = new Stack<String>();
		for(String str : strs){
			System.out.println(str);
			if(!isstr(str)){
	            if(str.equals("(")) s.push(str);
	            else sb.append(str);
			}
			else if(isstr(str)){ //如果是运算符号
				
				if(str.equals(")")){ 
					
					while(!s.peek().equals("(")){
						sb.append(s.pop());
					}
					s.pop();//弹出(
				}
				else{             //如果是加减乘除等操作符号 看优先级
					boolean isntInsert = true;
					if(s.size()==0) {
						s.push(str);
					isntInsert = false; //插入成功
					}
					while(isntInsert&&s.size()>0){
					if((map.get(str)>map.get(s.peek())||map.get(s.peek()).equals("("))){ //如果要放的优先级大于栈顶的优先级
						s.push(str);
						isntInsert = false;
					}
					else{                            //如果优先级小与等于
						sb.append(s.pop());
					}
					
					}
					if(s.size()==0) s.push(str);  //如果退不了 了
				}
			}
			
		}
		while(!s.isEmpty()){
			sb.append(s.pop());
		}
		return sb.toString();
	}
	public static boolean isstr(String tokens) {
	 if(tokens.equals("+")||tokens.equals("-")||tokens.equals("*")||tokens.equals("/")||tokens.equals(")")){
		
				return true;
			}
			return false;
		}
	
	public static void main(String[] args) {
		/*
		 * 主要逻辑 :
		 * 1 . 数字直接放入
		 * 2 . 操作符判断与栈顶的优先级关系,优先级大,放入。 优先级小于栈顶,弹出栈顶元素
		 * 3 . 如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。
		 * 4 . 如果我们读到了输入的末尾,则将栈中所有元素依次弹出。
		 */
		map.put("c", Integer.MAX_VALUE);
		map.put("+", 1);
		map.put("-", 1);
		map.put("*", 2);
		map.put("/", 2);
		map.put("(", 0);
		
		
		String s [] = {"3","+","5","*","(", "2" ,"+","6","-", "1" ,")"};
		System.out.println(transform(s));
	}
	
}

接下来我们就可以用后缀表达式,尽情的玩耍啦

代码写的较臃肿,欢迎大佬多多指教!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值