解决方案 »

  1.   

    没太理解楼主的要求,但是如果是需要解析一个数学表达式的字符串的话可以了解一下设计模式的解释器模式。还可以用一些第三方解析工具包,比如Expression4J、jep、jbcParser、Symja、MESP
      

  2.   

    http://blog.csdn.net/whos2002110/article/details/19119449
      

  3.   

    分词很简单:
        private List<String> expressionTokens(String expression) {
            // 1. 在操作符的两边加上空格, 便于分解
            // 2. 用空格分解成list
            return Arrays.asList(expression.replaceAll("([/\\+\\-\\*\\(\\)])", " $1 ").trim().split("\\s+"));
        }
      

  4.   

    分词很简单:
        private List<String> expressionTokens(String expression) {
            // 1. 在操作符的两边加上空格, 便于分解
            // 2. 用空格分解成list
            return Arrays.asList(expression.replaceAll("([/\\+\\-\\*\\(\\)])", " $1 ").trim().split("\\s+"));
        }显然这样不合理1.为什么要加空格  你不能用你的规范去控制调用者
    2.显然不该用正则
        2.1  你正则写的不对   一次分不干净  因为你没考虑负数
        2.2  正则分完了   但是失去了对源字符串校验的功能  这个步骤应该伴随着分词  不该分两步  影响性能
      

  5.   

    这个应该是编译原理里面的内容。以前帮别人写过一个代数运算器,比楼主这个要复杂得多,但是,原理基本是一致的。
    楼主可以看看我的博客 从C语言转换过来的Java版,字符串代数运算器 或许能够得到启发。
      

  6.   

    package com.csb.tree;import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Scanner;
    import java.util.Stack;/**
     * 
     * @author csb
     * 逆波兰表达式(后缀表达式) 是一种由波兰数学家扬·武卡谢维奇1920年引入的数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级。
     */
    public class ReversePolishNotation {
    static HashMap<String,Integer> operatorLevel ;
    static {
    operatorLevel = new HashMap<String,Integer>();
    operatorLevel.put("(", 5);
    operatorLevel.put(")", 5);
    operatorLevel.put("*", 4);
    operatorLevel.put("/", 4);
    operatorLevel.put("+", 3);
    operatorLevel.put("-", 3);
    }
    /**
     * 传入的是一个数组(包含操作符【+,-,*,/】和操作数【整数】)
     * @return int 
     * jdk1.7+
     */
    public static int eval(String[] tokens){
    int result = 0;
    String operators = "+-*/";
    Stack<String> stack = new Stack<String>();
    for(String t : tokens)
    {
    if(!operators.contains(t))
    {
    stack.push(t);
    }else
    {
    int a = Integer.valueOf(stack.pop());
    int b = Integer.valueOf(stack.pop());
    switch(t)
    {
    case "+":
    stack.push(String.valueOf(a+b));
    break;
    case "-":
    stack.push(String.valueOf(b-a));
    break;
    case "*":
    stack.push(String.valueOf(a*b));
    break;
    case "/":
    stack.push(String.valueOf(b/a));
    break;
    }
    }
    }
    result = Integer.valueOf(stack.pop());
    return result;
    }

    /**
     * jdk all
     * @return
     */
    public static int evaluate(String[] tokens)
    {
    int result = 0;
    String operators = "+-*/";
    Stack<String> stack = new Stack<String>();
    for(String t : tokens)
    {
    if(!operators.contains(t))
    {
    stack.push(t);
    }else
    {
    int a = Integer.valueOf(stack.pop());
    int b = Integer.valueOf(stack.pop());
    int index = operators.indexOf(t);
    switch(index)
    {
    case 0:
    stack.push(String.valueOf(a+b));
    break;
    case 1:
    stack.push(String.valueOf(b-a));
    break;
    case 2:
    stack.push(String.valueOf(a*b));
    break;
    case 3:
    stack.push(String.valueOf(b/a));
    break;
    }
    }
    }
    result = Integer.valueOf(stack.pop());
    return result;
    }

    public static String[]  toReversePolishNotation(String input){
    input = input.replaceAll(" ", "").replaceAll("=", "");//去除表达式中的空格和=号
    String[] newArr = input.replaceAll("([/\\+\\-\\*\\/\\(\\)])"," $1 ").trim().replaceAll("  ", " ").split(" "); //先把字符串中的操作符左右加空格,再去除最左和最后的空格,在把由于括号和运算符连在一起造成2个空格换成一个空格,最后根据空格分开
    ArrayList<String> output = new ArrayList<String>();
    Stack<String> stack = new Stack<String>();
    for(String t:newArr)
    {
    switch(t)
    {
    case "(":
    stack.push(t);
    break;
    case "+":
    if(!stack.empty()&&operatorLevel.get(stack.peek())>=operatorLevel.get(t))
    {
    do{
    if(stack.peek().equals("("))
    {
    break;
    }
    output.add(stack.pop());

    }while(!stack.empty()&&operatorLevel.get(stack.peek())>=operatorLevel.get(t));
    stack.push(t);
    }else
    {
    stack.push(t);
    }
    break;
    case "-":
    if(!stack.empty()&&operatorLevel.get(stack.peek())>=operatorLevel.get(t))
    {
    do{
    if(stack.peek().equals("("))
    {
    break;
    }
    output.add(stack.pop());
    }while(!stack.empty()&&operatorLevel.get(stack.peek())>=operatorLevel.get(t));
    stack.push(t);
    }else
    {
    stack.push(t);
    }
    break;
    case "*":
    if(!stack.empty()&&operatorLevel.get(stack.peek())>=operatorLevel.get(t))
    {
    do{
    if(stack.peek().equals("("))
    {
    break;
    }
    output.add(stack.pop());
    }while(!stack.empty()&&operatorLevel.get(stack.peek())>=operatorLevel.get(t));
    stack.push(t);
    }else
    {
    stack.push(t);
    }
    break;
    case "/":
    if(!stack.empty()&&operatorLevel.get(stack.peek())>=operatorLevel.get(t))
    {
    do{
    if(stack.peek().equals("("))
    {
    break;
    }
    output.add(stack.pop());
    }while(!stack.empty()&&operatorLevel.get(stack.peek())>=operatorLevel.get(t));
    stack.push(t);
    }else
    {
    stack.push(t);
    }
    break;
    case ")":
    while(!stack.isEmpty()&&!stack.peek().equals("("))
    {
    output.add(stack.pop());
    }
    stack.pop();
    break;
    default:
    output.add(t);
    break;
    }
    System.out.println(t);
    System.out.println("stack="+stack);
    System.out.println("output="+output);
    }
    while(!stack.isEmpty())
    {
    output.add(stack.pop());
    }
    String[] result = new String[output.size()];
    output.toArray(result);
    return result;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub

    System.out.println("请输入算式");
    Scanner s = new Scanner(System.in); //输入表达式
    String input = s.nextLine();
    String[] tookes = toReversePolishNotation(input);
    System.out.println(String.valueOf(evaluate(tookes)));
    }}