【问题标题】:Tail-recursive implementation of in-shufflein-shuffle 的尾递归实现
【发布时间】:2020-02-12 20:20:56
【问题描述】:

我对@9​​87654321@ 使用递归,将列表传递给方法,但与递归基本情况混淆。由于 Scala 不允许您修改传递的参数,因此我无法为传递的列表分配新值。 这是我的代码:

def shuffle(list1: List[Any], list2: List[Any]): List[Any] = {
    list1.zipAll(list2, "", "")
      .flatMap(_.productIterator.toList)
      .filter(_ != "")
  }
def splitLists(list: List[Any], n: Int) = {
    if (n > list.length) {
      throw new Exception("N is greater than length of list")
    }
    else if (n == list.length) {
      List(list, List())
    }
    else {
      List(list.slice(0, n),
        list.slice(n, list.length))
    }
  }

以下方法处于无限循环中。我知道问题出在我初始化 list 变量的第一行。

  @annotation.tailrec
  def in_shuffle(list:List[Any], org_list:List[Any]):Any={
    var list:List[Any] = List()
    if (list.equals(org_list)) return true
    if (list.length<1) {
      list=org_list
    }
    val div_list = splitLists(list, list.length/2)
    list = shuffle(div_list(0), div_list(1))
    in_shuffle(list, org_list)
  }

In-Shuffle 使用以下代码被调用。

println(in_shuffle(List(), (1 to 4).toList))
任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 传递的数组将是:[1,2,3,4] Step 1: [1,3,2,4] --&gt; Divide equally and then perform Shuffling Step 2: [1,2,3,4] --&gt; Divide equally and then perform Shuffling 检查其原始列表是否返回 true。
  • 我认为你想要实现什么以及问题是什么并不是很清楚。 “对基本情况感到困惑”......怎么办?在哪里?什么让你困惑?
  • 请使用泛型而不是 Any
  • 请指定示例输入和输出。我错过了一些东西。它将帮助我们抓住意图并简化实施。

标签: scala recursion shuffle tail-recursion


【解决方案1】:

您的代码几乎没有问题。我们尽量避免 Any 所以而不是

def shuffle(list1: List[Any], list2: List[Any]): List[Any]

我们使用类型参数T

def shuffle(t: (List[T], List[T])): List[T]

接下来我们flatten a list of tuples就这样

def shuffle(t: (List[T], List[T])): List[T] =
  t._2 zip t._1 flatMap { case (a, b) => List(a, b) }

接下来我们使用开箱即用的splitAt,而不是滚动我们自己的splitLists

val (left, right) = list.splitAt(list.size/2)

最后我们避免使用return。综上所述,我们有

def in_shuffle[T](original: List[T]) = {
  require(original.size % 2 == 0, "In shuffle requires even number of elements")

  def shuffle(t: (List[T], List[T])): List[T] =
    t._2 zip t._1 flatMap { case (a, b) => List(a, b) }

  def midpoint(l: List[T]): Int = l.size / 2

  @annotation.tailrec def loop(current: List[T]): Boolean = {
    if (original == current) true
    else loop(shuffle(current.splitAt(midpoint(current))))
  }

  loop(shuffle(original.splitAt(midpoint(original))))
}

in_shuffle((1 to 52).toList)   // res0: Boolean = true

注意in shuffle 要求元素数量是偶数。

【讨论】:

  • 一个问题@mario。如果我们需要切换到 out-shuffle 怎么办??????
  • @petereg157 只需将t._2 zip t._1 切换到t._1 zip t._2
猜你喜欢
  • 2019-04-07
  • 2019-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
  • 1970-01-01
相关资源
最近更新 更多