删除perl哈希中的冗余

时间:2012-03-28 12:03:02

标签: perl

我有一个看起来像这样的文件。

a_8_3_1-b_30_5_6-c_6_2_1- + b_30_5_6-
a_123_1_1- + d_144_1_7-
a_123_1_1- + c_1_4_1-
b_50_1_1- + d_144_1_7-
a_123_1_1- + c_2_1_2-
c_1_4_1- + a_123_1_1-
a_123_1_1- + a_93_1_2-
d_144_1_7- + a_123_1_1-
c_2_1_2- + a_123_1_1-
a_123_1_1- + c_2_1_2-

它有2列,用“+”符号分隔。我需要计算此文件中存在的唯一组合的数量。

如图所示,组合形成,例如a_123_1_1-和c_2_1_2-之间,以及c_2_1_2- + a_123_1_1-之间。现在我需要数不了。在这样的文件中出现这种对,我知道这种组合(不论它们的相对顺序)发生了3次。

与a_123_1_1-和d_144_1_7-类似。它们以两种组合出现。每个组合出现一次。因此,累计计数为= 2

我现在已经尝试将所有这些行放在哈希中(即每一行都是一个键,它的出现将是它的相应值)并打印出no。在PERL中使用map函数的事件。

但是如何包含这样的冗余并在各个元素之间解决这个顺序问题呢?

请帮忙。

3 个答案:

答案 0 :(得分:5)

在处理perl 时总是有不止一种方法,但你可以:

  1. 拆分每一行,使其产生@pair的两个条目
  2. 对@pair进行排序,以便唯一的对将始终产生相同的顺序
  3. 连接已排序的@pair,以便获得字符串
  4. 将您的字符串存储在%哈希并计算出现次数

  5. 如下例所示:

    use warnings;
    use strict;
    
    use Data::Dumper;
    
    my %count;
    
    for (<DATA>) { chomp;
      my $str_pair = join ':', sort split / \+ /;
      $count{$str_pair}++;
    }
    
    print STDERR Dumper \%count;
    
    __DATA__
    a_8_3_1-b_30_5_6-c_6_2_1- + b_30_5_6-
    a_123_1_1- + d_144_1_7-
    a_123_1_1- + c_1_4_1-
    b_50_1_1- + d_144_1_7-
    a_123_1_1- + c_2_1_2-
    c_1_4_1- + a_123_1_1-
    a_123_1_1- + a_93_1_2-
    d_144_1_7- + a_123_1_1-
    c_2_1_2- + a_123_1_1-
    a_123_1_1- + c_2_1_2-
    

    <强>输出

    $VAR1 = {
              'a_8_3_1-b_30_5_6-c_6_2_1-:b_30_5_6-' => 1,
              'a_123_1_1-:c_2_1_2-' => 3,
              'a_123_1_1-:c_1_4_1-' => 2,
              'a_123_1_1-:a_93_1_2-' => 1,
              'b_50_1_1-:d_144_1_7-' => 1,
              'a_123_1_1-:d_144_1_7-' => 2
            };
    

答案 1 :(得分:0)

my %terms;
while ( <> ) { 
    next unless my @parts = split /\s*\+\s*/;
    $terms{$_}++ foreach @parts;
}

say +( keys %terms) . ' unique terms.';

答案 2 :(得分:0)

这是一个处理您描述的数据的单行程序

perl -naF"/[\s+]+/" -e "$p{join ' ', sort @F}++; END{print 0+keys %p, qq( unique pairs\n)}" myfile

根据您问题中的数据,此输出

6 unique pairs

如果您需要更详细的内容,则需要恢复完整的程序。这相当于上面的代码

use strict;
use warnings;

my %pairs;

while (<>) {
  my $key = join ' ', sort split /[\s+]+/;
  $pairs{$key}++;
}

printf "%d unique pairs\n", scalar keys %pairs;