java – 分流码算法的问题

前端之家收集整理的这篇文章主要介绍了java – 分流码算法的问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经在 java中成功实现了一个分流码算法.算法本身很简单但是我在使用tokenizer时遇到了麻烦.目前,该算法适用于我想要的一切,不包括一件事.如何区分减法( – )和负数( – )之间的区别

如4-3是减法
但是-4 3是否定的

我现在知道如何找出什么时候它应该是负数,什么时候它应该是负数,但算法应该放在哪里,因为如果你像功能一样使用它它不会总是起作用的例子

3 4 * 2 / – (1 – 5)^ 2 ^ 3

当1-5变为-4时,它将变为4,然后变为平方和立方

就像
3 4 * 2 / cos(1 – 5)^ 2 ^ 3,你将在平方和立方之前取余弦

但是在真正的数学中你不会用 – 因为你真正说的是
3 4 * 2 / – ((1 – 5)^ 2 ^ 3)以获得正确的值

解决方法

听起来你正在做一个lex-then-parse风格的解析器,你需要在lexer中使用一个简单的状态机来获得单一和二进制减号的单独标记. (在PEG解析器中,这不是你需要担心的事情.)

JavaCC中,您将具有DEFAULT状态,您可以将 – 字符视为UNARY_MINUS.当您对主表达式的结尾(基于您给出的示例的结束表达式或整数)进行标记时,您将切换到INFIX状态,其中 – 将被视为INFIX_MINUS.一旦遇到任何中缀运算符,您将返回DEFAULT状态.

如果你自己滚动,它可能比这更简单.看看这个Python code是一个聪明的方法.基本上,当您遇到 – 时,您只需检查以前的令牌是否为中缀运算符.该示例使用字符串“-u”来表示一元减号令牌,这样便于非正式标记化.我能说的最好,Python示例确实无法处理a – 遵循开放式paren,或者来自输入开头的情况.那些也应该被认为是一元的.

为了在分流码算法本身中正确处理一元减号,它需要具有比任何中缀运算符更高的优先级,并且它需要标记为右关联. (确保你处理右关联性.你可能已将它遗漏了,因为其余的操作符都是左关联的.)这在Python代码中已经足够清楚了(尽管我会使用某种结构而不是两个单独的映射) .

当需要进行评估时,您需要稍微改变一元运算符,因为您只需要从堆栈中弹出一个数字,而不是两个.根据您的实现情况,可能更容易通过列表并用[-1,“*”]替换每个出现的“-u”.

如果您可以完全关注Python,那么您应该能够在我链接的示例中看到我正在谈论的所有内容.我发现代码比其他人提到的C版本更容易阅读.另外,如果你很好奇,我在前一段时间做了一些关于使用shunting-yard in Ruby文章,但是我将一元操作符作为一个单独的非终结符号处理,所以它们没有显示出来.

猜你在找的Java相关文章