使用Shunting Yard的计算器 - 收到postfix后如何继续

时间:2014-08-02 20:38:15

标签: java shunting-yard

我正在编写一个计算器来学习Java。我最近编写了一个与this非常类似的Shunting Yard算法。我的算法和链接的算法之间的唯一区别是我还包括一个指数运算符。以下是更改:

leftParen(0), rightParen(1), add(2), subtract(3), divide(4), multiply(5), modulus(6), eos(7), exponent(8), operand(9);

并且:

private static final int[] isp = {0, 19, 12, 12, 13, 13, 13, 0, 14};
private static final int[] icp = {20, 19, 12, 12, 13, 13, 13, 0, 14};
private static final char[] operators = {'(', ')', '+', '-', '/', '*', '%', ' ', '^'};

其他一切都是一样的。

但是,我对Java和数据结构很陌生,而且我不确定:

  1. 如何在我的Calc类中实现Shunting Yard算法。
  2. 如何开始处理算法提供的后缀。
  3. 非常感谢您对这两个问题的任何建议或示例,或者您看到的其他问题。

    下面是我的计算器原始代码的框架,它只能处理简单的函数,例如2+2。评论是我开始实施Shunting Yard算法的想法,但我不确定我是否在正确的轨道上。评论将取代它们上方/下方的某些行。我不确定这些代码中有多少仍然可用。

    import java.util.Scanner;
    import java.math.BigDecimal;
    
    public abstract class Calc 
    {
        private static BigDecimal num1, num2;
    
        public static void start()
        {
            System.out.println("Calculator. Type \"exit\" to quit.");
            System.out.print("> ");
    
            Scanner scan = new Scanner(System.in);       
            //ShuntingYard sy = new ShuntingYard();
            //String infix = scan.next();
            String entry = scan.next();
    
            //while (! (infix.equals("exit")))
            while (! (entry.equals("exit")))
            {    
                //String postfix = sy.postfix(infix);
    
                String [] numbers = entry.replaceAll("\\s+", "").split("[\\+\\-\\/\\*\\%\\^]");        
                String operator = entry.replaceAll("(\\s+|\\d+|\\.)", "");
    
                BigDecimal [] operands = new BigDecimal[numbers.length];           
                for (int i = 0; i < numbers.length; i++)
                {
                    operands[i] = new BigDecimal(numbers[i]);
                }
    
                num1 = operands[0];
                num2 = operands[1];
    
                BigDecimal result = new BigDecimal(0);
    
                switch (operator)
                {
                    case "+":
                        result = Calc.add(num1, num2);
                        break;
                    case "-":
                        ...
                    case "*":
                        ...
                    case "/":
                        ...
                    case "^":
                        ...
                    case "%":
                        ...
                    default:
                    System.out.println("Not valid.");
                }
    
                System.out.println(result);
                System.out.print("> ");
                entry = scan.next();
            }
        }
    
        public static BigDecimal add(BigDecimal num1, BigDecimal num2)
        {
            BigDecimal sum = num1.add(num2);
            return sum;
        }
    
        public static BigDecimal subtract(BigDecimal num1, BigDecimal num2)
        {
            ...
        }
    
        public static BigDecimal multiply(BigDecimal num1, BigDecimal num2)
        {
            ...
        }
    
        public static BigDecimal divide(BigDecimal num1, BigDecimal num2)
        {
            ...
        }
    
        public static BigDecimal exponentiate(BigDecimal num1, BigDecimal num2)
        {
            ...
        }
    
        public static BigDecimal modulus(BigDecimal num1, BigDecimal num2)
        {
            ...
       }
    }
    

    谢谢!

1 个答案:

答案 0 :(得分:1)

以下是调车场算法的一个例子:

http://rosettacode.org/wiki/Parsing/Shunting-yard_algorithm#Java

一旦你有了这个工作,它只是:

1)从操作堆栈中取一个操作符,并根据操作符

2)从操作数堆栈中取出一个或两个元素,应用运算符

3)推动结果并返回1)直到完成。