Java双栈算式解释器

import java.util.Stack;
// 

import java.util.regex.*;
import java.util.Stack;

/**
 * This class use for get calculate result from the String expression
 * we know that Java language have not class implement method calculate math 
 * expression, JavaScript have implement "eval".
 * First get simple math expression, iteration wipe out brackets, get expression
 * in brackets and format with priority, then insert result of formative expression 
 * into original expression, and simplify again
 * 
 * Support operator "+", "-", "*", "/", "(", ")", "(-)"
 * use Stack.RegEx
 * 
 * @author Denua
 * @version 07 May 2017 11.48
 */
public class Interpreter {

    public static void main(String[] args) {
        
        String s = "(1+2)-3*5+(5/5*5+5)-1/2";
        Interpreter in = new Interpreter();
        System.out.printf("%s = %g",s,in.elv(s));
    }
    /**
     * public method as the entry
     * @param str 
     *             String expression
     * @return
     *         double calculate result
     */
    public double elv(String str){
        
        double res = 0.00;
        res = eval(formate(
                       getSimple(str)                        
                  )
              );    
        return res;
    }
    /**
     * return String simple expression without brackets,use RegEx check brackets and get 
     * result from the expression in the brackets
     * @param str 
     *             String  complex expression
     * @return String 
     *             String simple expression
     */
    private String getSimple(String str){
        
        String res = str;
        // RegEx matching the expression in brackets
        Pattern pat2 = Pattern.compile("\\([\\d\\.\\+\\-\\*\\/]+\\)");
        // matching 
        Matcher mat = pat2.matcher(str);
        // if find matching, get simple expression result and joint to origin expression
        if( mat.find() ){
            String find = mat.group(0);
            String st1 = res.substring(0, str.indexOf(find));    
            String st2 = res.substring(str.indexOf(find) + find.length(), res.length());
            
            find = find.substring(1, find.length() - 1);
            find = formate(find);
            find = String.valueOf(eval(find));

            res = st1 + find + st2; 
            // matching again and find expression in brackets, if find, get simple expression
            Matcher mat2 = pat2.matcher(res);
            if(mat2.find()){
                res = getSimple(res);
            }
        }
        return res;
    }
    /**
     * add brackets for the simple String expression, complete priority, check
     *  each element in the expression 
     * 
     * @param str 
     *             String simple  expression
     * @return String 
     *             complete priority expression 
     */
    private String formate(String str){
        
        String res = str;
        String[][] part = getPart(res);
        String[] pt = new String[part[0].length];
        
        for(int q=0; q < pt.length; q++){
            pt[q] = "";
        }
        
        int count = part[0].length;
        int i = 0;
        
//  all case in priority
//         (*)    *     
//         (+)    +
     
//         (*)    +
//         (+)    *
        
//         +    *  (*)    +
//         * (*)    +
        
        while( i < count){

            String id= part[0][i];
            String ir = null;
            if(i < count - 1)
                ir = part[0][i + 1];

            if( nl(id) && nl(ir) ){
                
                if( isf(id) ){
                    
                    if( isf(ir) ){
                        pt[i+1] += ")";
                    }
                    else if( ! isf(ir) ){
                        pt[i+1] += ")";                        
                        int idx = i - 1;
                        
                        while( idx >= 0 ){
                            String si = part[0][idx];
                            if( ! isf(si) ){
                                pt[i+1] = "))";
                                break;
                            }
                            idx--;
                        }        
                    }
                }
                if( ! isf(id) ){
                    
                     if( ! isf(ir) )
                        pt[i+1] += ")";    
                }                
            }
            else if( nl(id) && ! nl(ir)){
                
                if( isf(id) ){                    
                    int ix = i - 1;
                    boolean find = false;
                    
                    while( ix >= 0 ){
                        String six = part[0][ix];
                        if( ! isf(six) ){
                            find = true;                            
                            break;
                        }
                        ix--;
                    }
                    if(find)
                        part[1][i+1] += "))";
                    else
                        part[1][i + 1] += ")";
                }
                else
                    part[1][i + 1] += ")";
            }
            else{
                return null;
            }                        
            i++;
        }
        res = "";
        for(int j = 0; j < part[0].length; j ++){
            part[0][j] = pt[j] + part[0][j];
            res =res + part[1][j] + part[0][j];
        }
        res += part[1][part[1].length -1];
        
        return res;
    }
    /**
     *  use two Stack calculate expression with complete priority, one Stack
     *  save number another save operator, check each element in the expression
     *  with complete priority, if current element is number, then add to 
     *  number Stack, if operator, add to operator Stack, else is ")" ,  extract
     *  two number from the number Stack, extract operator from the operator Stack
     *  and add result to number Stack, iteration get final result.
     * 
     * @param str 
     *             Complete priority expression
     * @return double 
     *             the result of the expression
     */
    private Double eval(String str){
        
        Stack<String> operate = new Stack<String>();
        Stack<Double> value = new Stack<Double>();
        
        String[] ele = getEle(str);
        
        int i = 0;
        while( i < ele.length){

            String s = ele[i];
            if(s.equals("(")){
            }
            else if(s.equals("+"))        operate.push(s)    ;
            
            else if(s.equals("-"))        operate.push(s) ;

            else if(s.equals("*"))        operate.push(s)    ;

            else if(s.equals("/"))        operate.push(s)    ;

            else if(s.equals("s"))        operate.push(s)    ;

            else if(s.equals(")")){
                
                String op = operate.pop();
                double vl = value.pop();
                
                if(op.equals("+"))            vl = value.pop() + vl;
                
                else if(op.equals("-"))        vl = value.pop() - vl;
                
                else if(op.equals("*"))        vl = value.pop() * vl;
                
                else if(op.equals("/"))        vl = value.pop() / vl;
                
                else if(op.equals("s"))    vl = Math.sqrt(vl);
                
                value.push(vl);
            }
            else{
                value.push(Double.parseDouble(s));
            }            
            i++;
        }
        return value.pop();
    }
    /**
     * get each part of the expression, cut expression and transform to Array
     * @param str complete priority expression
     * @return String[] 
     */
    private String[] getEle(String str){
        
        Stack<String> st = new Stack<String>();
        
        int j = 0;
        String numbTemp = "";
        while( j < str.length()){
            char temp = str.charAt(j);
            if( isNum(temp) || temp == ‘.‘ || ( j == 0 && temp == ‘-‘) || ( temp == ‘-‘ && isOp(str.charAt(j - 1)) ) ){                
                numbTemp += temp;
            }
            else if( ! isNum(temp)  ){
                if( !numbTemp.isEmpty()){
                    st.push(numbTemp);
                    numbTemp = "";
                }
                st.push(String.valueOf(temp));
            }
            j++;
        }
        
        String[] res = new String[st.size()];
        for(int i = st.size() - 1; i >= 0; i -- ){
            res[i] = st.pop();
        }
        return res;
    }
    private String[][] getPart(String str){
        
        String res = str;        
        int i = 0;
        Stack<String> cal = new Stack<String>();
        Stack<String> op = new Stack<String>();
        
        String num = "";
        while( i < res.length()){
            char temp = res.charAt(i);            
            if( isOp(temp) ){
                if(temp == ‘-‘ && i == 0)
                    num += "-";
                else if( temp == ‘-‘ && isOp(res.charAt(i-1)) )
                    num += "-";
                else
                    op.push(String.valueOf(temp));
            }
            else if(isNum(temp)){
                num += String.valueOf(temp);
                if(i >= str.length()){
                    break;
                }
                else{
                    if( i == str.length() - 1){
                        
                        String n = String.valueOf(str.charAt(i));
                        if( isNum(n) && isNum(String.valueOf(str.charAt(i-1)))){
                            num += n;
                        }
                        else{
                            num = n;
                        }
                    }
                    else{
                        String n = String.valueOf(str.charAt(i + 1));
                        boolean flag = true;
                        while( isNum(n) && flag){                        
                            num += n;
                            i ++;
                            
                            if( i > res.length() - 2){
                                flag = false;
                            }else{
                                n = String.valueOf(str.charAt(i + 1));
                            }
                        }
                    }                    
                }
                cal.push(num);
                num = "";
            }
            else if(temp == ‘)‘){        
                op.push(")");
            }
            i++;
        }
        i = 0;
        
