• 利用栈实现表达式计算


    package algorithm.other;

    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Stack;
    import java.util.Map.Entry;

    /**
    * 表达式计算
    * 支持带括号的+、-、*、/运算
    * @author CEMABENTENG
    *
    */
    public class ExpressionCal
    {
    private Map<Character,String> map= new HashMap<Character,String>();

    private String sorce;

    /**
    * 转成后缀表达式
    * @param sorce
    * @return
    */
    private String convertPostfix(String sorce)
    {
    String desk = "";
    Stack<Character> stack = new Stack<Character>();
    for(int i=0;i<sorce.length();i++)
    {
    char ch = sorce.charAt(i);
    switch(ch)
    {
    case '+':
    case '-':
    desk = getOperator(stack,ch,1,desk);
    break;
    case '*':
    case '/':
    desk = getOperator(stack,ch,2,desk);
    break;
    // case '^':
    // desk = getOperator(stack,ch,3,desk);
    // break;
    case '(':
    stack.push(ch);
    break;
    case ')':
    desk = getParenthesis(stack,ch,desk);
    break;
    default:
    desk = desk + ch;
    }
    }
    while(!stack.isEmpty())
    {
    desk = desk + stack.pop();
    }
    return desk;
    }

    private String getParenthesis(Stack<Character> stack, char ch, String desk)
    {
    while(!stack.isEmpty())
    {
    char top = stack.pop();
    if(top == '(')
    {
    break;
    }else
    {
    desk = desk + top;
    }

    }
    return desk;
    }

    private String getOperator(Stack<Character> stack, char ch, int precIn, String desk)
    {
    while(!stack.isEmpty())
    {
    char top = stack.pop();
    if( top == '(')
    {
    stack.push(top); //(2+或(2*情况 ,优先级在后面,先压入栈(+或(*
    break;
    }
    else
    {
    int precTop;
    if(top == '+' || top == '-')
    {
    precTop = 1;
    }
    else
    {
    precTop = 2;
    }
    if(precTop < precIn)
    {
    stack.push(top); // 2+3*情况,优先级在后面,先压入栈+*
    break;
    }
    else
    {
    desk = desk + top; //2*3+情况 或 2+3+情况,生成23*或23+
    }
    }

    }
    stack.push(ch);
    return desk;
    }

    /**
    * 放入表达式
    * @param sorce
    * @return 变量列表
    */
    public List<String> setExpression(String sorce)
    {

    map.clear();
    List<String> vars = new ArrayList<String>();
    StringBuffer buff = new StringBuffer();
    int varNum = 0;
    for (int i = 0; i<sorce.length();i++)
    {
    char ch = sorce.charAt(i);
    if(ch!='+'&&ch!='-'&&ch!='*'&&ch!='/'&&ch!='('&&ch!=')')
    {
    buff.append(ch);
    }
    else if(buff.length()>0)
    {
    if(!vars.contains(buff.toString()))
    {
    vars.add(buff.toString());
    map.put((char)('a'+varNum), buff.toString());
    varNum++;
    }
    buff.setLength(0);
    }
    }
    if(buff.length()>0)
    {
    if(!vars.contains(buff.toString()))
    {
    vars.add(buff.toString());
    map.put((char)('a'+varNum), buff.toString());
    }
    }

    for (Entry<Character, String> entry : map.entrySet())
    {
    sorce = sorce.replaceAll(entry.getValue(), entry.getKey()+"");
    }
    this.sorce = sorce;
    // System.out.println(sorce);
    // System.out.println(map);
    return vars;
    }

    /**
    * 表达式计算
    * @param feemap 变量--数值映射
    * @param scale 保留位数
    * @return 计算结果
    */
    public String calculate(Map<String, BigDecimal> feemap,int scale)
    {
    String tempResult = convertPostfix(sorce);
    String result = calculatePostfix(tempResult,feemap,scale);
    return result;
    }

    /**
    * 计算后缀表达式
    * @param tempResult
    * @return
    */
    private String calculatePostfix(String tempResult,Map<String, BigDecimal> feemap,int scale)
    {
    Stack<BigDecimal> stack = new Stack<BigDecimal>();
    BigDecimal temp;
    for (int i=0;i<tempResult.length();i++)
    {
    char ch = tempResult.charAt(i);
    if(ch>='a'&& ch<='z')
    {
    stack.push(feemap.get(map.get(ch)));
    }
    else
    {
    BigDecimal num2 = stack.pop();
    BigDecimal num1 = stack.pop();
    switch(ch)
    {
    case '+':
    temp = num1.add(num2);
    break;
    case '-':
    temp = num1.subtract(num2);
    break;
    case '*':
    temp = num1.multiply(num2);
    break;
    case '/':
    temp = num1.divide(num2, 6, BigDecimal.ROUND_HALF_UP);
    break;
    // case '^':
    // temp = num1.pow(num2.intValue());
    // break;
    default:
    temp = new BigDecimal(0);
    }
    stack.push(temp);
    }
    }
    if(scale==0)
    {
    return stack.pop().intValue()+"";
    }
    else
    {
    return stack.pop().setScale(scale).toString();
    }
    }

    public static void main(String[] args)
    {
    ExpressionCal ec = new ExpressionCal();
    List<String> list = ec.setExpression("(审定.静态投资-送审.静态投资)/(审定.动态投资-送审.动态投资)");
    System.out.println(list);
    Map<String, BigDecimal> feemap = new HashMap<String, BigDecimal>();
    feemap.put("审定.静态投资", new BigDecimal(801.82));
    feemap.put("送审.静态投资", new BigDecimal(400.42));
    feemap.put("审定.动态投资", new BigDecimal(202));
    feemap.put("送审.动态投资", new BigDecimal(200));
    System.out.println("计算结果:"+ec.calculate(feemap,1));
    }
    }

  • 相关阅读:
    PTA L1-002 打印沙漏 (20分)
    音乐研究
    LeetCode 155. 最小栈
    LeetCode 13. 罗马数字转整数
    LeetCode 69. x 的平方根
    LeetCode 572. 另一个树的子树
    errno错误号含义
    僵尸进程和孤儿进程
    TCP和UDP相关概念
    图相关算法
  • 原文地址:https://www.cnblogs.com/uip001/p/6872936.html
Copyright © 2020-2023  润新知