计算中缀表达式字符串的值

中缀表达式就是:“数字A    操作符    数字B”   这样的结构 ,例如:

           A + B 

           A * B + C

           就是 符号在两个数的中间

 

 

后缀表达式格式为: “数字A    数字B   操作符” 这样的结构 ,例如:

       AB+            

       AB*C+

       ABC+*

 

将后缀表达式 变为中缀表达式

      AB+        -->   A + B

     AB*C+     -->  A * B + C

     ABC+*     -- > A * (B + C)

 

 

如果给一个中缀表达式字符串,要计算其值 , 可以将其转换为后缀表达式 ,然后计算后缀表达式的值。

 

package com.zf.test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class EndsExpression {

	private final String regexStr = "(\\([\\d\\.-]+?\\)|\\d)(\\([\\d\\.-]+?\\)|\\d)([*/+-])";
	
	
	//计算后缀表达式的值
	public String resove(String exp){  

		Matcher matcher = Pattern.compile(regexStr).matcher(exp);  
		while(matcher.find()){
			double first = Double.valueOf(replaceToNumeral(matcher.group(1)));
			double second = Double.valueOf(replaceToNumeral(matcher.group(2)));
			String oprator = matcher.group(3); 
			double sum = calc(first , second , oprator);  //计算结果
			String sumStr = String.valueOf(sum);
			sumStr = sumStr.length() > 1 ? ( "(" + sumStr + ")" ) : sumStr; 
			exp = exp.substring(0, matcher.end() - (matcher.group(1).length() + matcher.group(2).length() + 1 )) + sumStr  + exp.substring(matcher.end(), exp.length()); 
			matcher = Pattern.compile(regexStr).matcher(exp);  
		} 
		return replaceToNumeral(exp) ;
	}

	// 将 (12) 这中值 变成 12 ,去掉其中的() 符号 , 使其变为数字格式
	public String replaceToNumeral(String str){
		return str.replace("(", "").replace(")", "");  
	}

	//根据两个数  和 一个操作符计算
	public double calc(double first , double second , String oprator){
		if(oprator.equals("+")){
			return first + second;
		}else if(oprator.equals("-")){
			return first - second;
		}else if(oprator.equals("*")){
			return first * second;
		}else if(oprator.equals("/")){  
			return first / second; 
		}else{
			return 0 ;
		}
	}

	//中缀表达式转换为后缀表达式
	public String transForm(String middleExp){
		String regStr = "\\d+\\.\\d+|\\d+|[+-/*\\()]";   
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(middleExp);

		StringBuffer endExp = new StringBuffer(); //后缀表达式 
		StackX<String> stack = new StackX<String>(100);   //操作符栈

		while(matcher.find()){
			String current = matcher.group();
			current = current.length() > 1 ? ( "(" + current + ")" ) : current;
			if(current.matches("[+-/*\\()]")){
				if(stack.isEmpty()){	 //栈为空 ,直接推入
					stack.put(current);
				}else{

					if(current.equals(")")){
						String top  = stack.pop() ;  //推出栈顶 操作符
						while(!top.equals("(")){
							endExp.append(top);  
							top  = stack.pop();
						}
					}else{

						String top  = stack.pop() ;  //推出栈顶 操作符
						if(top.equals("(") || compareOprator(current , top) > 0){   //当前操作符比 栈顶操作符大 , 就推入栈顶
							stack.put(top);
						}else{   //当前操作符 <= 栈顶操作符
							endExp.append(top);
						}
						stack.put(current);		
					}
				}
			}else{	//常数
				endExp.append(current);
			}
		}
		
		while(!stack.isEmpty())
			endExp.append(stack.pop());
		
		return endExp.toString() ;
	}

	//比较操作符优先级
	public int compareOprator(String op1 , String op2){
		if(op1.matches("[+-]")){
			if(op2.matches("[+-]")){
				return 0;
			}else{  
				return -1 ;  
			}
		}else if(op1.matches("/*")){
			if(op2.matches("[/*]")){
				return 0;
			}else if(op2.matches("[+-]")){
				return 1 ;  
			}else{
				return -1 ;
			}
		}else{
			if(op2.matches("[\\()]")){
				return 0;
			}else{
				return 1 ;
			}
		}
	}

	public static void main(String[] args) {
		EndsExpression e = new EndsExpression();
		
		String middleExps[] = new String[]{ 
				"12 + 2-21" 
			   ,"100*3 + 31 - 1 "
			   ,"12 * 3 + ( 1 - 2 * 2 )"
			   ,"20 * 2 + (2.31 - 1)*2 + 2"
		};
		
		for (String middleExp : middleExps) {    
			String endExp = e.transForm(middleExp);
			String result = e.resove(endExp);
			System.out.printf("中缀表达式%1$s\t转换为后表达式为:%2$s\t计算后缀表达式结果为:%3$s\n"  , middleExp , endExp , result);
		}
		
	}

}

 

使用到的工具类:

package com.zf.test;

public class StackX<T> {

	private int maxLengh ;

	private int top ;

	private Object[] array ;

	public StackX(int maxLengh){
		this.maxLengh = maxLengh ;
		this.array = new Object[maxLengh];
		this.top = -1 ;
	}

	
	public int size(){
		return this.top ;  
	}

	public void put(T entry){
		if(isFull())
			throw new ArrayIndexOutOfBoundsException("array is fully!");
		array[++top] = entry ;
	}
    
	@SuppressWarnings("unchecked")
	public T pop(){
		if(isEmpty())  
			throw new ArrayIndexOutOfBoundsException("array is empty!");
		return (T)array[top--];  
	}
	
	public boolean isEmpty(){
		return top == -1 ;
	}
	
	public boolean isFull(){
		return top == maxLengh - 1;
	}

}



 

结果:

中缀表达式12 + 2-21	转换为后表达式为:(12)2+(21)-	计算后缀表达式结果为:-7.0
中缀表达式100*3 + 31 - 1 	转换为后表达式为:(100)3*(31)+1-	计算后缀表达式结果为:330.0
中缀表达式12 * 3 + ( 1 - 2 * 2 )	转换为后表达式为:(12)3*122*-+	计算后缀表达式结果为:33.0
中缀表达式20 * 2 + (2.31 - 1)*2 + 2	转换为后表达式为:(20)2*(2.31)1-2*2++	计算后缀表达式结果为:44.62


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值