我刚刚想出了一个答案:
前提是:
1. the expression has been tokenized
2. no syntax error
3. there are only binary operators
输入:
list of the tokens, for example:
(, (, a, *, b, ), +, c, )
输出:
set of the redundant parentheses pairs (the orders of the pairs are not important),
for example,
0, 8
1, 5
请注意:集合不是唯一的,例如((a+b))*c,我们可以去掉外括号或内括号,但最终表达式是唯一的
数据结构:
a stack, each item records information in each parenthese pair
the struct is:
left_pa: records the position of the left parenthese
min_op: records the operator in the parentheses with minimum priority
left_op: records current operator
算法
1.push one empty item in the stack
2.scan the token list
2.1 if the token is operand, ignore
2.2 if the token is operator, records the operator in the left_op,
if min_op is nil, set the min_op = this operator, if the min_op
is not nil, compare the min_op with this operator, set min_op as
one of the two operators with less priority
2.3 if the token is left parenthese, push one item in the stack,
with left_pa = position of the parenthese
2.4 if the token is right parenthese,
2.4.1 we have the pair of the parentheses(left_pa and the
right parenthese)
2.4.2 pop the item
2.4.3 pre-read next token, if it is an operator, set it
as right operator
2.4.4 compare min_op of the item with left_op and right operator
(if any of them exists), we can easily get to know if the pair
of the parentheses is redundant, and output it(if the min_op
< any of left_op and right operator, the parentheses are necessary,
if min_op = left_op, the parentheses are necessary, otherwise
redundant)
2.4.5 if there is no left_op and no right operator(which also means
min_op = nil) and the stack is not empty, set the min_op of top
item as the min_op of the popped-up item
例子
示例一
((a*b)+c)
扫描到 b 后,我们有堆栈:
index left_pa min_op left_op
0
1 0
2 1 * * <-stack top
现在我们遇到第一个')'(在位置 5),我们弹出项目
left_pa = 1
min_op = *
left_op = *
和预读运算符'+',由于min_op优先级'*'>'+',所以pair(1,5)是多余的,所以输出。
然后扫描直到我们遇到最后一个')',此刻,我们有堆栈
index left_pa min_op left_op
0
1 0 + +
我们弹出这个项目(因为我们在pos 8遇到')'),并且预读next运算符,因为没有运算符并且在索引0处没有left_op,所以输出pair(0, 8)
示例二
a*(b+c)
当我们遇到')'时,栈是这样的:
index left_pa min_op left_op
0 * *
1 2 + +
现在,我们在 index = 1 处弹出 item,比较 min_op '+' 和 left_op '*' 在 index 0 处,我们可以发现 '(',')' 是必要的