接尾辞式計算単純四則演算(かっこなし)

3680 ワード

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

/**
 * 
 */

/**
 * @author  *
 */
public class PostfixEvaluator {

	/**
	 *                 
	 * @param string
	 * @return
	 */
	public static String[] parseExpress(String string)
	{
		string = string.replaceAll("\\+", " + ");
		string = string.replaceAll("-", " - ");
		string = string.replaceAll("\\*", " * ");
		string = string.replaceAll("/", " / ");
		String[] array = string.split(" ");
		System.out.println(Arrays.toString(array));
		return array;
	}
	
	/**
	 *               
	 * @param infixArray
	 * @return
	 */
	public static List<String> infixToPostfix(String[] infixArray)
	{
		List<String> list = new ArrayList<String>();
		Stack<String> stack = new Stack<String>();
		//       
		for (String str : infixArray)
		{
			if (0 == oprLevel(str))
			{
				//      ,    
				list.add(str);
			}
			else if ( stack.isEmpty() || (oprLevel(str) > oprLevel(stack.peek())))
			{
				//     ,                 ,    
				stack.push(str);
			}
			else
			{
				//      ,                  ,          ,
				//                     ,          
				while(!stack.isEmpty() && (oprLevel(str) <= oprLevel(stack.peek())))
				{
					list.add(stack.pop());
				}
				stack.push(str);
			}
		}
		
		//        ,        ,     
		while (!stack.isEmpty())
		{
			list.add(stack.pop());
		}
        System.out.println(list);
        //        
		return list;
	}
	
	/**
	 *          
	 * @param str
	 * @return 0 :    
	 *         1 :   
	 *         2 :   
	 */
	public static int oprLevel(String str)
	{
		if (str.equals("*") || str.equals("/"))
		{
			return 2;
		}
		else if (str.equals("+") || str.equals("-"))
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
	
	/**
	 *        
	 * @param postfix
	 * @return
	 */
	public static int calculatePostfix(String[] postfix)
	{
		Stack<Integer> stack = new Stack<Integer>();
		for (String token : postfix)
		{
			if ( 0 == oprLevel(token))
			{
				stack.push(Integer.parseInt(token));
			} 
			else 
			{
				int result = applyOpr(token, stack.pop(), stack.pop());
				stack.push(result);
			}
		}
		
		if (stack.size() != 1)
		{
			throw new IllegalArgumentException("         " + Arrays.toString(postfix));
		}
		
		return stack.pop();
	}
	
	/**
	 *          
	 * @param opr
	 * @param second
	 * @param first
	 * @return
	 */
	public static int applyOpr(String opr, int second, int first)
	{
		int result;
		char oprChar = opr.charAt(0);
		switch (oprChar) {
		case '+':
			result = first + second;
			break;
		case '-':
			result = first - second;
			break;
		case '*':
			result = first * second;
			break;
		case '/':
			result = first / second;
			break;
		default:
			throw new IllegalArgumentException("   '" + opr + "'  ");
		}
		
		return result;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String[] array = PostfixEvaluator.parseExpress("100+20*30-200/10");
//		System.out.println("  [100,20,30,*,+,200,10,/,-]");
        List<String> list = PostfixEvaluator.infixToPostfix(array);
        int result = calculatePostfix(list.toArray(new String[list.size()]));
        System.out.println(result);
//        String[] array2 = PostfixEvaluator.parseExpress("a+b*c-d");
//		System.out.println("  [a,b,c,*,+,d,-]");
//        List<String> list2 = PostfixEvaluator.infixToPostfix(array2);
	}

}