中序表达式:

中序表达式就是我们日常使用的表达式,由左往右阅读,结构清晰,但需要括号改变优先级,对计算机不友好

eg: (1+4)*3+10/5

前序表达式(波兰表示法Polish notation,或波兰记法):

一种逻辑算术代数表示方法,其特点是操作符置于操作数的前面,如果操作符的元数(arity)是固定的,则语法上不需要括号仍然能被无歧义地解析,不需要括号来改变优先级,未推广使用。

eg:

中序表达式:(1 + 4) * 3 + 10 / 5 

前序表达式:  + * + 1 4 3  / 10 5 


前序表达式的运算:
    
eg:
    + * + 1 4 3  / 6 5 

运算: + 1 4  =>   1 + 4 = 5  
      
      * 5 3  =>  5 * 3 = 15
     
新前序: + 15 / 10 5 
    
    / 10 5  =>  10 / 5 =2
    
新前序:  + 15 2
        
      =>  15 + 2 = 17  

 

后序表达式(逆波兰表示法Reverse Polish notationRPN,或逆波兰记法):

所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级,使用广泛。艾兹格·迪科斯彻引入了调度场算法,用于将中缀表达式转换为后缀形式。因其操作类似于火车编组场而得名。 大多数操作符优先级解析器(解析器用简单的查表操作即可实现,优先级表由开发者自己定制,在不同的应用场景中,开发者可自由改变操作符的优先级)能转换为处理后缀表达式,实际中,一般构造抽象语法树,树的后序遍历即为逆波兰记法。

eg:

中序表达式:(1 + 4) * 3 + 10 / 5 

后序表达式: 1 4 + 3 *  10 5 / +


后序表达式的运算:
    
eg:
    1 4 + 3 *  10 5 / +

运算: 1 4 +  =>   1 + 4 = 5  
      
      5 3 *  =>  5 * 3 = 15
     
新后序:  15 / 10 5 + 
    
     10 5  / =>  10 / 5 =2
    
新后序:  15 2 +
        
      =>  15 + 2 = 17  

中序转后序(调度场算法)

  1. 创建一个队列和一个操作数栈
  2. 遇到操作数则送入队列
  3. 遇到操作符则送入栈
  4. 当碰到与栈顶同优先级的操作符,则将栈顶的操作符取出,送入队列,并将新操作符压入栈中
  5. 遇到” )“括号则将栈内从”( “到” )“的所有操作符全部取出送入队列
  6. 表达式分类完成后,先输出队列内容,再输出栈内容,前者+后者便是后序表达式

实现代码(Java版):

public static String InfixToPostfix(String s) {
		
    Stack<Character> stack = new Stack<Character>();
    Queue<Character> queue = new Queue<Character>();
    
    Character s1 = ' ';
    char peeks = ' '; // 栈顶元素

    for (int i = 0; i < s.length(); i++) {

	// 如果是操作数,则送入操作数队列
	if (s.charAt(i) >= 48 && s.charAt(i) <= 57) {
	    queue.enqueue(s.charAt(i) );
	    continue;
	  }

      // 如果碰到右括号则遍历栈,并送入队列,直到碰到"("
	if (s.charAt(i) == ')') {
	    s1 = stack.pop();
	    while (s1 != '(' ) {
		queue.enqueue(s1);
		s1 = stack.pop();
	     }
	continue;
	}
			
       
       // 如果出现同优先级的运算符, 则将栈顶元素送入队列中 同时新运算符送入栈内
    
	if ( (s.charAt(i) == '/' || s.charAt(i) == '*') &&
             (peeks == '*' || peeks == '/') ) {
	
            queue.enqueue(stack.pop());
	    stack.push(s.charAt(i));
	    peeks=s.charAt(i);
	}
	
        // 剩下的普通情况下的操作符,送入操作符栈
	{
	    stack.push(s.charAt(i) );
	    peeks = s.charAt(i);	
	}

    }

    s = " ";// 初始化s来接收表达式

    //接收队列的值
    do {
	s += queue.dequeue() +" ";
    } while (!queue.isEmpty());

    //接受栈的值		
    do {
	s += stack.pop() + "  ";
    } while (!stack.isEmpty());
		
    return s;
}

 

posted on 2019-04-19 19:30  jeasion  阅读(1742)  评论(0编辑  收藏  举报