【问题标题】:Distributed algorithm to compute the balance of the parentheses计算括号余额的分布式算法
【发布时间】:2011-05-28 21:35:54
【问题描述】:

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

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

你会如何分发它?

【问题讨论】:

  • 你只需要知道它是否是一个有效的匹配字符串,还是你需要知道每个paren匹配的索引?后者不太直接。 (我的解决方案是前者。)
  • 我想我只需要验证字符串。

标签: algorithm distributed


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 我认为如果 minNest 在循环期间低于零,则括号不匹配。
  • @Keith,是的,我最初混淆了那个测试。
  • 最小嵌套深度是否等于当前子字符串中不匹配右括号的数量?另外,minNest 可以永远 > 0 吗?
  • @DenTheMan,从字符串开头到子字符串开头的不匹配左括号总数中减去该数字。
  • @jonderry :我不是 100% 清楚你的解决方案。你能描述一下完整的算法吗?
【解决方案2】:

我会应用 map-reduce 算法,其中 map 函数将计算字符串的一部分,如果括号是平衡的,则返回一个空字符串,或者返回一个带有最后一个括号的字符串。

然后reduce函数会通过map函数连接两个返回字符串的结果,并再次计算它,返回与map相同的结果。在所有计算结束时,您将获得一个空字符串或一个包含不平衡括号的字符串。

【讨论】:

  • 这种方法对于看起来像 "(((((((((((())))) 的字符串会遇到性能问题)))))))))))))))))" 或类似的。
【解决方案3】:

我将尝试对@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 n 是 minNestm+ntotGain。要制作真正平衡的琴弦,我们需要m+n == 0 &amp;&amp; n == 0

在并行操作中,我们如何从它的左右推导出节点?对于 totGain,我们只需要将它们相加。在计算节点的 n 时,如果 n(right) 没有贡献,它可以只是 n(left) 或 n(right) + left.totGain 中较小的一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 2015-11-06
    • 2012-03-12
    • 2011-10-05
    • 1970-01-01
    相关资源
    最近更新 更多