当前位置:  开发笔记 > 编程语言 > 正文

如何修改我的Shunting-Yard算法以便接受一元运算符?

如何解决《如何修改我的Shunting-Yard算法以便接受一元运算符?》经验,为你挑选了1个好方法。

我一直在努力在JavaScript中实现Shunting-Yard算法.

到目前为止,这是我的工作:

var userInput = prompt("Enter in a mathematical expression:");
var postFix = InfixToPostfix(userInput);
var result = EvaluateExpression(postFix);

document.write("Infix: " + userInput + "
"); document.write("Postfix (RPN): " + postFix + "
"); document.write("Result: " + result + "
"); function EvaluateExpression(expression) { var tokens = expression.split(/([0-9]+|[*+-\/()])/); var evalStack = []; while (tokens.length != 0) { var currentToken = tokens.shift(); if (isNumber(currentToken)) { evalStack.push(currentToken); } else if (isOperator(currentToken)) { var operand1 = evalStack.pop(); var operand2 = evalStack.pop(); var result = PerformOperation(parseInt(operand1), parseInt(operand2), currentToken); evalStack.push(result); } } return evalStack.pop(); } function PerformOperation(operand1, operand2, operator) { switch(operator) { case '+': return operand1 + operand2; case '-': return operand1 - operand2; case '*': return operand1 * operand2; case '/': return operand1 / operand2; default: return; } } function InfixToPostfix(expression) { var tokens = expression.split(/([0-9]+|[*+-\/()])/); var outputQueue = []; var operatorStack = []; while (tokens.length != 0) { var currentToken = tokens.shift(); if (isNumber(currentToken)) { outputQueue.push(currentToken); } else if (isOperator(currentToken)) { while ((getAssociativity(currentToken) == 'left' && getPrecedence(currentToken) <= getPrecedence(operatorStack[operatorStack.length-1])) || (getAssociativity(currentToken) == 'right' && getPrecedence(currentToken) < getPrecedence(operatorStack[operatorStack.length-1]))) { outputQueue.push(operatorStack.pop()) } operatorStack.push(currentToken); } else if (currentToken == '(') { operatorStack.push(currentToken); } else if (currentToken == ')') { while (operatorStack[operatorStack.length-1] != '(') { if (operatorStack.length == 0) throw("Parenthesis balancing error! Shame on you!"); outputQueue.push(operatorStack.pop()); } operatorStack.pop(); } } while (operatorStack.length != 0) { if (!operatorStack[operatorStack.length-1].match(/([()])/)) outputQueue.push(operatorStack.pop()); else throw("Parenthesis balancing error! Shame on you!"); } return outputQueue.join(" "); } function isOperator(token) { if (!token.match(/([*+-\/])/)) return false; else return true; } function isNumber(token) { if (!token.match(/([0-9]+)/)) return false; else return true; } function getPrecedence(token) { switch (token) { case '^': return 9; case '*': case '/': case '%': return 8; case '+': case '-': return 6; default: return -1; } } function getAssociativity(token) { switch(token) { case '+': case '-': case '*': case '/': return 'left'; case '^': return 'right'; } }

它到目前为止工作正常.如果我给它:

((5 + 3)*8)

它将输出:

中缀:((5 + 3)*8)
后缀(RPN):5 3 + 8*
结果:64

但是,我正在努力实现一元运算符,所以我可以做类似的事情:

((-5 + 3)*8)

实现一元运算符(否定等)的最佳方法是什么?另外,有没有人有任何处理浮点数的建议?

最后一件事,如果有人看到我在JavaScript中做任何奇怪的事情让我知道.这是我的第一个JavaScript程序,我还不习惯它.



1> Austin Taylo..:

最简单的方法是进行isNumber匹配/-?[0-9]+(\.[0-9]+)?/,处理浮点数和负数.

如果你真的需要处理一元运算符(比如,对括号表达式进行一元否定),那么你必须:

使它们成为正确的联想.

使它们优先于任何中缀运算符.

单独处理它们EvaluateExpression(创建一个单独的PerformUnaryExpression函数,只需要一个操作数).

InfixToPostfix通过跟踪某种状态来区分一元和二元减去.看看在这个Python示例中'-'是如何变成的.'-u'

我写了一个更彻底的解释,处理另一个问题上的一元减号.


该链接已损坏,请参阅http://web.archive.org/web/20130702040830/http://en.literateprograms.org/Shunting_yard_algorithm_(Python)
推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有