【发布时间】:2014-05-15 03:43:08
【问题描述】:
作为练习,我正在尝试实现一个堆栈来计算后缀表达式。
use strict;
use warnings;
use Scalar::Util qw(looks_like_number);
my %operators = (
'+' => \&sum,
'-' => \&subs,
'*' => \&mul,
'/' => \&div,
);
print 'Enter an expression to evaluate : ';
chomp($_ = <STDIN>);
my @lettres=split(//);
my @stack;
for(my $i = 0; $i < @lettres; $i++){
if(looks_like_number($lettres[$i])){
unshift @stack, $lettres[$i];
} else {
my $nb1 = shift @stack;
my $nb2 = shift @stack;
unshift @stack, $operators{$lettres[$i]}->($nb1,$nb2);
}
}
print 'Answer : ' .shift @stack;
sub sum { return $_[0] + $_[1];}
sub mul { return $_[0] * $_[1];}
sub subs { return $_[0] - $_[1];}
sub div { return $_[0] / $_[1];}
运行它时,我得到:
Can't use an undefined value as a subroutine reference at polonaise.pl line 25,
<STDIN> line 1.
第 25 行是:
unshift @stack, $operators{$lettres[$i]}->($nb1,$nb2);
我怀疑是 $operators{$lettres[$i]}->($nb1,$nb2); 导致了这个问题,但我不知道为什么,因为我从 Perl 开始。
为什么会发生这种情况,我该如何解决?
【问题讨论】:
-
这意味着
$operators{$lettres[$i]}返回了undef。 -
@ikegami 我现在看到了。这是因为我输入了
8 6 2 - / 3 +作为输入,所以我在letters数组中得到了空格。还有没有更好的方法呢?就像只创建一个也将运算符作为参数的函数?我的第一个实现是使用开关,但由于不支持,我使用了这种方法。 -
而不是在
//(一切)上分割,而是在所有空格/\s+/上分割,这只会采用不是空格的元素;即您的号码和运营商 -
split(' ')甚至更好,因为它忽略了前导空格。
标签: perl