Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

algorithm - Remove redundant parentheses from an arithmetic expression

This is an interview question, for which I did not find any satisfactory answers on stackoverflow or outside. Problem statement:

Given an arithmetic expression, remove redundant parentheses. E.g. ((a*b)+c) should become a*b+c

I can think of an obvious way of converting the infix expression to post fix and converting it back to infix - but is there a better way to do this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A pair of parentheses is necessary if and only if they enclose an unparenthesized expression of the form X % X % ... % X where X are either parenthesized expressions or atoms, and % are binary operators, and if at least one of the operators % has lower precedence than an operator attached directly to the parenthesized expression on either side of it; or if it is the whole expression. So e.g. in

q * (a * b * c * d) + c

the surrounding operators are {+, *} and the lowest precedence operator inside the parentheses is *, so the parentheses are unnecessary. On the other hand, in

q * (a * b + c * d) + c

there is a lower precedence operator + inside the parentheses than the surrounding operator *, so they are necessary. However, in

z * q + (a * b + c * d) + c

the parentheses are not necessary because the outer * is not attached to the parenthesized expression.

Why this is true is that if all the operators inside an expression (X % X % ... % X) have higher priority than a surrounding operator, then the inner operators are anyway calculated out first even if the parentheses are removed.

So, you can check any pair of matching parentheses directly for redundancy by this algorithm:

Let L be operator immediately left of the left parenthesis, or nil
Let R be operator immediately right of the right parenthesis, or nil
If L is nil and R is nil:
  Redundant
Else:
  Scan the unparenthesized operators between the parentheses
  Let X be the lowest priority operator
  If X has lower priority than L or R:
    Not redundant
  Else:
    Redundant

You can iterate this, removing redundant pairs until all remaining pairs are non-redundant.

Example:

((a * b) + c * (e + f))

(Processing pairs from left to right):

((a * b) + c * (e + f))   L = nil R = nil --> Redundant
^                     ^   
 (a * b) + c * (e + f)    L = nil R = nil --> Redundant
 ^     ^                  L = nil R = + X = * --> Redundant
  a * b  + c * (e + f)    L = * R = nil X = + --> Not redundant
               ^     ^

Final result:

a * b + c * (e + f)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...