⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xiaoboalgorithm.java

📁 计算器
💻 JAVA
字号:
/**
 * 
 */
package com.calc.algorithm;

import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import com.calc.model.Algorithm;

/**
 * @author 孙晓波
 * 表达式计算实现算法的具体实现类
 *
 */
public class XiaoBoAlgorithm implements Algorithm {

	public XiaoBoAlgorithm(){}
	/* (non-Javadoc)
	 * @see com.calc.model.Algorithm#calcExpr(java.lang.String)
	 */
	public double calcExpr(String expr) throws Exception {
		// TODO Auto-generated method stub
		expr="("+expr+")";
		List infix=getTokens(expr); //
		List postfix=covertToPostFix(infix);
		//下面计算后缀表达式的值
		return calculatePostfix(postfix);
	}
	
	/**
	 * 将表达式分解
	 * @param expr
	 * @return
	 */
	private List getTokens(String expr)throws Exception{
		List<String> list=new ArrayList<String>();
		StreamTokenizer tokenizer=new StreamTokenizer(new InputStreamReader(new ByteArrayInputStream(expr.getBytes())));
		tokenizer.resetSyntax();
		tokenizer.parseNumbers();
		tokenizer.ordinaryChar(43); // '+'
		tokenizer.ordinaryChar(45); // '-'
		tokenizer.ordinaryChar(42); // '*'
		tokenizer.ordinaryChar(47); // '/'
		tokenizer.ordinaryChar(40); // '('
		tokenizer.ordinaryChar(41); // ')'
		tokenizer.ordinaryChar(44); // ','
		tokenizer.wordChars(65, 90); //A-Z
		tokenizer.wordChars(97, 122); //a-z
		int type=0;
		while(true){
			type=tokenizer.nextToken();
			if(tokenizer.ttype==StreamTokenizer.TT_EOF){
				break;
			}
			if(type==StreamTokenizer.TT_NUMBER){
				list.add((new Double(tokenizer.nval).toString()));
			}else if(type==StreamTokenizer.TT_WORD){
				list.add(tokenizer.sval);
			}else{
				list.add(""+(Character.toChars(tokenizer.ttype))[0]);
			}
		}
		return list;
	}
	/**
	 * 将前缀计发转换成后缀计发,方便计算机进行计算
	 * @param infix
	 * @return
	 */
	private List covertToPostFix(List infix){
		Stack stack=new Stack();
		List list=new ArrayList();
		Iterator iter=infix.iterator();
		stack.push((String)iter.next()); //'('
		while(iter.hasNext()){
			String token=(String)iter.next();
			if(",".equals(token)){
				//stack.push(token);
				continue;
			}
			if("(".equals(token)){
				stack.push(token);
				continue;
			}
			if(")".equals(token)){
				String p=null;
				while(!(p=(String)stack.pop()).equals("(")){
					list.add(p);
				}
				continue;
			}
			if(!isOperator(token)){ //数字
				list.add(token);
				continue;
			}
			if(isOperator(token)){
				if(!stack.isEmpty()){
					String p=(String)stack.pop();
					if(isPrecedence(p,token)){
						list.add(p);
						stack.push(token);
					}else{
						stack.push(p);
						stack.push(token);
					}
				}else{
					stack.push(token);
				}
				continue;
			}
			
		}
		return list;
		
	}
	/**
	 * 计算后缀表达式的值
	 * @param postfix
	 * @return
	 */
	private double calculatePostfix(List postfix)throws Exception{
		postfix.add(")");
		Stack stack= new Stack();
		Iterator iter=postfix.iterator();
		while(iter.hasNext()){
			String token=(String)iter.next();
			if(")".equals(token)){
				return Double.valueOf((String)stack.pop());
			}
			if(!isOperator(token)){
				stack.push(token);
				continue;
			}
			if(isOperator(token)){
				//如果是函数
				if(com.calc.config.Config.isFunction(token)){
					if(com.calc.config.Config.getFunctionArgsCount(token)==1){
						String var=(String)stack.pop();
						double tres=caclulate(var,token);
						stack.push(""+tres);
						continue;
					}
					if(com.calc.config.Config.getFunctionArgsCount(token)==2){
						String var2=(String)stack.pop();
						String var1=(String)stack.pop();
						double tres=caclulate(var1,token,var2);
						stack.push(""+tres);
						continue;
					}if(com.calc.config.Config.getFunctionArgsCount(token)==0){
						double tres=caclulate(token);
						stack.push(""+tres);
						continue;
					}
				}else{
					String var2=(String)stack.pop();
					String var1=(String)stack.pop();
					double tres=caclulate(var1,token,var2);
					stack.push(""+tres);
					continue;
				}
			}
		}
		throw new Exception("calculate error!");
	}
	/**
	 * 判断op1操作符是否优先与op2操作符
	 * 如果是返回true,否则返回false
	 * @param op1
	 * @param op2
	 * @return
	 */
	private boolean isPrecedence(String op1,String op2){
		double p1=com.calc.config.Config.getOperatorPrecedence(op1);
		double p2=com.calc.config.Config.getOperatorPrecedence(op2);
		if(p1>=p2){
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 是否是操作符
	 * @param op
	 * @return
	 */
	private boolean isOperator(String op){
		return com.calc.config.Config.isOperator(op);
	}
	/**
	 * 无参数函数
	 * @param operator
	 * @return
	 */
	public double caclulate(String operator){
		try{
			if(com.calc.config.Config.isFunction(operator)){
				//是数学函数,那我们得用反射
				String mfun=com.calc.config.Config.getMathFunc(operator);
				Double res=new Double(0);		
					 Class mathClass = Class.forName("java.lang.Math");
			         java.lang.reflect.Method mfunMethod =
			        	 mathClass.getMethod(mfun, (Class[])null);
			         // do the invocation
			        res = (Double)mfunMethod.invoke(mathClass, (Object[])null);			
				return res.doubleValue();
			}
			throw new Exception("no such FUnction!");
		}catch(Exception err){
			System.out.print(err);
			return 0;
		}
	}
	/**
	 * 计算双目运算
	 * @param v1
	 * @param operator
	 * @param v2
	 * @return
	 */
	private double caclulate(String v1,String operator,String v2){
		double var1=Double.valueOf(v1);
		double var2=Double.valueOf(v2);
		try{
			if(com.calc.config.Config.isFunction(operator)){
				//是数学函数,那我们得用反射
				String mfun=com.calc.config.Config.getMathFunc(operator);
				Double res=new Double(0);		
					 Class mathClass = Class.forName("java.lang.Math");
			         java.lang.reflect.Method mfunMethod =
			        	 mathClass.getMethod(mfun, double.class,double.class);
			         // do the invocation
			        res = (Double)mfunMethod.invoke(mathClass, var1,var2);			
				return res.doubleValue();
			}else{
				//那就是+ - * /
				if("+".equals(operator)){
					return var1+var2;
				}else if("-".equals(operator)){
					return var1-var2;
				}else if("*".equals(operator)){
					return var1*var2;
				}else{/*("/".equals(operator))*/
					return var1/var2;
				}
			}
		}catch(Exception err){
			System.out.println(err);
			return 0;
		}
	}
	/**
	 * 计算单目运算
	 * 我们利用反射
	 * @param v
	 * @param operatoer
	 * @return
	 */
	private double caclulate(String v,String operatoer){
		String mfun=com.calc.config.Config.getMathFunc(operatoer);
		double var=Double.valueOf(v);
		Double res=new Double(0);
		try{
			 Class mathClass = Class.forName("java.lang.Math");
	         java.lang.reflect.Method mfunMethod =
	        	 mathClass.getMethod(mfun, double.class);
	         // do the invocation
	        res = (Double)mfunMethod.invoke(mathClass, var);		
		}catch(Exception err){
			System.out.println(err);
		}
	
         return res.doubleValue();
	}
	
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -