表达式计算

中缀表达式转后缀
后缀表达式计算
支持整型 分数计算,只支持 + - * /
package org.jf.alg.stack;

import java.util.List;
import java.util.ArrayList;
import java.util.Stack;

public class OperationUtil 
{

	/**
	 * 中缀表达式转为后缀表达式
	 * (1)获取下一个输入标记
	 * (2)如果标记是:
	 * 左括号:将其压入表达式栈
	 * 右括号:连续弹出并显示栈中的元素,直到遇到一个左括号
	 * 一个运算符:如果栈为空,或者标记具有比栈顶元素更高的优先级,则将其压入栈中,否则弹出并显示
	 *           栈顶元素;接着继续比较标记和新的栈顶元素
	 * 一个操作数:显示它
	 * (3)当到到中缀表达式结尾时,弹出并显示栈中的元素直到栈空
	 * @param middleFixString
	 * @param fraction
	 * @return
	 */
	public static List<String> toPostfixExp(String middleFixString,boolean fraction)
	{
		
		Stack<String> opSt = new Stack<String>();
		List<String> postExpList = new ArrayList<String>();
		List<String> eleList = getElementList(middleFixString,fraction);
		for(String ele:eleList)
		{
			char c = ele.charAt(0);
			if(ele.length()==1 && !(c>='0' && c<='9'))
			{
				switch(c)
				{
				case '(' :
					opSt.push(ele);
					break ;
				case ')' :
					for(;;)
					{
						if(opSt.isEmpty())
							break;
						String op = opSt.pop();
						if(op .equals("("))
							break;
							postExpList.add(op);
						
					}
					break ;
				default:
			
					if(opSt.isEmpty())
						opSt.push(ele);
					else
					{//比较优先级
						while(!opSt.isEmpty())
						{
							char opTop = opSt.peek().charAt(0);
							if(opSt.isEmpty()||opTop == '(')
							{
								opSt.push(ele);
								break;
							}
							
							if(getPriority(c)>getPriority(opTop))
							{
								opSt.push(ele);
								break;
							}
							else
							{
								postExpList.add(opSt.pop());
							}
						}
						
						if(opSt.isEmpty())
							opSt.push(ele);
					}
				}
			}
			else
			{
				postExpList.add(ele);
			}
		}
		
		while(!opSt.isEmpty())
		{
			postExpList.add(opSt.pop());
		}
		return postExpList;
	}
	
	
	

	private static List<String> getElementList(String middleFixExp,boolean fraction)
	{
		
		List<String> list = new ArrayList<String>();
		char [] seprator = null;
		if(fraction)
			seprator = new char[]{'+','-','*','(',')'};
		else
			seprator = new char[]{'+','-','/','*','(',')'};
		int opBeginIndx = -1;
		boolean isOperator = false;
		
		for(int i=0;i<middleFixExp.length();i++)
		{
			char curChar  = middleFixExp.charAt(i);
			isOperator = false;
			for(int j=0;j<seprator.length;j++)
			{
				if(seprator[j] == curChar)
				{   
					if(opBeginIndx != -1)
						list.add(middleFixExp.substring(opBeginIndx, i));
					list.add(curChar+"");
					isOperator  = true;
					opBeginIndx = -1;
					break;
				}
			}
			if(isOperator)
				continue;
			if(opBeginIndx == -1)
				opBeginIndx = i;
		}
		if(opBeginIndx != -1)
			list.add(middleFixExp.substring(opBeginIndx));
		return list;
	}
	
	public static String evaluate(String exp,boolean fraction)
	{
	
		Stack<String> sta = new Stack<String>();
		List<String> list = toPostfixExp(exp,fraction);
		String s ="";
		while(list.size()>0)
		{
			s = list.remove(0);
			if(s.length()==1 && !(s.charAt(0)>='0'&&s.charAt(0)<='9'))
			{
				String y = sta.pop();
				String x = sta.pop();
				
				if("+-*/".indexOf(s)>=0)
				{
					String result = "";
					if(fraction)
						result =caculateFraction(x,y,s.charAt(0));
					else
						result =caculateInteger(x,y,s.charAt(0));
					sta.push(result);
						
				}
				else throw new RuntimeException("not support operator:"+s); 
					
			}
			else
			{
				sta.push(s);
			}
		}
		
		return sta.pop();
	}
	
	private static String caculateInteger(String x,String y,char operator)
	{
		int px = Integer.parseInt(x);
		int py = Integer.parseInt(y);
		int result = 0;
		switch(operator)
		{
		case '+':
			result = px + py;
	        break;
		case '-' :
			result = px - py ;
			break;
		case '*' :
			result = px * py;
			break;
		case '/' :
			result = px / py;
			break;
		}
		return result+"";
	}
	
	private static String caculateFraction(String x,String y,char operator)
	{
		int dx = 1, dy = 1,nx = 1, ny = 1;
		if(x.indexOf("/")>0)
		{
			dx = Integer.parseInt(x.substring(x.indexOf("/")+1));
			nx = Integer.parseInt(x.substring(0,x.indexOf("/")));
		}else
		{
			nx = Integer.parseInt(x);
		}
		
		if(y.indexOf("/")>0)
		{
			dy = Integer.parseInt(y.substring(y.indexOf("/")+1));
			ny = Integer.parseInt(y.substring(0,y.indexOf("/")));
		}else
		{
			ny = Integer.parseInt(y);
		}
		
		String s = "";
		int sn = 0;
		int sd = 1;
		switch(operator)
		{
		
		 case '+':
			  sn = nx*dy+ny*dx;
			  sd = dx*dy;
			
			 break;
		 case '-':
			  sn = nx*dy-ny*dx;
			  sd = dx*dy;
			 if(sn%sd==0)
				 s = (sn/sd)+"";
			 else
				 s =  sn+"/"+sd;
			 break;
		 case '*':
			 sn = nx*ny;
			 sd = dx*dy;
			 break;
		 case '/':	 
			 sn = nx*dy;
			 sd = ny*dx;
			 break;
		}
		
		 if(sn%sd==0)
			 s = (sn/sd)+"";
		 else
			 s =  sn+"/"+sd;
		 return s;
	}
	
	private static int getPriority(char operator)
	{
		switch(operator)
		{
			case '+':
				return 0;
			case '-':
				return 0;
			case '*' :
				return 1;
			case '/' :
				return 1;
			case '%' :
				return 1;
			default :
				return -1;
		}
	}
	
	public static void main(String args[])
	{
//		System.out.println(Integer.parseInt("4/5"));
		String s ="+";
		System.out.println(s.length()==0 && !(s.charAt(0)>='0'&&s.charAt(0)<='9'));
		List<String> list = toPostfixExp("12+((3*(2-4/5))+5)*3",true);
		System.out.println(OperationUtil.evaluate("3+2-9", true));
	}
}

你可能感兴趣的:(表达式)