我正在努力使调车场算法的实现工作它与数字和运算符配合得很好但当我尝试向输入中添加函数时会出现问题因为当函数参数应该输出到右边时,它会输出到函数的左边。
测试程序
public class FrontTest
{
public static void main(String[] args)
{
String str = "cbrt ( 8 )";
System.out.println(ShuntTest.infixToPostfix(str));
}
}
算法
import java.util.*;
public class ShuntTest
{
public static String infixToPostfix(String infixStr)
{
Stack<String> operators = new Stack<String>();
Queue<String> output = new LinkedList<String>();
String[] tokens = infixStr.split("[\\s]");
StringBuilder postfixStr = new StringBuilder();
int tokensRemaining = tokens.length;
final String PAREN_LEFT = "[\\(]";
final String PAREN_RIGHT = "[\\)]";
final String FUNCTION_ARGSEP = "[\\;]";
for (int i = 0; i < tokens.length; i++)
{
if (isNumber(tokens[i]))
{
output.offer(tokens[i]);
}
else if (isFunction(tokens[i]))
{
operators.push(tokens[i]);
}
else if (tokens[i].matches(FUNCTION_ARGSEP))
{
while (!operators.empty() && operators.peek().matches(PAREN_RIGHT))
{
output.offer(operators.pop());
if (operators.empty() && !operators.peek().matches(PAREN_RIGHT))
{
throw new RuntimeException("Mismatched Parentheses.");
}
}
}
else if (isOperator(tokens[i]))
{
while (!operators.empty() && ((isOperator(operators.peek())
&& ((isLeftAssociative(tokens[i]) == true && ((operatorPrecedence(tokens[i]) <= operatorPrecedence(operators.peek()))
|| ((isLeftAssociative(tokens[i]) == false && ((operatorPrecedence(tokens[i]) < operatorPrecedence(operators.peek())))))))))))
{
output.offer(operators.pop());
}
operators.push(tokens[i]);
}
else if (!operators.empty() && tokens[i].matches(PAREN_LEFT))
{
operators.push(tokens[i]);
}
else if (!operators.empty() && tokens[i].matches(PAREN_RIGHT))
{
while (!operators.empty() && !operators.peek().matches(PAREN_LEFT))
{
output.offer(operators.pop());
}
if (!operators.empty())
{
operators.pop();
}
else if (!operators.empty() && isFunction(operators.peek()))
{
output.offer(operators.pop());
}
else if (operators.empty())
{
throw new RuntimeException("Mismatched Parentheses.");
}
}
tokensRemaining--;
}
if (tokensRemaining == 0)
{
while (!operators.empty())
{
if (operators.peek().matches(PAREN_LEFT)
|| operators.peek().matches(PAREN_RIGHT))
{
throw new RuntimeException("Mismatched Parentheses.");
}
output.offer(operators.pop());
}
}
while (!output.isEmpty())
{
while (output.size() > 1)
{
postfixStr.append(output.poll() + " ");
}
postfixStr.append(output.poll());
}
return postfixStr.toString();
}
public static boolean isNumber(String str)
{
final String NUMBER = "^0?-?\\+?\\d+(\\.\\d+)?$";
return str.matches(NUMBER) ? true : false;
}
public static boolean isOperator(String str)
{
switch (str)
{
case "^":
case "/":
case "*":
case "+":
case "-":
return true;
default:
return false;
}
}
private static boolean isLeftAssociative(String str)
{
switch (str)
{
case "^":
return false;
case "/":
case "*":
case "+":
case "-":
return true;
default:
throw new IllegalArgumentException("Operator unknown: " + str);
}
}
private static int operatorPrecedence(String str)
{
switch (str)
{
case "^":
return 4;
case "/":
case "*":
return 3;
case "+":
case "-":
return 2;
default:
throw new IllegalArgumentException("Operator unknown: " + str);
}
}
public static boolean isFunction(String str)
{
switch (str)
{
case "sin":
case "cos":
case "tan":
case "sqrt":
case "cbrt":
case "root_of":
return true;
default:
return false;
}
}
}
例1:
输入:
cbrt ( 8 )
输出:
8 cbrt
输出应为:
cbrt 8
例2:
输入:
cbrt ( 8 ) + sqrt ( 9 )
输出:
8 9 sqrt + cbrt
输出应为:
cbrt 8 sqrt 9 +
例3:
输入:
5 + 4 - 9 / 2 ^ 6 * cbrt ( 8 )
输出:
5 4 + 9 2 6 ^ / 8 cbrt * -
输出应为:
5 4 + 9 2 6 ^ / cbrt 8 * -
最佳答案
想想看调车场算法将中缀转换为后缀但是:
cbrt ( 8 )
不是中缀表达式。它是一个前缀表达式。
作为后缀表达式,它将如下所示:
8 cbrt
它可能看起来像中缀表达式,留给读者作为练习,但它不是您开始使用的。