中缀表达式转后缀表达式的算法,需要考虑一元运算符。

9

算法的输入会是像这样的一个表达式:

a+(-b)
a*-b+c
即任何标准C编译器支持的表达式。 现在,我已经将输入格式化为令牌流,这些令牌包含信息,无论是操作符还是操作数。算法应该接受此输入并给出一个后缀表达式,以便我可以进行评估。 如果我使用标准转换算法,我无法区分一元和二元操作符。例如a*(-b)会给我ab-*,这会导致错误的计算。

4
问题在哪里? - kotlomoy
它在输出中使用另一个符号(例如“_”)作为一元运算符“-”的符号。 - BLUEPIXY
问题是:建议修改标准算法或提出新的算法以对我的问题进行排序。 - Aditya
@user2512249,就像@BLUEPIXY建议的那样,只需使用不同的符号表示一元“-”。 - kotlomoy
3个回答

17
如果运算符是表达式中的第一个元素、或者在另一个运算符之后出现、或者在左括号之后出现,那么它就是一个一元运算符。 你必须在输出字符串中使用其他符号表示一元运算符,因为否则在后缀表达式中无法区分二元和一元变量。

如果有几个连续的运算符怎么办?那个规则还适用吗?例如,5+-2是可以的,但5+-+-2呢? - hfossli
2
@htossli 是的,它确实很重要。 - n. m.

3
在您的输入中,如果有两个连续的操作符,则第二个操作符将作为一元操作符。如果有更多的连续操作符,则除第一个外的所有操作符都将为一元操作符。
将所有一元的-操作符转换为操作数-1和操作符*,并删除所有一元的+操作符。
如果第一个元素是操作符,则它是一元操作符。
括号是一种特殊情况,但您可以进行第一次忽略括号的处理。在下面的示例中,-*连续。
4*(-(5))

这样,您的令牌将变成:

4
*
(
-1
*
(
5
)
)

我看到你最终更喜欢另一个答案,确实你需要在一元运算符的输出中使用特殊符号。最终,你将 a*(-b) 转换后的字符串是什么样子的?你坚持使用 C 符号还是也接受像 4(5-2) 这样只隐含 * 符号的表达式? - Antonio
我已经定义了一个包含以下成员的类:int操作码,string操作数。我首先将输入字符串转换为这个类的数组,所以在扫描时我检查它是一元运算符还是二元运算符,并相应地分配我的操作码。然后我将其转换为后缀表达式,在评估时只需要if-else条件处理一下一元运算符(由于我已经知道哪些是一元运算符,因为我已经给它们分配了一组特定的操作码)。 - Aditya

1
你可以将-6转换为06-以完全消除一元运算符。我喜欢这种方法,因为它更正交,你不需要在处理时考虑特殊情况。
另一种方法是使用相同符号的一元和二元版本的运算符,例如-仍然是二元减号,~变成否定符号。

但是我们必须针对不同的运算符使用不同的方法。我们如何处理ln(x)? - Ashish Duklan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接