我正在编写一个计算器来学习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)直到完成。