2014-05-14 34 views
0

作爲練習,我試圖實現一個堆棧來計算後綴表達式。不能使用未定義的值作爲子程序引用

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

它表示'$ operators {$ lettres [$ i]}'返回undef。 – ikegami

+0

@ikegami我現在看到。這是因爲我輸入'8 6 2 -/3 +'作爲輸入,所以我在'letters'數組中獲得了空格。還有沒有更好的方法來做到這一點?就像只創建一個函數一樣,也需要運算符作爲參數?我的第一個實現是使用交換機,但由於它不被支持,我使用這種方法。 – user2336315

+0

而不是在所有的空格上分割所有空格/ \ s + /'這隻會使用非空白的元素;即你的數字和運營商 –

回答

2

首先,只考慮非空格字符的有效令牌序列。其次,如果令牌看起來不像數字,請確保%operators散列中的句柄exists。我發現pushpop在處理堆棧時更自然,但這並不重要;

#!/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, 
    '/' => \&divide, 
); 

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];} 
+0

是的,我喜歡移位和不移位原因,這就像我想象堆棧。 – user2336315

相關問題