可以使用更多功能方法解决此任务吗?

时间:2013-11-05 21:34:03

标签: scala scala-collections polynomial-math

我正在为自己的需要编写简单的多项式相关库。至于现在,我只使用多项式基于GF(2)的多项式,所以它们简单地表示为

case class Polynomial(coeffs: BitSet)

所以我可以写一些像

这样的东西
Polynomial(BitSet(0,1,2))

代表

(x^2 + x + 1)

现在,我对我的乘法功能感到特别自豪:

def *(that: Polynomial): Polynomial = Polynomial {
    coeffs.foldLeft(BitSet.empty) { case (acc, i) => acc ^ that.coeffs.map(i +) }
}

但就目前而言,我用其他多项式模数表示减少的所有努力都没有显示出任何类似的结果。我确实理解除法有点复杂,但我目前有非常非常脏的递归解决方案,我根本不喜欢它。 我现在拥有的是下面的内容(不要忘记我们在GF(2)中)。 (UPD:简化代码使其可以在课外运行)

  def foo(thisSet: BitSet, thatSet: BitSet): BitSet = {
    var ts = thisSet
    while (!ts.isEmpty && ts.max >= thatSet.max) {
      ts = ts ^ thatSet.map(_ - thatSet.max + ts.max)
    }
    ts
  }

它运行正常(虽然到目前为止我还没有编写任何测试),但我希望有一些整洁的东西(最多是尾递归,但最好只使用folds / maps /简化。

1 个答案:

答案 0 :(得分:0)

您总是可以以递归方式编写简单循环

例如你的foo函数:

import scala.annotation.tailrec
def fooRec(thisSet : BitSet, thatSet : BitSet) : BitSet = {
    @tailrec def loop(acc : BitSet) : BitSet = {
        if (!acc.isEmpty && acc.max >= thatSet.max) loop(acc ^ thatSet.map(_ - thatSet.max + acc.max))
        else acc
    }
    loop(thisSet)
}                                         //> fooRec: (thisSet: scala.collection.BitSet, thatSet: scala.collection.BitSet)
                                          //| scala.collection.BitSet

foo(BitSet(1, 2, 0), BitSet(3, 0, 1))           //> res0: scala.collection.BitSet = BitSet(0, 1, 2)
fooRec(BitSet(1, 2, 0), BitSet(3, 0, 1))        //> res1: scala.collection.BitSet = BitSet(0, 1, 2)

您可以看到var ts是内部递归函数loop的参数,而while现在只是if

尾部递归函数和while循环在性能和可读性方面几乎相同,在我看来。你可以选择最适合你的风格。

我个人认为这个版本比while版本更脏。