Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl Can';t使用未定义的值作为子例程引用_Perl - Fatal编程技术网

Perl Can';t使用未定义的值作为子例程引用

Perl Can';t使用未定义的值作为子例程引用,perl,Perl,作为练习,我尝试实现一个堆栈来计算后缀表达式 use strict; use warnings; use Scalar::Util qw(looks_like_number); my %operators = ( '+' => \&sum, '-' => \&subs, '*' => \&mul, '/' => \&div, ); print 'Enter an expression to evalua

作为练习,我尝试实现一个堆栈来计算后缀表达式

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];}
我怀疑
$operators{$lettres[$I]}->($nb1,$nb2)导致了这个问题,但我不知道为什么,因为我从Perl开始


为什么会发生这种情况,我如何解决这个问题?

首先,只考虑非空间字符的有效令牌序列。其次,如果令牌看起来不像数字,请确保
%operators
哈希中有一个处理程序。我发现在处理堆栈时,它更加自然,但这并不重要

#!/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];}
#/usr/bin/env perl
严格使用;
使用警告;
#启用自动刷新
当地$|=1;
使用Scalar::Util qw(看起来像数字);
我的%operators=(
“+”=>\&add,
“-”=>\&subtract,
“*”=>\&乘法,
“/”=>\÷,
);
打印“输入要计算的表达式:”;
我的$input=;
my@tokens=拆分“”,$input;
我的@stack;
我的$tokens(@tokens){
如果(看起来像数字($token)){
推@stack,$token;
}
否则{
if(存在$operators{$token}){
my$op=$operators{$token};
my$x=pop@stack;
my$y=pop@stack;
推送@stack,$op->($x,$y);
}
否则{
警告“未知令牌“$token”\n;
}
}
}
打印“应答:$stack[-1]\n”;
子添加{$\[0]+$\[1];}
子乘法{$\[0]*$\[1];}
子减法{$\[0]-$\[1];}
子除法{$\[0]/$\[1];}

它的意思是
$operators{$lettres[$i]}
返回了undf。@ikegami我现在明白了。这是因为我输入了
8 6 2-/3+
作为输入,所以在
字母
数组中得到了空格。还有更好的方法吗?就像只创建一个函数,它也将运算符作为参数?我的第一个实现是使用一个开关,但由于它不受支持,我使用了这种方法。不是在
/
(所有内容)上拆分,而是在所有空白
/\s+/
上拆分,这将只取非空白的元素;也就是说,你的数字和运算符
split(“”)
甚至更好,因为它忽略了前导空格。是的,我更喜欢移位和取消移位,因为这就像我可视化堆栈一样。
unshift @stack, $operators{$lettres[$i]}->($nb1,$nb2);
#!/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];}