这段代码是什么意思(if v then return v end)?
What does this code mean (if v then return v end)?
所以我有这段代码,它是这样的:
do
local function index(n,m)
return n*(n+1)//2 + m
end
local binomtable = {}
function binom3(n,m)
if n<0 or m<0 or m>n then return 0 end
if n=0 or m=0 or m=n then return 1 end
local i = index(n,m)
local v = binomtable[i]
if v then return v end
v = binom3(n-1,m-1) + binom3(n-1,m)
binomtable[i] = v
return v
end
end
我想知道什么
if v then return v end
表示。
谢谢!
简短的回答是 if v then return v end
returns 值 v
如果它是真实的,即,如果它既不是 false
也不是 nil
。否则函数继续计算 v
的值,将该值存储在 binomtable
中,最后返回它。更有趣的问题是,为什么函数要完成所有这些?
在发布的代码中,binom3
是一个递归函数。使用递归调用 v = binom3(n-1,m-1) + binom3(n-1,m)
将会有很多重复工作,这意味着会浪费很多 space 和时间。考虑:
binom3(4, 2)
--> binom3(3, 1) + binom3(3, 2)
--> binom3(2, 0) + binom3(2, 1) + binom3(2, 1) + binom3(2, 2)
--> 1 + binom3(1, 0) + binom3(1, 1) + binom3(1, 0) + binom3(1, 1) + 1
请注意在第二次归约中有两个相同的项:
binom3(2, 1) + binom3(2, 1)
没有理由计算binom3(2, 1)
项两次,这样做意味着这对项:
binom3(1, 0) + binom3(1, 1)
也必须计算两次,如第三次归约所示。只计算一次 binom3(2, 1)
并保存结果以供以后在更大的计算中使用是明智的。当 m
和 n
较大并且计算数量呈指数爆炸时,这对于所需内存量和所需时间量的性能来说都是一个非常重要的问题。
发布的代码使用 memoization 来提高性能。进行计算时,它存储在 table binomtable
中。在进行任何计算之前,请参考 binomtable
。首先,v
设置为binomtable[i]
的值;如果这个值是任何真值(任何整数在 Lua 中都是真值),那么该值将被简单地返回而不需要递归计算。否则,如果返回 nil
(即尚未为计算存储任何值),函数将继续进行递归计算。计算完成后,将新值存入binomtable
中,以备下次需要时使用。这种策略节省了大量无用的计算量,并且可以使此类递归算法的性能产生巨大差异。
针对你的具体问题
if v then return v end
的意思是,如果v
,一个变量,不是nil
或false
,它就是returnv变量的值并停止执行那个功能。
--Similar
function myfunc(input)
local MyVar = "I am a string and am not nil!"
if MyVar then
return "hi"
else
return "hello"
end
print("I am not seen because I am unreachable code!")
end
如果调用此函数,它总是 return "hi" 而不是 "hello" 因为 MyVar 为真,因为它有一个值。此外,下面的 print
函数永远不会被调用,因为它在调用 return
后停止执行该函数。
现在,对于您的代码案例,它正在检查 table
以查看它是否在某个 index
处有条目,如果有,则 return 是值。
所以我有这段代码,它是这样的:
do
local function index(n,m)
return n*(n+1)//2 + m
end
local binomtable = {}
function binom3(n,m)
if n<0 or m<0 or m>n then return 0 end
if n=0 or m=0 or m=n then return 1 end
local i = index(n,m)
local v = binomtable[i]
if v then return v end
v = binom3(n-1,m-1) + binom3(n-1,m)
binomtable[i] = v
return v
end
end
我想知道什么
if v then return v end
表示。
谢谢!
简短的回答是 if v then return v end
returns 值 v
如果它是真实的,即,如果它既不是 false
也不是 nil
。否则函数继续计算 v
的值,将该值存储在 binomtable
中,最后返回它。更有趣的问题是,为什么函数要完成所有这些?
在发布的代码中,binom3
是一个递归函数。使用递归调用 v = binom3(n-1,m-1) + binom3(n-1,m)
将会有很多重复工作,这意味着会浪费很多 space 和时间。考虑:
binom3(4, 2)
--> binom3(3, 1) + binom3(3, 2)
--> binom3(2, 0) + binom3(2, 1) + binom3(2, 1) + binom3(2, 2)
--> 1 + binom3(1, 0) + binom3(1, 1) + binom3(1, 0) + binom3(1, 1) + 1
请注意在第二次归约中有两个相同的项:
binom3(2, 1) + binom3(2, 1)
没有理由计算binom3(2, 1)
项两次,这样做意味着这对项:
binom3(1, 0) + binom3(1, 1)
也必须计算两次,如第三次归约所示。只计算一次 binom3(2, 1)
并保存结果以供以后在更大的计算中使用是明智的。当 m
和 n
较大并且计算数量呈指数爆炸时,这对于所需内存量和所需时间量的性能来说都是一个非常重要的问题。
发布的代码使用 memoization 来提高性能。进行计算时,它存储在 table binomtable
中。在进行任何计算之前,请参考 binomtable
。首先,v
设置为binomtable[i]
的值;如果这个值是任何真值(任何整数在 Lua 中都是真值),那么该值将被简单地返回而不需要递归计算。否则,如果返回 nil
(即尚未为计算存储任何值),函数将继续进行递归计算。计算完成后,将新值存入binomtable
中,以备下次需要时使用。这种策略节省了大量无用的计算量,并且可以使此类递归算法的性能产生巨大差异。
针对你的具体问题
if v then return v end
的意思是,如果v
,一个变量,不是nil
或false
,它就是returnv变量的值并停止执行那个功能。
--Similar
function myfunc(input)
local MyVar = "I am a string and am not nil!"
if MyVar then
return "hi"
else
return "hello"
end
print("I am not seen because I am unreachable code!")
end
如果调用此函数,它总是 return "hi" 而不是 "hello" 因为 MyVar 为真,因为它有一个值。此外,下面的 print
函数永远不会被调用,因为它在调用 return
后停止执行该函数。
现在,对于您的代码案例,它正在检查 table
以查看它是否在某个 index
处有条目,如果有,则 return 是值。