2

私はScalaを初めて使用し、末尾再帰について学び始めました。関数型プログラミングの末尾再帰は、命令型プログラミングの反復 (for ループ) のカウンター部分であることを学びました。

リスト要素を合計する単純な C++ ループ:

uint32_t sum = 0;
for (size_t i = 0; i < list.length(); ++i) {
    sum += list[i];
}

Scala の再帰的等価物:

def listSum(list: List[Int]): Int = {
  def listSumHelper(list: List[Int], sum: Int): Int = {
    if (list.isEmpty) sum
    else listSumHelper(list.tail, sum + list.head)
  }
  listSumHelper(list, 0)
}  

質問: ネストされた for ループに相当するスカラ再帰は何ですか?

uint32_t sum = 0;
for (size_t i = 0; i < list.width(); ++i) {
    for (size_t j = j < list.height(); ++j) {
        sum += list[i][j];
    }
}
4

2 に答える 2

2

ネストされたリスト ( List[List[Int]])で機能する同一のリスト再帰メソッドを単純に記述します。

def listSum2(list: List[List[Int]]): Int = {
  @tailrec def listSumHelper2(list: List[List[Int]], sum: Int): Int = {
    if (list.isEmpty) sum
    else listSumHelper2(list.tail, sum + listSum(list.head))
  }
  listSumHelper2(list, 0)
}
于 2013-03-28T15:49:14.833 に答える
2

完全な末尾再帰が必要な場合は、すべてのループを引数に移動する必要があります。だから(ここではヘルパーなしで、簡潔にするために):

def sumsum(xss: List[List[Int]], current: List[Int] = Nil, sum: Int = 0): Int = {
  current match {
    case x :: more => sumsum(xss, more, sum+x)
    case Nil => xss match {
      case xs :: more => sumsum(more, xs, sum)
      case Nil => sum
    }
  }
}

ただし、ループが非常に短い場合を除き、おそらく必要ありません。反復ごとに、1 つの末尾再帰関数が別の関数を呼び出すだけです。

于 2013-03-28T16:45:46.417 に答える