递归匿名函数计算级数和
recursive anonymous function to calculate series sum
我尝试编写一个函数来计算以下内容,
我能想到的就是这个,这是行不通的。
$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);
}
同样,fact
就是:
sub fact {
my ($n) = @_;
my $acc = 1;
$acc *= $_ for 1..$n;
return $acc;
}
关于问题,递归函数匿名只是将递归调用替换为__SUB__->(...)
[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
无论如何都必须在某种程度上进行特殊处理。
__SUB__
是在 Perl 5.16 中引入的。如果你想避免内存泄漏,那之前就更复杂了。
我尝试编写一个函数来计算以下内容,
我能想到的就是这个,这是行不通的。
$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);
}
同样,fact
就是:
sub fact {
my ($n) = @_;
my $acc = 1;
$acc *= $_ for 1..$n;
return $acc;
}
关于问题,递归函数匿名只是将递归调用替换为__SUB__->(...)
[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
无论如何都必须在某种程度上进行特殊处理。__SUB__
是在 Perl 5.16 中引入的。如果你想避免内存泄漏,那之前就更复杂了。