【发布时间】:2012-10-23 15:47:51
【问题描述】:
问题:
从字符串中删除多余的括号。
例如
((a+b))*c => (a+b)*c
(a+b)+c => (a+b)+c
((a+b)/(c+d)) => ((a+b)/(c+d))
(a+(((b-c)))*d) => (a+(b-c)*d) and so on.
我想出了以下解决方案:
方法:我扫描字符串并记住(使用映射)左括号的索引以及它是否是额外的(默认情况下是额外的)。如果我找到一个右括号,我会从 map 中检查相应的左括号,如果它是多余的,则将两者都删除。
void removeExtraParentheses(string& S){
map<int, bool> pmap;
for(int i = 0; i < S.size(); i++){
map<int, bool>::iterator it;
if(S.at(i) == '('){
pmap[i] = true;
}
else if(S.at(i) == ')'){
it = pmap.end();
it--;
if(!(*it).second){
pmap.erase(it);
}
else{
S.erase(S.begin() + i);
S.erase(S.begin() + (*it).first);
pmap.erase(it);
i = i - 2;
}
}
else{
if(!pmap.empty()){
it = pmap.end();
it--;
(*it).second= false;
}
}
}
}
时间复杂度:O(n2)
空间:O(n)
我对我的解决方案不太满意,因为我正在使用额外的存储空间并在二次时间内完成。
我们可以在 O(n) 时间和 O(1) 空间内做到这一点吗?如果不是,最好的方法是什么?
【问题讨论】:
-
当你说“额外的括号”时,你只是指有的地方 (( 还是你的意思是数学不需要它们的地方?例如 (a+b)+c 也产生+b+c 因为加法是可交换的。如果不是,只需将“(((”)“((”)替换为“(”,以及“)))”和“))”替换为“)”。跨度>
-
我认为我给出的第二个示例输入消除了您的疑问。我不确定“只需将“(((”“((”)与“(”和“)))”和“))”替换为“)””的字符串即可
-
@FrankThomas 首先,这些例子表明数学没有考虑在内,只有双括号被替换。其次,这将失败。想想它会对
((a + b) + (c + d))做些什么 -
@jasper,我相信它会返回 (a+b) + (c+d)。好点,这些也可以删除。
-
@FrankThomas 你提出了一个有趣的问题。对于浮点类型(可能也适用于有符号整数类型,但在任何常见架构上都不是这种情况),加法 not 关联,
(a + b) + c与a + b + c相同,但在a + (b + c)的情况下,您需要括号。或者他的问题可能没有明确说明:在 Windows 机器上,或者在大多数 Unices 上,在最后一种情况下,您不需要int的括号,但在某些奇异的机器上,您可能需要。
标签: c++ string map expression parentheses