`
Jatula
  • 浏览: 278444 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

一个简单的Eval算法的启示

阅读更多

前些天在 fuliang 的博客上面看到他写的一个eval算法,我再贴出来,当做收藏,希望fuliang不要介意;

 

package com.jatula.util;   
  
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 com.jatula.util;   
  
public class IllegalExpressionException extends RuntimeException{   
       
    public IllegalExpressionException(){   
           
    }   
       
    public IllegalExpressionException(String info){   
        super(info);   
    }   
}  

 

 

我想说的是,让我想到了Google的搜索可以做计算的用法,虽然这算法以前读书也学过,不过总不能找到一个可以用在实践的地方,终于记下来了;3Q

2
2
分享到:
评论

相关推荐

    一个简单的dh加密算法实现

    简单的DH加密算法程序,采用C语言实现,权当学习资料使用; 一共7个函数,加上一个主程序实现; 不用makefile文件编写,直接一个文件编译执行

    动态规划,分治算法,概率算法,模拟退火算法,搜索算法,贪婪算法,网上matlab,遗传算法,组合算法

    2. **分治算法**:分治策略是将一个大问题分解为两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。典型的分治算法包括快速排序、归并排序和大数乘法等。 3. **...

    数学建模30个常用算法(Python)

    数学建模30个常用算法(Python)数学建模30个常用算法(Python)数学建模30个常用算法(Python)数学建模30个常用算法(Python)数学建模30个常用算法(Python)数学建模30个常用算法(Python)数学建模30个常用算法...

    算法披露的域外经验与启示.docx

    算法披露的域外经验与启示 算法披露是指将算法的原理、参数和实验结果公开,以提高算法的透明度和可解释性。算法披露有助于促进算法领域的发展和创新,并且可以提高算法的可靠性和信任度。通过算法披露,人们可以更...

    算法图解.pdf,就是个简单的一个pdf

    算法图解.pdf,就是个简单的一个pdf,这里有字数要求啊,哎呀哎呀,算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解...

    一个简单银行家算法实现实例

    这个银行家算法的实现很简单,只是简单的模拟了操作系统课本上的一个实例

    模型算法大全(20+种常用算法模型+代码实现)

    模型算法大全(20+种常用算法模型+代码实现)模型算法大全(20+种常用算法模型+代码实现)模型算法大全(20+种常用算法模型+代码实现)模型算法大全(20+种常用算法模型+代码实现)模型算法大全(20+种常用算法模型+...

    算法文档无代码搬运工问题的启示

    这种方式意味着,算法文档中可能会包含一个百度网盘的分享链接,使用该链接可以访问包含算法代码的文件,而不直接在文档中嵌入代码。这种方式的好处是,可以保持算法文档的整洁,避免大量代码段落干扰文档的阅读,...

    社区划分算法的python3实现, 包括KL算法、 COPAR、Louvain 算法、LFM算法、InfoMap算法等

    社区发现是网络分析中的一个重要领域,它旨在将网络中的节点划分为不同的群组或社区,以便更好地理解网络的结构和功能。在这个Python3实现的压缩包中,包含了多种社区划分算法,包括KL算法、COPAR、Louvain算法、LFM...

    一个简单的KNN算法的实现脚本文件

    KNN(K-Nearest Neighbor)算法是机器学习算法中最基础、最简单的算法之一,这是一个简单的KNN算法的实现脚本文件,其中有具体的执行代码和提示,

    平面区域简单种子填充算法的改进

    种子填充算法作为其中的一种方法,其核心思想是通过一个种子点(即区域内部的任意一点)开始,递归地将相同颜色的像素点连接起来,直至整个区域被覆盖。然而,传统的简单种子填充算法存在效率低下和内存消耗大的问题...

    操作系统磁盘调度算法实验报告

    本实验报告的主要目的是设计一个磁盘调度模拟系统,旨在使磁盘调度算法更加形象化、易于理解,使磁盘调度的特点更简单明了。通过本实验,学生可以加深对先来先服务算法、最短寻道时间优先算法、扫描算法以及循环扫描...

    一个简单的javademo,实现sm国密算法。

    一个简单的javademo,实现sm国密算法。希望对大家有所帮助,SMS4算法是在国内广泛使用的WAPI无线网络标准中使用的加密算法,是一种32轮的迭代非平衡Feistel结构的分组加密算法,其密钥长度和分组长度均为128。SMS4...

    逍遥风算法精华集.chm

    ·18.THrawN的CRACKME8算法简单分析 ·19.OCN算法练习(VB的很简单) ·20.crackme算法分析 ·21.一个2合1的CRACKME算法分析 ·22.简单CRACKME算法分析(很适合新手) ·23.一个简单的CRACKME算法分析(适合新手) ...

    基于matlab实现的RRT算法、双向RRT算法、A*算法、PRM、模糊路径规划算法、遗传算法路径规划

    1. **RRT(快速探索随机树)算法**:RRT是一种随机规划算法,它通过不断扩展一个随机树来搜索目标区域。每次迭代时,RRT会在当前树的邻居中随机选择一个点,并尝试向目标方向生长。当新点与现有树中的某个点足够接近...

    银行家算法-----一个n个并发进程共享m个资源的银行家算法的模拟实现

    (1) 简单的交互界面 (2) 能显示当前系统资源的剩余情况和占用情况 (3) 能输入每个进程的最大资源要求 模拟利用银行家算法为进程的若干次资源请求分配资源 (4) 输入本次资源要求; (5) 按银行家算法为进程分配资源,...

    计算机图形学实验一(DDA算法、中点算法、Bresenham算法、中点画圆算法)

    1、运行附件中参考例子,理解Visual C++和OpenGL的使用。...5、构造任意一个封闭并且不自交的多边形,假定该多边形内部是四连通的。要求: 用多边形扫描线算法实现对多边形内部的填充,要求内部颜色和边界颜色不一致。

    java算法全卷(包括基本算法和图算法)

    Java算法全卷涵盖了基本算法和图算法,是学习和提升编程技能的重要资源。...这两部分结合,为Java开发者提供了一个全面的算法学习资源库,无论你是初学者还是经验丰富的开发人员,都能从中受益匪浅。

    一个简单的字符串加密解密算法(C#)

    一个简单的字符串加密解密算法,使用C#语言实现。。。

    算法实习:分治算法求n个数的数组中找出第二个最大元素

    分治(Divide and Conquer)是一种重要的算法设计策略,它通过递归地将一个问题分解成两个或更多的相同或相似的子问题,直到最后子问题可以简单地直接求解,原问题的解即为子问题的解的合并。分治法通常包含三个步骤...

Global site tag (gtag.js) - Google Analytics