        String[][] part = new String[2][];
        String[] temp1 = new String[op.size()];
        String[] temp2 = new String[cal.size()];
        for(Object o:op.toArray()){
            temp1[i] = (String) o;
            i++;            
        }
        i = 0;
        for(Object o:cal.toArray()){
            temp2[i] = (String) o;
            i++;            
        }
        
        part[0] = temp1;
        part[1] = temp2;
        
        return part;
        
    }
    private boolean isNum(String str){
        return  str.equals("0") || str.equals("1") || str.equals("2") || str.equals("3") || str.equals("4") ||
                str.equals("5") || str.equals("6") || str.equals("7") || str.equals("8") || str.equals("9") || str.equals(".");
    }
    private boolean isOp(char str){        
        return str == ‘s‘ || str == ‘+‘  ||str == ‘-‘  || str == ‘*‘  || str == ‘/‘ ;
    }
    private boolean isNum(char str){
        return  str == ‘0‘  || str == ‘1‘ || str == ‘2‘  || str == ‘3‘  || str == ‘4‘  ||
                str == ‘5‘  || str == ‘6‘  || str == ‘7‘  || str == ‘8‘  || str == ‘9‘ || str == ‘.‘  ;
    }    
    private boolean isf(String str){
        return str.equals("*") || str.equals("/");
    }
    private boolean nl(Object obj){
        return obj != null;
    }
}
时间: 2024-10-18 17:36:53

