现在的位置: 首页 > 综合 > 正文

算数表达式求值

2018年01月31日 ⁄ 综合 ⁄ 共 8023字 ⁄ 字号 评论关闭

HaspMap方法:

转载自:

http://www.eoeandroid.com/thread-317031-1-1.html

public double StringToDouble(String s1) {
		double d = 0;
		// 字符串按加减号分开
		String[] a = s1.split("[+-]");
		// 这不用说了
		List<Map<String, Object>> list;
		List<Map<String, Object>> list2 = new ArrayList<Map<String, Object>>();
		char cc[] = s1.toCharArray();
		for (int i = 0; i < cc.length; i++) {
			Map<String, Object> map2 = new HashMap<String, Object>();
			if (cc[i] == '+') {
				map2.put("P", "add");
				list2.add(map2);
			}
			if (cc[i] == '-') {
				map2.put("P", "sub");
				list2.add(map2);
			}
		}
		/*
		 * Toast.makeText(CalcolatorActivity.this, list2.size() + "s1/x",
		 * Toast.LENGTH_LONG).show();
		 */
		int x = 0;
		// 循环a字符串数组
		for (int i = 0; i < a.length; i++) {
			// 按照乘除分教
			String[] b = a[i].split("[*/]");
			/*
			 * Toast.makeText(CalcolatorActivity.this, b.length + "b",
			 * Toast.LENGTH_LONG).show();
			 */
			// 吧分解到的a在分解成字符数组
			char c[] = a[i].toCharArray();
			// 循环a是每次创建集he
			list = new ArrayList<Map<String, Object>>();
			// 遍历字符数组每次创建一个万能的map,用来存放算式中的乘除法。
			for (int j = 0; j < c.length; j++) {
				Map<String, Object> map = new HashMap<String, Object>();
				if (c[j] == '/') {
					map.put("M", "div");
					list.add(map);
				}
				if (c[j] == '*') {
					map.put("M", "mul");
					list.add(map);
				}
			}
			// Toast.makeText(CalcolatorActivity.this,
			// list.size() + ":list", Toast.LENGTH_LONG).show();
			// 利用存放好的map和a数组结合起来,遍历算出每个a的结果。
			int w = 0;
			double dd = 1;
			if (list.size() == 0) {
				// dd=Double.parseDouble(a[i]);
				dd = Double.parseDouble(1 + "");
			} else {

				for (int k = 0; k < b.length - 1; k++) {
					if (w == 0) {
						double d1 = Double.parseDouble(b[k]);
						double d2 = Double.parseDouble(b[k + 1]);
						String m = list.get(k).get("M").toString();
						if (m.equals("mul")) {
							dd = d1 * d2;
						} else if (m.equals("div")) {
							dd = d1 / d2;
						}
						w = 1;
					} else {
						double d3 = Double.parseDouble(b[k + 1]);
						String m = list.get(k).get("M").toString();
						if (m.equals("mul")) {
							dd = dd * d3;
						} else if (m.equals("div")) {
							dd = dd / d3;
						}
					}
					/*
					 * Toast.makeText(CalcolatorActivity.this, "bbbbbbbbs",
					 * Toast.LENGTH_LONG).show();
					 */
				}
			}

			if (x == 0) {
				d = dd;
				x = 1;
			} else {
				String n = list2.get(i - 1).get("P").toString();
				if (n.equals("add")) {
					d = d + dd;
				} else if (n.equals("sub")) {
					d = d - dd;
				}
			}
		}
		/*
		 * Toast.makeText(CalcolatorActivity.this, d + "_最后救国",
		 * Toast.LENGTH_LONG).show();
		 */

		return d;
	}

第二种:

public class ArithHelper {

	// 默认除法运算精度
	private static final int DEF_DIV_SCALE = 16;

	// 这个类不能实例化
	private ArithHelper() {
	}

	/**
	 * 提供精确的加法运算。
	 * 
	 * @param v1
	 *            被加数
	 * @param v2
	 *            加数
	 * @return 两个参数的和
	 */

	public static double add(double v1, double v2) {
		java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
		java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
		return b1.add(b2).doubleValue();
	}

	public static double add(String v1, String v2) {
		java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
		java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
		return b1.add(b2).doubleValue();
	}

	/**
	 * 提供精确的减法运算。
	 * 
	 * @param v1
	 *            被减数
	 * @param v2
	 *            减数
	 * @return 两个参数的差
	 */

	public static double sub(double v1, double v2) {
		java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
		java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
		return b1.subtract(b2).doubleValue();
	}

	public static double sub(String v1, String v2) {
		java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
		java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
		return b1.subtract(b2).doubleValue();
	}

	/**
	 * 提供精确的乘法运算。
	 * 
	 * @param v1
	 *            被乘数
	 * @param v2
	 *            乘数
	 * @return 两个参数的积
	 */

	public static double mul(double v1, double v2) {
		java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
		java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
		return b1.multiply(b2).doubleValue();
	}

	public static double mul(String v1, String v2) {
		java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
		java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
		return b1.multiply(b2).doubleValue();
	}

	/**
	 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
	 * 
	 * @param v1
	 *            被除数
	 * @param v2
	 *            除数
	 * @return 两个参数的商
	 */

	public static double div(double v1, double v2) {
		return div(v1, v2, DEF_DIV_SCALE);
	}

	public static double div(String v1, String v2) {
		java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
		java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
		return b1.divide(b2, DEF_DIV_SCALE, java.math.BigDecimal.ROUND_HALF_UP)
				.doubleValue();
	}

	/**
	 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
	 * 
	 * @param v1
	 *            被除数
	 * @param v2
	 *            除数
	 * @param scale
	 *            表示表示需要精确到小数点以后几位。
	 * @return 两个参数的商
	 */

