`

写了一个简单的Java版的eval函数

阅读更多
今天一同学做东西要用这个东东,就帮他写了一个,先转化成后缀表达式,然后再
计算.当然也可以直接计算中缀表达式,考虑到要多位数,就没那么做.
支持多位数的带括号的整数的加减乘除.

package edu.jlu.fuliang;

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

public class Eval {
   public int eval(String exp){
	   List<String> list = infixExpToPostExp(exp);//转化成后缀表达式
	   return doEval(list);//真正求值
   }
   
   //遇到操作符压栈,遇到表达式从后缀表达式中弹出两个数,计算出结果,压入堆栈
   private int doEval(List<String> list) {
	  Stack<String> stack =  new Stack<String>();
	  String element;
	  int n1,n2,result;
	  try{
		  for(int i = 0; i < list.size();i++){
			  element = list.get(i);
			  if(isOperator(element)){
				  n1 = Integer.parseInt(stack.pop());
				  n2 = Integer.parseInt(stack.pop());
				  result = doOperate(n1,n2,element);
				  stack.push(new Integer(result).toString());
			 }else{
				 stack.push(element);
			 }
		  }
		  return Integer.parseInt(stack.pop());
	  }catch(RuntimeException e){
		  throw new IllegalExpressionException(e.getMessage()); 	  
	  }
   }
   
   private int doOperate(int n1, int n2, String operator) {
      if(operator.equals("+"))
    	  return n1 + n2;
      else if(operator.equals("-"))
    	  return n1 - n2;
      else if(operator.equals("*"))
    	  return n1 * n2;
      else
          return n1 / n2;
   }

   private boolean isOperator(String str){
	   return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/");
   }
   
   private List<String> infixExpToPostExp(String exp){//将中缀表达式转化成为后缀表达式
	   List<String> postExp = new ArrayList<String>();//存放转化的后缀表达式的链表
	   StringBuffer numBuffer = new StringBuffer();//用来保存一个数的
	   Stack<Character> opStack = new Stack<Character>();//操作符栈
	   char ch,preChar;
	   opStack.push('#');
	   try{
		   for(int i = 0; i < exp.length();){
			   ch = exp.charAt(i);
			   switch(ch){
			   		case '+':
			   		case '-':
			   		case '*':
			   		case '/':
			   			preChar = opStack.peek();
//		    	如果栈里面的操作符优先级比当前的大,则把栈中优先级大的都添加到后缀表达式列表中
			   			while(priority(preChar) >= priority(ch)){
			   				postExp.add(""+preChar);
			   				opStack.pop();
			   				preChar = opStack.peek();
			   			}
			   			opStack.push(ch);
			   			i++;
			   			break;
			   		case '(':
//	            左括号直接压栈
			   			opStack.push(ch);
			   			i++;
			   			break;
			   		case ')':
//		    	右括号则直接把栈中左括号前面的弹出,并加入后缀表达式链表中
			   			char c = opStack.pop();
			   			while(c != '('){
			   				postExp.add("" + c);
			   				c = opStack.pop();
			   			}
			   			i++;
			   			break;
//		     #号,代表表达式结束,可以直接把操作符栈中剩余的操作符全部弹出,并加入后缀表达式链表中
			     case '#':
			    	 char c1;
			    	 while(!opStack.isEmpty()){
			    		 c1 = opStack.pop();
			    		 if(c1 != '#')
			    		   postExp.add("" + c1);
			    	 }
			    	 i++;
			    	 break;
	                          //过滤空白符
			     case ' ':
			     case '\t':
			    	 i++;
			    	 break;
//		    	 数字则凑成一个整数,加入后缀表达式链表中
			     default:
			    	 if(Character.isDigit(ch)){
			    		 while(Character.isDigit(ch)){
			    			 numBuffer.append(ch);
			    		     ch = exp.charAt(++i);
			    		 }
			             postExp.add(numBuffer.toString());
			             numBuffer = new StringBuffer();
			    	 }else{
			    		 throw new IllegalExpressionException("illegal operator");
			    	 }
			   }
		   }
	   }catch(RuntimeException e){
		   throw new IllegalExpressionException(e.getMessage()); 
	   }
	   return postExp;
   }
   
   private int priority(char op){//定义优先级
		switch(op){
	   	case'+':
	   	case'-':
	   		return 1;
	   	case'*':
	   	case'/':
	   		return 2;
	   	case'(':
	   	case'#':
	        return 0;
	   	}
		throw new IllegalExpressionException("Illegal operator");
  }
   
   public static void main(String[] args) {
	   Eval eval = new Eval();
	   int result = eval.eval("2+3+55*22+21*2+(3+2)*3+4*3+3*4#");
	   System.out.println(result);
   }
}



package edu.jlu.fuliang;

public class IllegalExpressionException extends RuntimeException{
    
	public IllegalExpressionException(){
		
    }
    
    public IllegalExpressionException(String info){
    	super(info);
    }
}

9
3
分享到:
评论
8 楼 wshcdr 2011-11-20  
不错,引用了
7 楼 fuliang 2010-06-30  
yangguo 写道
多位数怎么会正确呢?
22,5 +
压到栈后变成 225,怎么区分22跟5

22和5在栈的不同层中。
6 楼 yangguo 2010-06-12  
多位数怎么会正确呢?
22,5 +
压到栈后变成 225,怎么区分22跟5
5 楼 wjpiao 2010-02-26  
4楼正解,,哈哈,
楼主思路不错啊
4 楼 zht2006rj 2010-02-03  
24行:                  result = doOperate(n1,n2,element); 
改为                  result = doOperate(n2,n1,element); 
后缀表达式的做操作数先入栈,所以计算时候要交换下顺序,另外可以把数据类型都改为Double或者Float,就更好了.
3 楼 jxva 2008-10-17  
支持泛点数就比较好了!
2 楼 qwxi_1 2008-03-18  
我正在学习Java。看了你的程序,我有很大的收获。谢谢!
1 楼 galaxystar 2008-03-16  
恩,不错!

相关推荐

    java实现eval函数

    然而,如果你提供的压缩包"java实现eval函数"包含的是一个Java项目,那么它很可能是实现了类似功能的自定义解决方案,可能是一个解析器或者编译器,用于处理特定的表达式或脚本语法。这个项目可能包括以下几个部分:...

    java实现js中eval功能

    在Java中,没有直接对应的内置函数可以实现这样的功能,但我们可以构建一个类似的机制来模拟`eval()`的行为。 首先,我们需要理解`eval()`的核心功能:将字符串转换为可执行的代码。在Java中,这可以通过编译和执行...

    javascript 自定义eval函数实现

    以下是一个简单的示例,创建一个安全的`eval`替代函数: ```javascript function safeEval(code) { const sandbox = { Math, JSON, // 添加其他安全的全局对象... }; with (sandbox) { try { return new ...

    java动态特性eval

    在JavaScript中,`eval()`函数能够将一个字符串作为代码执行,从而实现动态编程。Java中虽然没有直接对应的内置方法,但通过一些技术手段,我们可以模拟实现类似的功能。 1. **Java反射机制**: Java反射API允许...

    java解析公式 eval.jar

    Java解析公式库`eval.jar`是一个专门为Java开发者设计的开源工具,它允许程序在运行时动态解析和执行数学表达式。这个库的核心功能是提供一个简单、高效的接口,用于处理包含加法(+)、减法(-)、乘法(*)、除法...

    利用eval()函数给树节点统一添加单击事件实现新建选项卡功能

    这篇博客“利用eval()函数给树节点统一添加单击事件实现新建选项卡功能”探讨了一个具体的JavaScript编程技巧,如何通过eval()函数来处理用户交互,特别是针对树形结构数据的点击事件,进而实现新的选项卡功能。...

    javascript中eval函数用法分析

    本文实例分析了javascript中eval函数用法。分享给大家供大家参考。具体分析如下: eval&#40;&#41;只有一个参数,如果传入的参数不是字符串,则直接返回这个参数。否则会将字符串当成js代码进行编译,如果编译失败则...

    JavaREPL是一个Java语言读入-求值-打印-循环(Read-Eval-Print-Loop)功能实现

    通过研究这些源代码,开发者可以了解如何实现一个简单的JavaREPL,或者对其进行定制以满足特定需求。 在实际使用JavaREPL时,开发者可以利用它来: - **快速测试代码片段**:比如尝试一个新的API调用,或者验证一...

    在java中利用动态编译实现eval

    在JavaScript等脚本语言中,`eval`函数接收一个字符串参数,该字符串被视为可执行的代码,然后解析并执行这个代码。这对于动态创建和执行代码非常有用,比如根据用户输入或外部数据动态生成操作。 在Java中,实现...

    写公共函数文件,要使用到类,将类传参进来.rb

    以下是一个简单的示例,展示了如何在Ruby中创建一个公共函数文件并接受类作为参数: ```ruby # 公共函数文件,例如命名为lib/utility_module.rb module UtilityModule # 定义一个接受类作为参数的公共函数 def ...

    ExprEval.rar_ExprEval_java 计算器_java表达式运算_jep-3.1.0-trial.jar_表达式

    在Java编程语言中,开发一个能够解析和计算数学表达式的工具是常见的需求,"ExprEval.rar"中的"ExprEval_java 计算器"就是这样一个实现。这个程序允许用户输入类似于传统数学作业中的表达式,然后自动进行计算。它...

    Java数学表达式计算(Expression Evaluator)

    在提供的压缩文件`ExprEvalSample`中,可能包含了一个简单的表达式评估器的示例代码。这个样本可能展示了一个自定义解析器的实现,包括如何处理运算符优先级、处理括号内的表达式,以及如何处理变量。分析这个代码...

    Java类似JavaScript的eval实现,和随机4个数计算24点

    但是,我们可以模拟实现一个类似的函数,来解析并计算简单的数学表达式。以下是一个基于给定内容的简化的Java `Eval` 类实现: ```java import java.util.Stack; public class Eval { private String exp; ...

    深入认识javascript中的eval函数

    eval函数接收一个参数s,如果s不是字符串,则直接返回s。否则执行s语句。如果s语句执行结果是一个值,则返回此值,否则返回undefined。 需要特别注意的是对象声明语法“{}”并不能返回一个值,需要用括号括起来才会...

    js eval 压缩工具

    "js eval 压缩工具"就是这样一个专门针对JavaScript文件进行压缩的工具,其原理是利用`eval`函数来执行经过压缩后的代码。 `eval`函数在JavaScript中是一个非常强大的功能,它可以将字符串作为JavaScript代码来执行...

    j4locr_eval

    标题“j4locr_eval”指向的是一个与Java开发相关的技术或库,特别是与图像处理或者文本识别有关,因为“j4locr”通常与OCR(Optical Character Recognition,光学字符识别)技术关联。这个“eval”可能表示这是评估...

    Java直接运行JS代码

    以下是一个简单的示例,展示如何使用Nashorn引擎在Java中运行JavaScript代码: ```java import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public ...

    利用java进行浮点型大数计算,支持四则运算和指数函数,三角函数,对数函数,双曲函数等运算,精度可调整

    利用java进行浮点型大数计算,支持四则运算和指数函数,三角函数,对数函数,双曲函数等运算,精度可调整。例如: MATH a=new MATH("1111.111111111111222222222222*33333333333); MATH b=a.eval&#40;"Sin(Pi(&#41;)...

    Z.Expressions.Eval.2.4.2

    总的来说,Z.Expressions.Eval 2.4.2 是一个强大且灵活的库,为Java开发者提供了便捷的表达式处理工具,使得在各种项目中实现自定义计算逻辑变得更加简单和高效。通过深入理解和熟练运用,你可以利用它的功能来提升...

Global site tag (gtag.js) - Google Analytics