【问题标题】:Is it possible to rewrite this function tail-recursively?是否可以递归地重写这个函数?
【发布时间】:2020-12-18 17:42:51
【问题描述】:

我有递归编写的订单匹配功能,我想知道是否可以将此功能变成尾递归?以及如何。

或者有没有更好的方法来提高性能?谢谢

object CollectiveMatch extends App {


  def findSubSet(orders: List[Order], goal: (Double, Double)): List[List[Order]] = {

    var collector: List[List[Order]] = List.empty
    if (orders.isEmpty) return List.empty

    def findMatches(orders: List[Order], index: Int, current: (Double, Double), goal: (Double, Double), result: List[Order]) {
      if (orders.length < index) return
      for (i <- index until orders.length) {
        val newCurrent = if ("Buy".equals(orders(i).side)) {
          (current._1 + orders(i).qty, current._2 + orders(i).volume)
        } else {
          (current._1 - orders(i).qty, current._2 - orders(i).volume)
        }
        if (Math.abs(newCurrent._1 - goal._1) <= 0.00001 && Math.abs(newCurrent._2 - goal._2) <= 0.00001) {
          collector = collector :+ (result :+ orders(i))
        } else {
          findMatches(orders, i + 1, newCurrent, goal, result :+ orders(i))
        }
      }
    }

    findMatches(orders, 0, (0.0, 0.0), (0.0, 0.0), List.empty)
    collector
  }


  val orders = List[Order](
    Order("boc", "Buy", 75.5, 30),
    Order("jp", "Buy", 76, 120),
    Order("ocbc", "Buy", 78, 40),
    Order("sxs", "Buy", 76, 20),
    Order("icbc", "Buy", 79.5, 30),
    Order("morgan", "Buy", 80.5, 30),

    Order("eb", "Sell", 75.5, 50),
    Order("gdb", "Sell", 76.5, 50),
    Order("bocc", "Sell", 77, 80),
    Order("abc", "Sell", 80, 60),
  )

  val allSets: List[List[Order]] = findSubSet(orders, (0.0, 0.0))


}

【问题讨论】:

  • 该方法的目的是什么?你想达到什么目的?
  • 你可以做的最重要的提高性能的事情很可能不是在List 上使用随机访问模式(即,如果orders 是@,则不要写orders(i) 987654325@).
  • 还值得注意的是它已经是尾递归的(假设 return 没有搞砸)。

标签: scala tail-recursion


【解决方案1】:

是的。您将需要使用头/尾作为“外部”递归来递归 List[Order],然后递归您每次附加到的 List[List[Order]](取自 orders.tails)的尾部工作列表进入内部递归循环。

【讨论】:

【解决方案2】:

有一些方法可以优化和增强你的代码,如果你将var collector 作为函数参数传递给递归函数,那么你离你想要的更近了一步,而且在函数式编程方面也更好(避免 var s ),并且在函数结束时,如果您到达断点,而不是空的 return,您可以返回 collector 作为结果。我猜这就是你要找的东西。

你也可以去掉return关键字。

【讨论】:

    猜你喜欢
    • 2011-01-07
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 2016-01-14
    • 2021-11-16
    • 1970-01-01
    • 2013-09-10
    • 2018-07-14
    相关资源
    最近更新 更多