当我看到这个封闭问题的标题时,我认为它看起来像是一个有趣的高尔夫挑战代码。因此,让我这样介绍一下:
挑战:
编写一个程序,表达式或子例程,给定一个用infix表示的算术表达式,例如1 + 2
,以后缀表示即输出相同的表达式1 2 +
。
(注意:类似的挑战在1月初发布。 但是,我确实觉得这两个任务在细节上有很大不同,足以证明这个单独的挑战是正确的。而且,我只在键入下面的所有内容后才注意到另一个线程,我宁愿不只是把它扔掉。)
输入:
输入包括由以下组成的有效缀算术表达式的数目(非负整数表示为一个或多个十进制数字序列),平衡括号来指示分组的子表达式,和四个缀二进制运算符 +
,-
,*
和/
。这些中的任何一个都可以由任意数量的空格字符分隔(并且整个表达式都被包围),应将其忽略。1个
对于那些喜欢形式语法的人,这里有一个简单的类似于BNF的语法,定义了有效的输入。为了简洁起见,语法不包含可选空格,该空格可能出现在任意两个标记之间(数字中的数字除外):
expression := number | subexpression | expression operator expression
subexpression := "(" expression ")"
operator := "+" | "-" | "*" | "/"
number := digit | digit number
digit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
1空格的存在可能会影响解析的唯一情况是它们将两个连续的数字分开。但是,由于没有被运算符分隔的两个数字不会出现在有效的中缀表达式中,因此这种情况永远不会出现在有效的输入中。
输出:
输出应该是与输入等效的后缀表达式。输出表达式应仅由数字和运算符组成,每对相邻标记之间必须有一个空格字符,如以下语法(确实包含空格)2所示:
expression := number | expression sp expression sp operator
operator := "+" | "-" | "*" | "/"
number := digit | digit number
digit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
sp := " "
2再次为简单起见,number
即使下面的规则在输出中禁止使用前导零,该语法中的乘积也接受前导零。
运算符优先级:
在没有括号的情况下,适用以下优先级规则:
- 运算符
*
和/
具有比+
和高的优先级-
。 - 运算符
*
和/
彼此具有相同的优先级。 - 运算符
+
和-
彼此具有相同的优先级。 - 所有运算符都是左关联的。
例如,以下两个表达式是等效的:
1 + 2 / 3 * 4 - 5 + 6 * 7
((1 + ((2 / 3) * 4)) - 5) + (6 * 7)
并且它们都应产生以下输出:
1 2 3 / 4 * + 5 - 6 7 * +
(这些都是一样的优先规则在C语言中来源于它大多数语言。他们可能像你教小学的规则,可能除了相对优先级*
和/
)。
杂项规则:
如果给定的解决方案是表达式或子例程,则应提供输入,并将输出作为单个字符串返回。如果解决方案是一个完整的程序,则应从标准输入中读取包含infix表达式的行,并将包含后缀版本的行打印至标准输出。
输入中的数字可能包含前导零。输出中的数字不得带有前导零(数字0除外,该数字应输出为
0
)。不应以任何方式评估或优化表达式。特别是,您不应假定运算符必须满足任何关联,可交换或其他代数恒等式。也就是说,您不应该假设例如
1 + 2
equals2 + 1
或1 + (2 + 3)
equals(1 + 2) + 3
。您可以假设输入中的数字不超过2 31 − 1 = 2147483647。
这些规则旨在确保正确的输出由输入唯一定义。
例子:
这是一些有效的输入表达式和相应的输出,形式"input" -> "output"
如下:
"1" -> "1"
"1 + 2" -> "1 2 +"
" 001 + 02 " -> "1 2 +"
"(((((1))) + (2)))" -> "1 2 +"
"1+2" -> "1 2 +"
"1 + 2 + 3" -> "1 2 + 3 +"
"1 + (2 + 3)" -> "1 2 3 + +"
"1 + 2 * 3" -> "1 2 3 * +"
"1 / 2 * 3" -> "1 2 / 3 *"
"0102 + 0000" -> "102 0 +"
"0-1+(2-3)*4-5*(6-(7+8)/9+10)" -> "0 1 - 2 3 - 4 * + 5 6 7 8 + 9 / - 10 + * -"
(至少,我希望所有这些都是正确的;我是手动进行转换的,所以错误可能会逐渐蔓延。)
为了清楚起见,以下输入均无效;它并不会不管你的解决方案,如果不给他们(虽然,当然,如返回的错误信息是不是更好,比如说,消耗的内存无限量):
""
"x"
"1 2"
"1 + + 2"
"-1"
"3.141592653589793"
"10,000,000,001"
"(1 + 2"
"(1 + 2)) * (3 / (4)"
1 2 3 4 + *
?
1 2 3 4 +
意思是“ 1 + 2 + 3 + 4”。