java eval

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

Java 代码
  1. package  edu.jlu.fuliang;  
  2.   
  3. import  java .util.ArrayList;  
  4. import  java .util.List;  
  5. import  java .util.Stack;  
  6.   
  7. public   class  Eval  {  
  8.    public   int  eval (String exp){  
  9.        List list = infixExpToPostExp(exp);//转化成后缀表达式   
  10.        return  doEval(list); //真正求值   
  11.    }  
  12.      
  13.    //遇到操作符压栈,遇到表达式从后缀表达式中弹出两个数,计算出结果,压入堆栈   
  14.    private   int  doEval(List list) {  
  15.       Stack stack =  new  Stack();  
  16.       String element;  
  17.       int  n1,n2,result;  
  18.       try {  
  19.           for ( int  i =  0 ; i < list.size();i++){  
  20.               element = list.get(i);  
  21.               if (isOperator(element)){  
  22.                   n1 = Integer.parseInt(stack.pop());  
  23.                   n2 = Integer.parseInt(stack.pop());  
  24.                   result = doOperate(n1,n2,element);  
  25.                   stack.push(new  Integer(result).toString());  
  26.              }else {  
  27.                  stack.push(element);  
  28.              }  
  29.           }  
  30.           return  Integer.parseInt(stack.pop());  
  31.       }catch (RuntimeException e){  
  32.           throw   new  IllegalExpressionException(e.getMessage());         
  33.       }  
  34.    }  
  35.      
  36.    private   int  doOperate( int  n1,  int  n2, String operator) {  
  37.       if (operator.equals( "+" ))  
  38.           return  n1 + n2;  
  39.       else   if (operator.equals( "-" ))  
  40.           return  n1 - n2;  
  41.       else   if (operator.equals( "*" ))  
  42.           return  n1 * n2;  
  43.       else   
  44.           return  n1 / n2;  
  45.    }  
  46.   
  47.    private   boolean  isOperator(String str){  
  48.        return  str.equals( "+" ) || str.equals( "-" ) || str.equals( "*" ) || str.equals( "/" );  
  49.    }  
  50.      
  51.    private  List infixExpToPostExp(String exp){ //将中缀表达式转化成为后缀表达式   
  52.        List postExp = new  ArrayList(); //存放转化的后缀表达式的链表   
  53.        StringBuffer numBuffer = new  StringBuffer(); //用来保存一个数的   
  54.        Stack opStack = new  Stack(); //操作符栈   
  55.        char  ch,preChar;  
  56.        opStack.push('#' );  
  57.        try {  
  58.            for ( int  i =  0 ; i < exp.length();){  
  59.                ch = exp.charAt(i);  
  60.                switch (ch){  
  61.                     case   '+' :  
  62.                     case   '-' :  
  63.                     case   '*' :  
  64.                     case   '/' :  
  65.                         preChar = opStack.peek();  
  66. //              如果栈里面的操作符优先级比当前的大,则把栈中优先级大的都添加到后缀表达式列表中   
  67.                         while (priority(preChar) >= priority(ch)){  
  68.                             postExp.add("" +preChar);  
  69.                             opStack.pop();  
  70.                             preChar = opStack.peek();  
  71.                         }  
  72.                         opStack.push(ch);  
  73.                         i++;  
  74.                         break ;  
  75.                     case   '(' :  
  76. //              左括号直接压栈   
  77.                         opStack.push(ch);  
  78.                         i++;  
  79.                         break ;  
  80.                     case   ')' :  
  81. //              右括号则直接把栈中左括号前面的弹出,并加入后缀表达式链表中   
  82.                         char  c = opStack.pop();  
  83.                         while (c !=  '(' ){  
  84.                             postExp.add(""  + c);  
  85.                             c = opStack.pop();  
  86.                         }  
  87.                         i++;  
  88.                         break ;  
  89. //           #号,代表表达式结束,可以直接把操作符栈中剩余的操作符全部弹出,并加入后缀表达式链表中   
  90.                  case   '#' :  
  91.                      char  c1;  
  92.                      while (!opStack.isEmpty()){  
  93.                          c1 = opStack.pop();  
  94.                          if (c1 !=  '#' )  
  95.                            postExp.add(""  + c1);  
  96.                      }  
  97.                      i++;  
  98.                      break ;  
  99.                               //过滤空白符   
  100.                  case   ' ' :  
  101.                  case   '/t' :  
  102.                      i++;  
  103.                      break ;  
  104. //               数字则凑成一个整数,加入后缀表达式链表中   
  105.                  default :  
  106.                      if (Character.isDigit(ch)){  
  107.                          while (Character.isDigit(ch)){  
  108.                              numBuffer.append(ch);  
  109.                              ch = exp.charAt(++i);  
  110.                          }  
  111.                          postExp.add(numBuffer.toString());  
  112.                          numBuffer = new  StringBuffer();  
  113.                      }else {  
  114.                          throw   new  IllegalExpressionException( "illegal operator" );  
  115.                      }  
  116.                }  
  117.            }  
  118.        }catch (RuntimeException e){  
  119.            throw   new  IllegalExpressionException(e.getMessage());   
  120.        }  
  121.        return  postExp;  
  122.    }  
  123.      
  124.    private   int  priority( char  op){ //定义优先级   
  125.         switch (op){  
  126.         case '+' :  
  127.         case '-' :  
  128.             return   1 ;  
  129.         case '*' :  
  130.         case '/' :  
  131.             return   2 ;  
  132.         case '(' :  
  133.         case '#' :  
  134.             return   0 ;  
  135.         }  
  136.         throw   new  IllegalExpressionException( "Illegal operator" );  
  137.   }  
  138.      
  139.    public   static   void  main(String[] args) {  
  140.        Eval  eval  = new  Eval ();  
  141.        int  result = eval .eval ( "2+3+55*22+21*2+(3+2)*3+4*3+3*4#" );  
  142.        System.out.println(result);  
  143.    }  
  144. }  
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 list = infixExpToPostExp(exp);//转化成后缀表达式
	   return doEval(list);//真正求值
   }
   
   //遇到操作符压栈,遇到表达式从后缀表达式中弹出两个数,计算出结果,压入堆栈
   private int doEval(List list) {
	  Stack stack =  new Stack();
	  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 infixExpToPostExp(String exp){//将中缀表达式转化成为后缀表达式
	   List postExp = new ArrayList();//存放转化的后缀表达式的链表
	   StringBuffer numBuffer = new StringBuffer();//用来保存一个数的
	   Stack opStack = new Stack();//操作符栈
	   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);
   }
}


Java 代码

转自:http://fuliang.javaeye.com/blog/172233
未研究

你可能感兴趣的:(java概念,基础知识)