你如何在 Scala 中记忆案例?
How do you memoization with cases in Scala?
将这段使用记忆的代码转换为正确的 Scala 使用案例和函数式编程的最佳方法是什么?
def uniquePathsMemoization(n:Int, m:Int, row:Int, col:Int, seen:Array[Array[Int]]):Int = {
if (row == m && col == n) 1
if (row > m || col > n) 0
if (seen(row+1)(col) == -1) seen(row+1)(col) = uniquePathsMemoization(n, m, row + 1, col, seen)
if (seen(row)(col + 1) == -1 ) seen(row)(col) = uniquePathsMemoization(n,m, row, col + 1, seen)
seen(row+1)(col) + seen(row)(col + 1)
}
这是使用 match
和 case
的代码修改版本
def uniquePathsMemoization(n:Int, m:Int, row:Int, col:Int, seen:Array[Array[Int]]):Int = (row,col) match{
case (row,col) if row == m && col == n =>
1
case (row,col) if row > m || col > n =>
0
case (row,col) =>
if (seen(row+1)(col) == -1) seen(row+1)(col) = uniquePathsMemoization(n, m, row + 1, col, seen)
if (seen(row)(col + 1) == -1 ) seen(row)(col) = uniquePathsMemoization(n,m, row, col + 1, seen)
seen(row+1)(col) + seen(row)(col + 1)
}
由于存储在 seen
数组中的状态,将此代码转换为纯函数版本并不容易。但是这个状态可以为应用程序的其余部分隐藏,使用函数装饰器:
def uniquePathsMemoizationGenerator( maxRows: Int, maxCols:Int ) : (Int,Int,Int,Int) => Int = {
def uniquePathsMemoization(n:Int, m:Int, row:Int, col:Int, seen:Array[Array[Int]]):Int = (row,col) match{
case (row,col) if row == m && col == n =>
1
case (row,col) if row > m || col > n =>
0
case (row,col) =>
if (seen(row+1)(col) == -1) seen(row+1)(col) = uniquePathsMemoization(n, m, row + 1, col, seen)
if (seen(row)(col + 1) == -1 ) seen(row)(col) = uniquePathsMemoization(n,m, row, col + 1, seen)
seen(row+1)(col) + seen(row)(col + 1)
}
val seen = Array.fill(maxRows,maxCols)(-1)
uniquePathsMemoization(_,_,_,_,seen)
}
val maxRows = ???
val maxCols = ???
val uniquePaths = uniquePathsMemoizationGenerator( maxRows, maxCols )
// Use uniquePaths from this point, instead of uniquePathsMemoization
将这段使用记忆的代码转换为正确的 Scala 使用案例和函数式编程的最佳方法是什么?
def uniquePathsMemoization(n:Int, m:Int, row:Int, col:Int, seen:Array[Array[Int]]):Int = {
if (row == m && col == n) 1
if (row > m || col > n) 0
if (seen(row+1)(col) == -1) seen(row+1)(col) = uniquePathsMemoization(n, m, row + 1, col, seen)
if (seen(row)(col + 1) == -1 ) seen(row)(col) = uniquePathsMemoization(n,m, row, col + 1, seen)
seen(row+1)(col) + seen(row)(col + 1)
}
这是使用 match
和 case
def uniquePathsMemoization(n:Int, m:Int, row:Int, col:Int, seen:Array[Array[Int]]):Int = (row,col) match{
case (row,col) if row == m && col == n =>
1
case (row,col) if row > m || col > n =>
0
case (row,col) =>
if (seen(row+1)(col) == -1) seen(row+1)(col) = uniquePathsMemoization(n, m, row + 1, col, seen)
if (seen(row)(col + 1) == -1 ) seen(row)(col) = uniquePathsMemoization(n,m, row, col + 1, seen)
seen(row+1)(col) + seen(row)(col + 1)
}
由于存储在 seen
数组中的状态,将此代码转换为纯函数版本并不容易。但是这个状态可以为应用程序的其余部分隐藏,使用函数装饰器:
def uniquePathsMemoizationGenerator( maxRows: Int, maxCols:Int ) : (Int,Int,Int,Int) => Int = {
def uniquePathsMemoization(n:Int, m:Int, row:Int, col:Int, seen:Array[Array[Int]]):Int = (row,col) match{
case (row,col) if row == m && col == n =>
1
case (row,col) if row > m || col > n =>
0
case (row,col) =>
if (seen(row+1)(col) == -1) seen(row+1)(col) = uniquePathsMemoization(n, m, row + 1, col, seen)
if (seen(row)(col + 1) == -1 ) seen(row)(col) = uniquePathsMemoization(n,m, row, col + 1, seen)
seen(row+1)(col) + seen(row)(col + 1)
}
val seen = Array.fill(maxRows,maxCols)(-1)
uniquePathsMemoization(_,_,_,_,seen)
}
val maxRows = ???
val maxCols = ???
val uniquePaths = uniquePathsMemoizationGenerator( maxRows, maxCols )
// Use uniquePaths from this point, instead of uniquePathsMemoization