用于计算括号平衡的分布式算法

时间:2010-12-21 15:23:42

标签: algorithm distributed

这是interview question:“如何构建分布式算法来计算括号的平衡?”

通常他的平衡算法从左到右扫描一个字符串形式,并使用一个堆栈来确保开括号的数量始终> =近括号的数量,最后是开括号的数量==近括号的数量

你会如何分发它?

3 个答案:

答案 0 :(得分:9)

您可以将字符串分成块并单独处理,假设您可以并行读取并发送到其他计算机。每个字符串需要两个数字。

  1. 相对于字符串开头的最小嵌套深度。

  2. 整个字符串中嵌套深度的总收益或损失。

  3. 使用这些值,您可以计算多个块的串联值,如下所示:

    minNest = 0
    totGain = 0
    for p in chunkResults
      minNest = min(minNest, totGain + p.minNest)
      totGain += p.totGain
    return new ChunkResult(minNest, totGain)
    

    如果totGainminNest的最终值为零,则会匹配括号。

答案 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为较小者。