【问题标题】:How to reduce with a non-associative function via adjacent pairs如何通过相邻对减少非关联函数
【发布时间】:2018-07-06 20:58:07
【问题描述】:

如何通过相邻对减少集合?

例如,令 + 为非关联运算符:

(1, 2, 3, 4, 5, 6) => ((1+2) + (3+4)) + (5+6)

(a, b, c, d, e, f, g, h) => ((a+b) + (c+d)) + ((e+f) + (g+h))

这个问题类似于this,但是我不认为并行集合适用,因为语义需要关联运算符来确定。我不太关心并行执行,而是关心实际关联以构建平衡的表达式树。

【问题讨论】:

标签: scala


【解决方案1】:

这是一个版本,可以满足您的需求,但对“剩余”元素的处理有些随意(如果当前迭代中的输入数量为奇数,则保留一个元素):

def nonassocPairwiseReduce[A](xs: List[A], op: (A, A) => A): A = {
  xs match {
    case Nil => throw new IllegalArgumentException
    case List(singleElem) => singleElem
    case sthElse => {
      val grouped = sthElse.grouped(2).toList
      val pairwiseOpd = for (g <- grouped) yield {
        g match {
          case List(a, b) => op(a, b)
          case List(x) => x
        }
      }
      nonassocPairwiseReduce(pairwiseOpd, op)
    }
  }
}

例如,如果这是您对Strings 的非关联操作:

def putInParentheses(a: String, b: String) = s"(${a} + ${b})"

然后你的例子

for {
  example <- List(
    ('1' to '6').toList.map(_.toString),
    ('a' to 'h').toList.map(_.toString)
  )
} {
  println(nonassocPairwiseReduce(example, putInParentheses))
}

映射到

(((1 + 2) + (3 + 4)) + (5 + 6))
(((a + b) + (c + d)) + ((e + f) + (g + h)))

知道你为什么要这样做会很有趣。

【讨论】:

  • 这是完美的,谢谢!我想这样做是因为我使用 Scala 来设计硬件(使用一个名为 Chisel 的库),所以我的非关联函数是创建硬件模块的特定拓扑。
猜你喜欢
  • 1970-01-01
  • 2021-11-04
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 2017-12-20
  • 2021-09-27
  • 1970-01-01
相关资源
最近更新 更多