Perl 递归匿名函数来计算级数和
我试着写一个函数来计算, 我所能想到的就是这个,它不起作用Perl 递归匿名函数来计算级数和,perl,recursion,anonymous-function,Perl,Recursion,Anonymous Function,我试着写一个函数来计算, 我所能想到的就是这个,它不起作用 $fact = sub { $n = shift; if($n==0 || $n ==1){ return 1; }else{ return $n*&$fact($n-1); } } sub fun{ ($x,$n)= @_; if($n==0){ return 1; }elsif($n == 1){ re
$fact = sub {
$n = shift;
if($n==0 || $n ==1){
return 1;
}else{
return $n*&$fact($n-1);
}
}
sub fun{
($x,$n)= @_;
if($n==0){
return 1;
}elsif($n == 1){
return $x;
}else{
return ($x)/&$fact($n)+fun($x,$n-1);
}
}
print (fun(3,5));
首先,始终使用
use strict;
use warnings qw( all );
它会抓住你的一个错误
其次,你把你的潜艇命名错误,你错过了一个
my
,你发明了一个特例(因为($x**1)/1!==$x
)[1]。忽略目前匿名的需要,f
只是:
sub f {
my ($x, $n) = @_;
return 1 if $n == 0;
return ($x**$n) / fact($x) + f($x, $n-1);
}
sub fact {
my ($n) = @_;
my $acc = 1;
$acc *= $_ for 1..$n;
return $acc;
}
类似地,事实
也只是:
sub f {
my ($x, $n) = @_;
return 1 if $n == 0;
return ($x**$n) / fact($x) + f($x, $n-1);
}
sub fact {
my ($n) = @_;
my $acc = 1;
$acc *= $_ for 1..$n;
return $acc;
}
关于这个问题,使递归函数匿名只是将递归调用替换为
\uuuu SUB\uuu->(…)
[2]的问题,因此以下是匿名版本:
use feature qw( current_sub );
my $f = sub {
my ($x, $n) = @_;
return 1 if $n == 0;
return ($x**$n) / fact($x) + __SUB__->($x, $n-1);
};
如果你也希望fact
匿名
use feature qw( current_sub );
my $f = sub {
my ($x, $n) = @_;
return 1 if $n == 0;
my $fact = sub {
my ($n) = @_;
my $acc = 1;
$acc *= $_ for 1..$n;
return $acc;
};
return ($x**$n) / $fact->($x) + __SUB__->($x, $n-1);
};
也就是说,对于这个函数来说,使用递归是一种巨大的浪费。下面是一个高效的实现:
my $f = sub {
my ($x, $n) = @_;
my $acc = 1;
my $numerator_acc = 1;
my $denominator_acc = 1;
for (1..$n) {
$numerator_acc *= $x;
$denominator_acc *= $_;
$acc += ( $numerator_acc / $denominator_acc );
}
return $acc;
};
($x**0)/0!==1
,但无论发生什么情况,$n==0
都必须在一定程度上进行特殊处理\uuuuuuuu SUB\uuuuuuuuu
。如果您想避免内存泄漏,那么在此之前就更复杂了首先,始终使用
use strict;
use warnings qw( all );
它会抓住你的一个错误
其次,你把你的潜艇命名错误,你错过了一个
my
,你发明了一个特例(因为($x**1)/1!==$x
)[1]。忽略目前匿名的需要,f
只是:
sub f {
my ($x, $n) = @_;
return 1 if $n == 0;
return ($x**$n) / fact($x) + f($x, $n-1);
}
sub fact {
my ($n) = @_;
my $acc = 1;
$acc *= $_ for 1..$n;
return $acc;
}
类似地,事实
也只是:
sub f {
my ($x, $n) = @_;
return 1 if $n == 0;
return ($x**$n) / fact($x) + f($x, $n-1);
}
sub fact {
my ($n) = @_;
my $acc = 1;
$acc *= $_ for 1..$n;
return $acc;
}
关于这个问题,使递归函数匿名只是将递归调用替换为
\uuuu SUB\uuu->(…)
[2]的问题,因此以下是匿名版本:
use feature qw( current_sub );
my $f = sub {
my ($x, $n) = @_;
return 1 if $n == 0;
return ($x**$n) / fact($x) + __SUB__->($x, $n-1);
};
如果你也希望fact
匿名
use feature qw( current_sub );
my $f = sub {
my ($x, $n) = @_;
return 1 if $n == 0;
my $fact = sub {
my ($n) = @_;
my $acc = 1;
$acc *= $_ for 1..$n;
return $acc;
};
return ($x**$n) / $fact->($x) + __SUB__->($x, $n-1);
};
也就是说,对于这个函数来说,使用递归是一种巨大的浪费。下面是一个高效的实现:
my $f = sub {
my ($x, $n) = @_;
my $acc = 1;
my $numerator_acc = 1;
my $denominator_acc = 1;
for (1..$n) {
$numerator_acc *= $x;
$denominator_acc *= $_;
$acc += ( $numerator_acc / $denominator_acc );
}
return $acc;
};
($x**0)/0!==1
,但无论发生什么情况,$n==0
都必须在一定程度上进行特殊处理\uuuuuuuu SUB\uuuuuuuuu
。如果您想避免内存泄漏,那么在此之前就更复杂了你把你的两个功能搞混了。sub
fact
只接受一个数字n,并返回n!。您需要定义一个单独的函数,该函数使用fact
计算原始和,并调用它。此外,如果您真的要生成一个匿名和递归的函数,则需要使用某种零点组合器。@Mark Reed,在执行递归sub时,临时为其创建一个名称要容易得多:sub{local*\u r=sub{…\u r(…)…};\u r(@)}
。这两个函数混淆了。subfact
只接受一个数字n,并返回n!。您需要定义一个单独的函数,该函数使用fact
计算原始和,并调用它。此外,如果您真的要生成一个匿名和递归的函数,则需要使用某种零点组合器。@Mark Reed,在执行递归sub时,临时为其创建一个名称要容易得多:sub{local*\ur=sub{…\ur(…)…};\ur(@)}
。哇!令人惊叹的你真是个天才!SUB->($x$n-1),你能解释一下这个部分吗。或者添加到教程的链接来了解这一点?返回对当前执行的子例程的引用。->()
是通过引用调用子例程的方式;例如,您需要调用$f->(3,5)
将ikegami的实现用于示例输入。哇!令人惊叹的你真是个天才!SUB->($x$n-1),你能解释一下这个部分吗。或者添加到教程的链接来了解这一点?返回对当前执行的子例程的引用。->()
是通过引用调用子例程的方式;例如,您需要调用$f->(3,5)
以将ikegami的实现用于示例输入。