2012-08-26 115 views
1

我已經用Perl編寫了下面的代碼,但它沒有給出理想的輸出。我正在處理一個數組和兩個散列數組之間的比較。Perl:將數組的2個哈希與另一個數組進行比較

鑑於樣本輸入文件:

1) file1.txt 
    A6416 A2318 
    A84665 A88 

2)hashone.pl

%hash1=(
A6416=>['E65559', 'C11162.1', 'c002gnj.3',], 
A88=>['E77522', 'M001103', 'C1613.1', 'c001hyf.2',], 
A84665=>['E138347', 'M032578', 'C7275.1', 'c009xpt.3',], 
A2318=>['E128591', 'C43644.1', 'C47705.1', 'c003vnz.4',], 
); 

3)hashtwo.pl

%hash2=(
15580=>['C7275.1', 'E138347', 'M032578', 'c001jnm.3', 'c009xpt.2'], 
3178=>['C1613.1', 'E77522','M001103', 'c001hyf.2', 'c001hyg.2'], 
24406=>['C11162.1', 'E65559', 'M003010', 'c002gnj.2'], 
12352=>['C43644.1', 'C47705.1', 'E128591','M001458', 'c003vnz.3'], 
); 

我的目標是實現任務描述:

從file1.txt,我必須l在%hash1中找到相應的ID。例如,A6416(file1.txt)是%hash1中的關鍵字。接下來,我必須在%hash2中找到A6416 ['E65559','C11162.1','c002gnj.3',]的值。如果在%hash2中找到多數(超過50%)的值,我用%hash2中的相應鍵替換A6416。

Example: 
A6416 A2318 
A84665 A88 

Output: 
24406 12352 
15580 3178 

請注意,%hash1和%hash2的鍵是不同的(它們不重疊)。但值是相同的(它們重疊)。

#!/usr/bin/perl -w 
use strict; 
use warnings; 
open FH, "file1.txt" || die "Error\n"; 
my %hash1 = do 'hashone.pl';  
my %hash2 = do 'hashtwo.pl'; 
chomp(my @array=<FH>); 

foreach my $amp (@array) 
{ 
    if ($amp =~ /(\d+)(\s?)/) 
    { 
     if (exists ($hash1{$1})) 
     { 
      for my $key (keys %hash2) 
      { 
       for my $i (0 .. $#{ $hash2{$key} }) 
       { 
        if ((@{$hash1{$1}}) eq ($hash2{$key}[$i])) 
        { 
        print "$key"; 
        } 
       } 
      } 
     } 
    } 
} 
close FH; 
1; 

關於這個問題的任何指導,高度讚賞。謝謝!

回答

3

我想你應該顛倒%hash2成這種結構:

$hash2{'C7275.1'} = $hash2{'E138347'} = $hash2{'M032578'} 
        = $hash2{'c001jnm.3'} = $hash2{'c009xpt.2'} = 15580; 
$hash2{'C1613.1'} = $hash2{'E77522'} = $hash2{'M001103'} 
        = $hash2{'c001hyf.2'} = $hash2{'c001hyg.2'} = 3178; 
$hash2{'C11162.1'} = $hash2{'E65559'} 
        = $hash2{'M003010'} = $hash2{'c002gnj.2'} = 24406; 
$hash2{'C43644.1'} = $hash2{'C47705.1'} = $hash2{'E128591'} 
        = $hash2{'M001458'} = $hash2{'c003vnz.3'} = 3178; 

這樣就可以更有效地執行這些查找窗口,而不是每個元素的的%hash2每一個元素迭代。

+0

感謝您的答覆。我嘗試了reverse()函數來顛倒%hash2。 %revhash = reverse(%hash2);但它會產生一個錯誤。鑑於每個密鑰都有多個值,有沒有具體的方法可以做到這一點? – zock

+0

爲了澄清,你創建了一個具有多個鍵和1個值的散列結構嗎?請讓我知道,以便我可以相應地進行。 – zock

+0

@zock:由於'%hash2'的每個鍵映射到一個arrayref,因此不能只使用'reverse'。你需要寫一個循環:'my%revhash; foreach my $ key(keys%hash2){foreach my $ value(@ {$ hash2 {$ key}}){$ revhash {$ value} = $ key; }}。 – ruakh

1

大廈從ruakh和zock這裏的答覆是,你需要建立查找表HASH2

#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dumper; 

my %hash2=(
15580=>['C7275.1', 'E138347', 'M032578', 'c001jnm.3', 'c009xpt.2'], 
3178=>['C1613.1', 'E77522','M001103', 'c001hyf.2', 'c001hyg.2'], 
24406=>['C11162.1', 'E65559', 'M003010', 'c002gnj.2'], 
12352=>['C43644.1', 'C47705.1', 'E128591','M001458', 'c003vnz.3'], 
); 

# Build LUT for hash2 
my %hash2_lut; 
foreach my $key (keys %hash2) 
{ 
    foreach my $val (@{$hash2{$key}}) 
    { 
     $hash2_lut{$val} = $key 
    } 
} 

print Dumper(\%hash2_lut); 

請選擇ruakh的崗位作爲答案的代碼,只是想澄清的代碼爲你。使用Data::Dumper ...這是你的朋友。

這裏是輸出:

$VAR1 = { 
     'C47705.1' => '12352', 
     'M032578' => '15580', 
     'E138347' => '15580', 
     'E77522' => '3178', 
     'C7275.1' => '15580', 
     'c001jnm.3' => '15580', 
     'E65559' => '24406', 
     'C1613.1' => '3178', 
     'M001458' => '12352', 
     'c002gnj.2' => '24406', 
     'c009xpt.2' => '15580', 
     'c001hyf.2' => '3178', 
     'C43644.1' => '12352', 
     'E128591' => '12352', 
     'c001hyg.2' => '3178', 
     'M003010' => '24406', 
     'c003vnz.3' => '12352', 
     'C11162.1' => '24406', 
     'M001103' => '3178' 
    }; 
+0

感謝您的幫助! – zock

相關問題