所以我有一个像这样的字符串,准备评估:
"getInfo(((((2+2)*(3/4) / ((44))))))"
所以,有一个地方,一个tripple括号是没用的,一个地方,一个双人无用,所以字符串可以这样简单:
"getInfo((2+2)*(3/4) / (44))"
为了对这些无法使用的括号进行排序,你可以用1个括号替换每2个无用的括号,如下所示:
"do((((2+2 - 3)*(2))))" -> "do(((2+2 - 3)*(2)))" -> "do((2+2 - 3)*(2))"
无论是RegExp还是循环使用String.replace方法来执行此操作,以及如何执行?
答案 0 :(得分:2)
这似乎有效:
function simplify(str) {
var i=0;
return (function recur(s, b) {
var c = str.charAt(i++); // Get next char
if(!c || c == ')') return s; // End of string or end of inner part
if(c == '(') {
var s1 = recur('', true), // Get inner part
s2 = recur(''); // Get following part
return s + (!b || s2 ? '('+s1+')' : s1) + s2;
}
return recur(s+c); // Continue to next char
})('');
}
此代码应该是等效的,函数调用次数较少:
function simplify(str) {
var i=0;
return (function recur(b) {
var c, s = '';
while(c = str.charAt(i++)) { // Keep getting chars
if(c == ')') return s; // End of inner part
if(c == '(') {
var s1 = recur(true), // Get inner part
s2 = recur(); // Get following part
return s + (!b || s2 ? '('+s1+')' : s1) + s2;
}
s += c; // Add current char
b = false;
}
return s;
})();
}
摆脱不必要的括号的部分就是这个:
return s + (!b || s2 ? '('+s1+')' : s1) + s2;
基本上,它返回当前字符串,与内部部分(可能是括号)连接,与以下部分连接。
如果以下部分不为空,或者b
是假的(即内部部分尚未立即包裹在括号中),则内部部分用括号括起来。
请注意,上面的代码需要格式良好的表达式。如果没有,
如果)
没有相应的(
simplify("a)b"); // "a"
如果有未公开的)
,则返回的字符串最后会有(
:
simplify("a(b"); // "a(b)"
答案 1 :(得分:1)
我在javascript方面并不擅长,但这似乎是一个有趣的问题,所以我会尝试为你运用逻辑。您可以通过内部工作以编程方式执行此操作,'识别有效的paren对并删除'他们来自字符串。鉴于您的原始示例:
从左到右遍历,直到第一次关闭paren")"。在这里,它是一个从零开始的字符数组中的15。
getInfo(((((2+2)*(3/4) / ((44))))))
0123456789012345
向后走,直到打开paren"("。这里将是11。
getInfo(((((2+2)*(3/4) / ((44))))))
012345678901
如果这两个位置之间的字符串段包含至少一个非空白字符,则这是一个有效的括号对,因此要保留它。你"删除"这个小组从评估然后循环,找到下一个关闭的paren(在这种情况下,在21位)。
getInfo((((#####*(3/4) / ((44))))))
0123456789012345678901
在17岁的时候倒退到下一个上一个打开的paren,并且"删除。"
getInfo((((#####*##### / ((44))))))
012345678901234567
再次(26至29):
getInfo((((#####*##### / (####)))))
012345678901234567890123456789
同样,但这次在位置(30和25)之间没有非空格字符,所以我们记录这两个位置以便删除。
getInfo((((#####*##### / X####X))))
0123456789012345678901234567890
重复(31到20),一个有效的部分,因为除法和乘法符号:
getInfo(((############ / X####X#)))
012345678901234567890123456789012
再次(32和9),但这次是另一个无效的组,所以标记这些位置:
getInfo((X###############X####X#X))
012345678901234567890123456789012
再次(33和8):
getInfo(XX###############X####X#XX)
0123456789012345678901234567890123
最后(34到7):
getInfoXXX###############X####X#XXX
01234567890123456789012345678901234
不再有剩余的关闭,所以现在我们将标记为删除的字符位置数组删除,并删除这些字符。在示例字符串中,那是30,25,32,9,33,8,34和7.你可能必须从最高的角色位置开始向后工作,否则你&# 39; d影响字符串中其余字符的位置。所以,像(伪代码,自然):
removalArray.sort(ascending)
for (int x=removalArray.length; x>0; x--) {
myString.removeCharacter(removalArray(x))
}
这样做给了我们:
getInfo((2+2)*(3/4) / (44))
很抱歉,回复很久。祝你好运!