逆波兰算法

import java.util.Stack;   
import java.util.regex.Matcher;   
import java.util.regex.Pattern;   
public class Count {   
    // 操作符数组,优先级从低到高   
    private static String[] operas = { "#", "+-", "*/", "%^" };   
    public static String test(String s) {   
        if (null == s)   
            return "";   
        s += "#";   
        Pattern num = Pattern.compile("^(\\d+(\\.\\d+)?)(.*)");   
        Matcher matcher;   
        Stack<String> stack1 = new Stack<String>();   
        Stack<String> stack2 = new Stack<String>();   
        char ch;   
        while (s.length() > 0) {   
            matcher = num.matcher(s);   
            // 判断开头是否是数字   
            if (matcher.find()) {   
                stack2.add(matcher.replaceAll("$1"));   
                s = matcher.replaceAll("$3");   
            } else {   
                ch = s.charAt(0);   
                s = s.substring(1);   
                // //////////   
                // / 优先级 '(' ')'   
                // /////////   
                if ('(' == ch) {   
                    stack1.add("" + ch);   
                    continue;   
                } else if (ch == ')') {   
                	//查看堆栈顶部的对象,但不从堆栈中移除它
                    while (!stack1.isEmpty() && !("(").equals(stack1.peek())) {   
                        stack2.add(calc(stack2.pop(), stack1.pop().charAt(0), stack2.pop()));   
                    }   
                    if (!stack1.isEmpty())   
                        stack1.pop();   
                    continue;   
                }   
                // ////////////   
                // / 计算表达式   
                // ///////////   
                if (isOpea(ch)) {   
                    while (true) {   
                        if (!stack1.isEmpty() && yxj("" + ch, stack1.peek())) {   
                            stack2   
                                    .add(calc(stack2.pop(), stack1.pop().charAt(0), stack2   
                                            .pop()));   
                        } else {   
                            stack1.add("" + ch);   
                            break;   
                        }   
                    }   
                } else {   
                    throw new RuntimeException("表达式非法!!");   
                }   
            }   
        }   
        return stack2.pop();   
    }   
    /**  
     * 判断一个字符是否是操作符  
     *   
     * @param ch  
     *            需要判断的字符  
     * @return 如果是操作符返回 true 否则返回 false  
     */  
    private static boolean isOpea(char ch) {   
        for (String str : operas) {   
            if (str.indexOf(ch) != -1)   
                return true;   
        }   
        return false;   
    }   
    /**  
     * 比较操作符的优先级  
     *   
     * @param str  
     *            第一个操作符  
     * @param str1  
     *            第二个操作符  
     * @return 第一个操作符的优先级高于第二个操作符 返回false 否则返回 true  
     */  
    private static boolean yxj(String str, String str1) {   
        int stack1 = 0, stack2 = 0;   
        for (int i = 0; i < operas.length; i++) {   
            if (operas[i].indexOf(str) > -1) {   
                stack1 = i;   
            }   
            if (operas[i].indexOf(str1) > -1) {   
                stack2 = i;   
            }   
        }   
        return stack2 >= stack1;   
    }   
    /**  
     * 计算  
     *   
     * @param stack1  
     *            操作数1  
     * @param c  
     *            操作符  
     * @param stack2  
     *            操作数2  
     * @return 返回操作数1和操作数2 经过操作符 c 运算后的结果  
     */  
    private static String calc(String stack1, char c, String stack2) {   
        String result = "0";   
        Double d1 = Double.parseDouble(stack1);   
        Double d2 = Double.parseDouble(stack2);   
        switch (c) {   
        case '+':   
            result = "" + (d1 + d2);   
            break;   
        case '-':   
            result = "" + (d2 - d1);   
            break;   
        case '*':   
            result = "" + (d1 * d2);   
            break;   
        case '/':   
            result = "" + (d2 / d1);   
            break;   
        case '%':   
            result = "" + (d2 % d1);   
            break;   
        case '^':   
            result = "" + (Math.pow(d2, d1));   
            break;   
        }   
        return result;   
    }   
    public static void main(String[] args) {   
        System.out.println(test("(1+1+1+1*1*2.5*3)/2-1)"));   
    }   
} 

 也是在别人这里看到的,给大家分享

猜你喜欢

转载自qq-24665727.iteye.com/blog/2299159