fla*_*awr 13 recursion matlab anonymous-function
我知道这不是匿名函数的用途,但就像我试图通过匿名函数创建递归函数一样.递归函数的原型显然是阶乘函数.问题是,这是很难做出区分的情况下内的匿名函数.到目前为止我设法做的是:
f=@(cn,n,f)eval('if n>1; f(cn*n,n-1,f);else;ans=cn;end');
f=@(n)f(1,n,f);
Run Code Online (Sandbox Code Playgroud)
或者:
f=@(cn,n,f)eval('if n>1; f(cn*n,n-1,f);else;disp(cn);end');
f=@(n)f(1,n,f);
Run Code Online (Sandbox Code Playgroud)
不太令人满意的是,直接分配时仍然无法使用此功能,a=f(3)仍会产生错误,因为eval没有得到值.
所以我的问题是,您是否可以通过匿名函数实际执行递归函数,例如以允许例如a=f(3)仅依赖于本机matlab函数(或者您可以在命令行中创建的函数,如我在示例中所做的那样)计算阶乘的方式?
PS:我知道这没有任何实际用途,这只是对你可以弯曲和滥用Matlab语法的挑战.
我们现在发现了两种可能性,都依赖于细胞阵列的使用.请注意,这可能不适用于Octave.
此方法使用matlabs布尔值,true可以计算为,1而false可以计算为0.
if_ = @( pred_, cond_ ) cond_{ 2 - pred_ }();
Run Code Online (Sandbox Code Playgroud)
这里我们必须提供一个条件作为第一个参数,一个2元素单元格数组作为第二个参数.每个单元格元素应该是一个函数句柄,如果条件为真/不为真,则调用该函数句柄.我们的阶乘函数看起来像这样:
fac = @(n,f)if_(n>1,{@()n*f(n-1,f),@()1})
factorial_=@(n)fac(n,fac);
factorial_(10)
Run Code Online (Sandbox Code Playgroud)
正如@AndrasDeak在下面评论的那样:这里的重要部分是我们有一个函数的单元数组而不是值.这提供了短路,n*f(n-1,f)除非我们调用相应的功能,否则不进行评估@()n*f(n-1,f).
该第二种方法是由@beaker发现,是较为灵活:
iif = @(varargin) varargin{2*find([varargin{1:2:end}], 1, 'first')}();
Run Code Online (Sandbox Code Playgroud)
这利用了varargin即使在匿名函数中也可以使用(可变数量的参数)这一事实.当您调用此函数时,您必须替换条件以及条件为真时应执行的操作.这个甚至允许switch构造或if ... else if ... else if ... (...) else ...构造.调用时,它将查找第一个为true(find([varargin{1:2:end}], 1, 'first'))的条件并调用相应的函数.我们的阶乘函数示例如下所示:
fac = @(n,f)iif(n>1,@()n * f(n-1,f),true,@()1);
factorial_=@(n)fac(n,fac);
factorial_(10)
Run Code Online (Sandbox Code Playgroud)
编辑:有趣的事实:我们正在做什么线
factorial_=@(n)fac(n,fac);
Run Code Online (Sandbox Code Playgroud)
也被称为应用Y-组合子.事实上,我们可以写为
Y = @(f)@(x)f(x,f);
factorial_=Y(f);
Run Code Online (Sandbox Code Playgroud)