首页 > 解决方案 > 当我尝试将哈希(通过引用)和变量传递给子以打印哈希中的相应值时修复 Perl 错误

问题描述

在我的自然语言处理课程中,我正在努力解决我们被分配解决的 Perl 任务。

他们要求我们能够用 Perl 解决的问题如下:

根据经验,我确信我的脚本已经能够执行上述“第 1 部分”。

第 2 部分需要使用 Perl 子程序(子例程)完成,该子程序通过引用获取哈希值以及 to 哈希值。这是我遇到严重麻烦的部分。

Stefan Becker 建议进行重大更改之前的第一个版本;

#!/usr/bin/perl                                                                           

use warnings;
use strict;

sub hash_4Frequency
{
    my ($hashWord, $ref2_Hash) = @_;                       
    print $ref2_Hash -> {$hashWord}, "\n";  # thank you Stefan Becker, for sobriety
}

my %f = ();  # hash that will contain words and their frequencies                              
my $wc = 0;  # word-count                                       

my ($stdin, $word_2Hash) = @ARGV;  # corrected, thanks to Silvar

while ($stdin)
{
    while ("/\w+/")
    {
        my $w = $&;
        $_ = $";
        $f{lc $w} += 1;
        $wc++;
    }
}

my @args = ($word_2Hash, %f);
hash_4Frequency(@args);

修改后的第二个版本;

#!/usr/bin/perl

use warnings;
use strict;

sub hash_4Frequency
{
    my $ref2_Hash = %_;
    my $hashWord = $_;

    print $ref2_Hash -> {$hashWord}, "\n";
}

my %f = ();  # hash that will contain words and their frequencies
my $wc = 0;  # word-count

while (<STDIN>) 
{
    while (/\w+/)
    {
        chomp;
        my $w = $&;
        $_ = $";

        $f{$_}++ foreach keys %f;
        $wc++;
    }
}

hash_4Frequency($_, \%f);

当我在终端中执行' ./script.pl < somefile.txt someWord '时,Perl 抱怨(Perl 的第一个版本的输出)

 Use of uninitialized value $hashWord in hash element at   
 ./word_counter2.pl line 35.

 Use of uninitialized value in print at ./word_counter2.pl line 35.

Perl 对第二个版本的抱怨;

 Can't use string ("0") as a HASH ref while "strict refs" in use at ./word_counter2.pl line 13, <STDIN> line 8390.

至少现在我知道脚本可以成功运行到最后一点,而且它似乎是语义上的而不是句法上的。

关于最后一部分有什么进一步的建议吗?将不胜感激。

PS:对不起朝圣者,我只是Perl道路上的新手。

标签: stringperlnlp

解决方案


你的固定版本并不比你的第一个好多少。尽管它通过了语法检查,但它有几个语义错误。这是一个具有最少修复量的版本以使其正常工作

注意:这不是你用惯用的 Perl 编写它的方式。

#!/usr/bin/perl
use warnings;
use strict;

sub hash_4Frequency($$) {
    my($ref2_Hash, $hashWord) = @_;

    print $ref2_Hash -> {$hashWord}, "\n";
}

my %f = ();  # hash that will contain words and their frequencies
my $wc = 0;  # word-count

while (<STDIN>)
{
    chomp;
    while (/(\w+)/g)
    {
        $f{$1}++;
        $wc++;
    }
}

hash_4Frequency(\%f, $ARGV[0]);

使用“Lorem ipsum”作为输入文本的测试输出:

$ cat dummy.txt 
Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor
incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.
Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.

$ perl <dummy.txt dummy.pl Lorem
1

奖金代码:这将是我第一次解决给定的问题。您的第一个版本将所有单词都小写,这很有意义,所以我保留了它:

#!/usr/bin/perl
use warnings;
use strict;

sub word_frequency($$) {
    my($hash_ref, $word) = @_;

    print "The word '${word}' appears ", $hash_ref->{$word} // 0, " time(s) in the input text.\n";
}

my %words;  # hash that will contain words and their frequencies
my $wc = 0; # word-count

while (<STDIN>) {
    # lower case all words
    $wc += map { $words{lc($_)}++ } /(\w+)/g
}

print "Input text has ${wc} words in total, of which ",
      scalar(keys %words),
      " are unique.\n";

# return frequency in input text for every word on the command line
foreach my $word (@ARGV) {
    word_frequency(\%words, lc($word));
}

exit 0;

测试运行

$ perl <dummy.txt dummy.pl Lorem ipsum dolor in test
Input text has 66 words in total, of which 61 are unique.
The word 'lorem' appears 1 time(s) in the input text.
The word 'ipsum' appears 1 time(s) in the input text.
The word 'dolor' appears 1 time(s) in the input text.
The word 'in' appears 2 time(s) in the input text.
The word 'test' appears 0 time(s) in the input text.

推荐阅读