我正在编写一个计算器来学习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和数据结构非常陌生,并且不确定:


如何在我的Calc类中实现Shunting Yard算法。
如何开始处理算法提供的后缀。


对于这两个问题的任何建议或示例,或您看到的其他问题,将不胜感激。

以下是计算器的原始代码框架,该框架只能处理简单的功能,例如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)
    {
        ...
   }
}


谢谢!

最佳答案

这是调车场算法的示例:

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

完成这项工作后,便很简单:

1)从操作堆栈中取出一名操作员,并根据该操作员

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

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

10-06 11:07