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 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-05 13:21:51

Java实现Djikstra双栈算式解释器, 识别添加优先级的相关文章

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, JavaS

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

java的堆,栈,静态代码区 详解

面试中,有家公司做数据库开发的,对内存要求比较高,考到了这个 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配.你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象. ------最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈(stack).位于通用RAM中,但通过它的“栈指针”可以从处理器哪里获得支持

约吗,IPv6/IPv4双栈命中注定需要发生的事

导读:曾经发过一条朋友圈:说说那个让你奋不顾身的人的故事吧.收到了很多留言,其中有一个男孩的留言让我印象很深刻.他说,刚见到她第一眼的时候,就喜欢上了.她给我的感觉,和其他人真的不一样.我不敢轻举妄动,怕她觉得这样我太肤浅,但不知道为什么,说不上她哪里好,但就是谁都替代不了. 虽然今天讲的这个事情(IPv6/IPv4双栈),没有那么美好的意境,但不约有些人是会后悔的. 2016年5月5日消息,苹果向开发者发出提醒,App Store将于今年6月1日实施全新策略,届时所有提交至苹果App Stor

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); /

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)就是一个“可

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

二分图 and code1170 双栈排序

6.6二分图 二分图是这样一个图: 有两顶点集且图中每条边的的两个顶点分别位于两个顶点集中,每个顶点集中没有边直接相连接. 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数. 判断二分图的常见方法是染色法: 开始对任意一未染色的顶点染色,之后判断其相邻的顶点中,若未染色则将其染上和相邻顶点不同的颜色, 若已经染色且颜色和相邻顶点的颜色相同则说明不是二分图,若颜色不同则继续判断,bfs和dfs都可以. 易知:任何无回路的的图均是二分图. 代码: bool Color(