【问题标题】:Search an element in a hash table在哈希表中搜索元素
【发布时间】:2013-06-14 11:40:29
【问题描述】:

我从这样的文本文件创建了一个哈希表:

use strict;
use warnings;

my %h;

open my $fh, '<', 'tst' or die "failed open 'tst' $!";
while ( <$fh> ) {
  push @{$h{keys}}, (split /\t/)[0];
}
close $fh;

use Data::Dumper;
print Dumper \%h;

现在我想在哈希表的另一个文本文件中查找一个字段。 如果存在,则将当前行写入结果文件:

use strict;
use warnings;

my %h;

open my $fh, '<', 'tst' or die "failed open 'tst' $!";
while ( <$fh> ) {
  push @{$h{keys}}, (split /\t/)[0];
}
close $fh;


use Data::Dumper;
print Dumper \%h;

open (my $fh1,"<", "exp") or die "Can't open the file: ";

while (my $line =<$fh1>){

chomp ($line);



my ($var)=split(">", $line);

if exists $h{$var};
print ($line);

}

我收到了这些错误:

syntax error at codeperl.pl line 26, near "if exists" 
Global symbol "$line" requires explicit package name at codeperl.pl line 27. 
syntax error at codeperl.pl line 29, near "}" 
Execution of codeperl.pl aborted due to compilation errors.

有什么想法吗?

【问题讨论】:

    标签: perl search hashtable


    【解决方案1】:

    有什么要说的? 语句 if exists $h{$var}; 是语法错误。你可能想要:

    print $line, "\n" if exists $h{$var};
    

    if (exists $h{$var}) {
      print $line, "\n";
    }
    

    一旦您修复了该错误,其他错误就会消失。如果您遇到多个错误,请始终查看 first 错误(相对于行号)。后来的错误通常是前一个错误的结果。在这种情况下,语法错误搞砸了解析。


    编辑

    您的主要问题不是语法错误,而是您填充哈希的方式。

    push @{$h{keys}}, (split /\t/)[0];
    

    将行上的第一个字段推到keys 条目中的arrayref 上。对我来说,您似乎实际上想使用这个字段作为键:

    my ($key) = split /\t/;
    $h{$key} = undef;   # any value will do.
    

    之后,您的Dumper \%h 将产生类似

    $VAR1 = {
      '@ ries bibliothèques électroniques à travers' => undef,
      'a a pour les ressortissants des'              => undef,
      'a a priori aucune hiérarchie des'             => undef,
    };
    

    您通过exists 进行的查找应该可以工作。

    【讨论】:

    • 我不知道你的评论是什么意思(我不会说法语也无济于事)。如果您想显示示例输入(一个好主意),请edit您的问题。
    • 首先,抱歉我的英语不好 :( 我在哈希表中有这个 :$VAR1 = { 'keys' => [ '@ries bibliothèques électroniques à travers', 'aa pour les ressortissants des ', 'aa priori aucune hiérarchie des', ] }; 在输入文件“exp”中有这样的内容:“@ries bibliothèques électroniques à travers > the building which (0.000000183067019)” 所以脚本将搜索“”@ries bibliothèques électroniques à travers”,通常存在于哈希表中.. 但找不到它
    • @CyrineEzzahra 你的哈希只有一个键:keys。请参阅我的更新以了解如何正确填充哈希,使其具有多个键。
    • use strict; use warnings; my %h; open my $fh, '&lt;', 'tst' or die "failed open 'tst' $!"; while ( &lt;$fh&gt; ) { my ($key) = split /\t/; $h{$key} = 1; } close $fh; use Data::Dumper; print Dumper \%h; open (my $fh1,"&lt;", "exp") or die "Can't open the file: "; while (my $line =&lt;$fh1&gt;){ chomp ($line); my ($var)=split("&gt;", $line); if (exists $h{$var}) { print $line, "\n"; } } like this doesnt work also, it cannot find
    • @CyrineEzzahra 好的,那么第二个文件的内容是什么?要使exists 返回 true,键必须与文件中的字段的字符相同。
    【解决方案2】:

    试试这样的代码

    首先,构建你的哈希

    while(<$file1>){
        # get your key from current line
        $key = (split)[0];
    
        # set the key into the hash
        $hash{$key} = 1;
    }
    

    二、判断

    while(<$file2>){
         # get the field you want you judge
         $value = (split)[0];
    
         # to see if $value exists
         if( exists $hash{$value} ){
             print "got $value";
         }
    }
    

    【讨论】:

    • use strictuse warnings 怎么样?
    • @M42 配合use strictuse warnings,可以帮助你避免一些编码错误。上面的代码只是一个提示。
    • @akawhy 但是你知道你的代码不会在strict 下运行吗?你还知道split 返回标量上下文中的字段数吗?
    • @amon 感谢您指出这一点。我将对代码进行一些更改
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    • 2012-10-12
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多