Java双栈算式解释器的相关文章

Java实现Djikstra双栈算式解释器, 识别添加优先级

package Dijkstra; import java.util.Stack; import java.util.regex.*; /** * This class use for get calculate result from the String expression * we know that Java language have not class implement method calculate math * expression, JavaScript have imp

JBoss7配置之支持IPv4和IPv6双栈环境

由于实验室项目需要,将EJB 3.0的程序部署在JBoss AS 7.1.1.Final中,并要求支持IPv4与IPv6.但其默认配置并不支持IPv6,于是查阅JBoss Community Documentation,即官方文档,在5.4.1 Interfaces and ports节中找到了相关介绍,研究后对JBoss进行配置修改,使JBoss中EJB 3.0的程序能够在IPv4和IPv6双栈环境下正常运行,包括客户端在IPv4环境下获取Remote远程接口对象,调用远程对象的方法收发IPv

Dijkstra的双栈算术表达式求值

import java.util.Stack; import java.util.Scanner; public class Evaluate { public static void main(String[] args) { Stack<String> ops=new Stack<String>(); Stack<Double> vals=new Stack<Double>(); Scanner cin=new Scanner(System.in); /

探究Java虚拟机栈

前言 Java 虚拟机的内存模型分为两部分:一部分是线程共享的,包括 Java 堆和方法区:另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一小部分内存.今天我就 Java 虚拟机栈做一些比较浅的探究. 熟悉 Java 的同学应该都知道了,JVM 是基于栈的.但是这个"栈" 具体指的是什么?难道就是虚拟机栈?想要回答这个问题我们先要从虚拟机栈的结构谈起. 虚拟机栈 何为虚拟机栈虚拟机栈的栈元素是栈帧,当有一个方法被调用时,代表这个方法的栈帧入栈:当这个方法返回时,其栈帧

AC日记——双栈排序 洛谷 P1155

双栈排序 思路: 二分图染+模拟: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 #define maxm 2000005 int n,head[maxn],E[maxm],V[maxm],cnt,col[maxn]; int minn[maxn],ai[maxn],sta1[maxn],sta2[maxn],top1,top2; bool if_[maxn][maxn]; inline void in(

NOIP2008 双栈排序

题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1不为空,将S1栈顶元素弹出至输出序列 操作c 如果输入序列不为空,将第一个元素压入栈S2 操作d 如果栈S2不为空,将S2栈顶元素弹出至输出序列 如果一个1~n的排列P可以通过一系列操作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”.例如(1,3,2,4)就是一个“可

JAVA虚拟机栈

JAVA虚拟机栈几个重要概念 java 虚拟机栈 = java virtual machine stacks = jvms 1.JVMS 线程私有,生命周期与线程相同 2.JVMS 描述的是JAVA方法执行的内存模型:JVMS在方法执行时会创建一个"栈帧" stack frame,用于记录局部变量表.操作数栈.动态链接.方法出口等,每一个方法从调用到完成的过程,就是一个栈帧在JVMS中入栈到出栈的过程 3.局部变量表存放基本数据类型.对象引用.returnAddress(字节码指令地址

BZOJ 2080: [Poi2010]Railway 双栈排序

2080: [Poi2010]Railway Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 140  Solved: 35[Submit][Status][Discuss] Description 一个铁路包含两个侧线1和2,右边由A进入,左边由B出去(看下面的图片) 有n个车厢在通道A上,编号为1到n,它们被安排按照要求的顺序(a1,a2,a3,a4....an)进入侧线,进去还要出来,它们要按照编号顺序(1,2,3,4,5....n)从通道B

Java虚拟机栈和本地方法栈

Java虚拟机栈的特征 线程私有 后进先出(LIFO)栈 存储栈帧,支持Java方法的调用.执行和退出 可能出现OutOfMemoryError异常和StackOverflowError异常 Java本地方法栈的特征 线程私有 后进先出(LIFO)栈 作用是支撑Native方法的调用.执行和退出 可能出现OutOfMemoryError异常和StackOverflowError异常 有一些虚拟机(如HotSpot)将Java虚拟机栈和本地方法栈合并实现 栈帧的概念和特征 Java虚拟机栈中存储的