作为练习,我试图实现一个堆栈来计算后缀表达式。
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开始。
为什么会发生这种情况,我该如何解决?
答案 0 :(得分:2)
首先,仅考虑非空格字符的有效令牌序列。其次,如果令牌看起来不像数字,请确保%operators
哈希中的处理程序exists。在处理堆栈时,我发现push和pop更自然,但这并不重要;
#!/usr/bin/env perl
use strict;
use warnings;
# Turn on autoflush
local $| = 1;
use Scalar::Util qw(looks_like_number);
my %operators = (
'+' => \&add,
'-' => \&subtract,
'*' => \&multiply,
'/' => \÷,
);
print 'Enter an expression to evaluate : ';
my $input = <STDIN>;
my @tokens = split ' ', $input;
my @stack;
for my $token (@tokens) {
if (looks_like_number($token)) {
push @stack, $token;
}
else {
if (exists $operators{$token}) {
my $op = $operators{$token};
my $x = pop @stack;
my $y = pop @stack;
push @stack, $op->($x, $y);
}
else {
warn "Unknown token '$token'\n";
}
}
}
print "Answer: $stack[-1]\n";
sub add { $_[0] + $_[1];}
sub multiply { $_[0] * $_[1];}
sub subtract { $_[0] - $_[1];}
sub divide { $_[0] / $_[1];}