这是interview question:“如何构建分布式算法来计算括号的平衡?”
通常他的平衡算法从左到右扫描一个字符串形式,并使用一个堆栈来确保开括号的数量始终> =近括号的数量,最后是开括号的数量==近括号的数量
你会如何分发它?
答案 0 :(得分:9)
您可以将字符串分成块并单独处理,假设您可以并行读取并发送到其他计算机。每个字符串需要两个数字。
相对于字符串开头的最小嵌套深度。
整个字符串中嵌套深度的总收益或损失。
使用这些值,您可以计算多个块的串联值,如下所示:
minNest = 0
totGain = 0
for p in chunkResults
minNest = min(minNest, totGain + p.minNest)
totGain += p.totGain
return new ChunkResult(minNest, totGain)
如果totGain
和minNest
的最终值为零,则会匹配括号。
答案 1 :(得分:2)
我会应用map-reduce算法,其中map函数将计算字符串的一部分,如果括号是平衡的,则返回空字符串,或者保留剩余最后一个括号的字符串。
然后reduce函数将通过map函数连接两个返回字符串的结果并再次计算它返回与map相同的结果。在所有计算结束时,您将获得一个空字符串或包含非平衡括号的字符串。
答案 2 :(得分:1)
我将尝试对@jonderry的答案进行更详细的解释。首先在Scala中进行编码
def parBalance(chars: Array[Char], chunkSize: Int): Boolean = {
require(chunkSize > 0, "chunkSize must be greater than 0")
def traverse(from: Int, until: Int): (Int, Int) = {
var count = 0
var stack = 0
var nest = 0
for (n <- from until until) {
val cur = chars(c)
if (cur == '(') {
count += 1
stack += 1
}
else if (cur == ')') {
count -= 1
if (stack > 0) stack -= 1
else nest -= 1
}
}
(nest, count)
}
def reduce(from: Int, until: Int): (Int, Int) = {
val m = (until + from) / 2
if (until - from <= chunkSize) {
traverse(from, until)
} else {
parallel(reduce(from, m), reduce(m, until)) match {
case ((minNestL, totGainL), (minNestR, totGainR)) => {
((minNestL min (minNestR + totGainL)), (totGainL + totGainR))
}
}
}
}
reduce(0, chars.length) == (0,0)
}
给出一个字符串,如果我们删除平衡的括号,剩下的将是)))(((
的形式,并以 n 表示)
和 m 表示(
的数量,然后m> = 0,n <= 0(为便于计算)。这里的 n 是 minest , m + n 是 totGain 。要制作真正的平衡弦,我们需要m+n == 0 && n == 0
。
在并行操作中,如何从节点的左侧和右侧导出节点的那些?对于totGain,我们只需要将它们加起来即可。在为节点计算 n 时,如果n(right)不起作用,则可以为n(left),或者n(right) + left.totGain
为较小者。