	public static double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
        }
        java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
        java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
    }

	/**
	 * 提供精确的小数位四舍五入处理。
	 * 
	 * @param v
	 *            需要四舍五入的数字
	 * @param scale
	 *            小数点后保留几位
	 * @return 四舍五入后的结果
	 */

	public static double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
        }
        java.math.BigDecimal b = new java.math.BigDecimal(Double.toString(v));
        java.math.BigDecimal one = new java.math.BigDecimal(1);
        return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
    }

	public static double round(String v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
        }
        java.math.BigDecimal b = new java.math.BigDecimal(v);
        java.math.BigDecimal one = new java.math.BigDecimal(1);
        return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}

package com.example.democalculatortest;

import java.util.Collections;
import java.util.Stack;

/**
 * ClassName   :XXXXXXXXXX
 * Comments    :XXXXXXXXXX
 *
 */
public class Calculator {
    private Stack<String> postfixStack  = new Stack<String>();//后缀式栈
    private Stack<Character> opStack  = new Stack<Character>();//运算符栈
    private int [] operatPriority  = new int[] {0,3,2,1,-1,1,0,2};//运用运算符ASCII码-40做索引的运算符优先级
//    public static void main(String[] args) {
//        System.out.println(5+12*(3+5)/7.0);
//        Calculator cal  = new Calculator();
//        String s = 5+12*(3+5)/7;
//        double result  = cal.calculate(s);
//        System.out.println(result);
//    }

    /**
     * 按照给定的表达式计算
     * @param expression 要计算的表达式例如:5+12*(3+5)/7
     * @return
     */
    public double calculate(String expression) {
        Stack<String> resultStack  = new Stack<String>();
        prepare(expression);
        Collections.reverse(postfixStack);//将后缀式栈反转
        String firstValue  ,secondValue,currentValue;//参与计算的第一个值,第二个值和算术运算符
        while(!postfixStack.isEmpty()) {
            currentValue  = postfixStack.pop();
            if(!isOperator(currentValue.charAt(0))) {//如果不是运算符则存入操作数栈中
                resultStack.push(currentValue);
            } else {//如果是运算符则从操作数栈中取两个值和该数值一起参与运算
                 secondValue  = resultStack.pop();
                 firstValue  = resultStack.pop();
                 String tempResult  = calculate(firstValue, secondValue, currentValue.charAt(0));
                 resultStack.push(tempResult);
            }
        }
        return Double.valueOf(resultStack.pop());
    }
    
    /**
     * 数据准备阶段将表达式转换成为后缀式栈
     * @param expression
     */
    private void prepare(String expression) {
        opStack.push(',');//运算符放入栈底元素逗号,此符号优先级最低
        char[] arr  = expression.toCharArray();
        int currentIndex  = 0;//当前字符的位置
        int count = 0;//上次算术运算符到本次算术运算符的字符的长度便于或者之间的数值
        char currentOp  ,peekOp;//当前操作符和栈顶操作符
        for(int i=0;i<arr.length;i++) {
            currentOp = arr[i];
            if(isOperator(currentOp)) {//如果当前字符是运算符
                if(count > 0) {
                    postfixStack.push(new String(arr,currentIndex,count));//取两个运算符之间的数字
                }
                peekOp = opStack.peek();
                if(currentOp == ')') {//遇到反括号则将运算符栈中的元素移除到后缀式栈中直到遇到左括号
                    while(opStack.peek() != '(') {
                        postfixStack.push(String.valueOf(opStack.pop()));
                    }
                    opStack.pop();
                } else {
                    while(currentOp != '(' && peekOp != ',' && compare(currentOp,peekOp) ) {
                        postfixStack.push(String.valueOf(opStack.pop()));
                        peekOp = opStack.peek();
                    }
                    opStack.push(currentOp);
                }
                count = 0;
                currentIndex = i+1;
            } else {
                count++;
            }
        }
        if(count > 1 || (count == 1 && !isOperator(arr[currentIndex]))) {//最后一个字符不是括号或者其他运算符的则加入后缀式栈中
            postfixStack.push(new String(arr,currentIndex,count));
        } 
        
        while(opStack.peek() != ',') {
            postfixStack.push(String.valueOf( opStack.pop()));//将操作符栈中的剩余的元素添加到后缀式栈中
        }
    }
    
    /**
     * 判断是否为算术符号
     * @param c
     * @return
     */
    private boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' ||c == ')';
    }
    
    /**
     * 利用ASCII码-40做下标去算术符号优先级
     * @param cur
     * @param peek
     * @return
     */
    public  boolean compare(char cur,char peek) {// 如果是peek优先级高于cur,返回true,默认都是peek优先级要低
        boolean result  = false;
        if(operatPriority[(peek)-40] >= operatPriority[(cur) - 40]) {
           result = true;
        }
        return result;
    }
    
    /**
     * 按照给定的算术运算符做计算
     * @param firstValue
     * @param secondValue
     * @param currentOp
     * @return
     */
    private String calculate(String firstValue,String secondValue,char currentOp) {
        String result  =" " ;
        switch(currentOp) {
            case '+':
                result = String.valueOf(ArithHelper.add(firstValue, secondValue));
                break;
            case '-':
                result = String.valueOf(ArithHelper.sub(firstValue, secondValue));
                break;
            case '*':
                result = String.valueOf(ArithHelper.mul(firstValue, secondValue));
                break;
            case '/':
                result = String.valueOf(ArithHelper.div(firstValue, secondValue));
                break;
        }
        return result;
    }
}

【上篇】
【下篇】

抱歉!评论已关闭.