3

I have something I cannot get my head around

Let's say I have a phone list used for receiving and dialing out stored like below. The from and to location is specified as well.

Country1        Country2           number1           number2
USA_Chicago     USA_LA             12                14
AUS_Sydney      USA_Chicago        19                15
AUS_Sydney      USA_Chicago        22                21
CHI_Hong-Kong   RSA_Joburg         72                23
USA_LA          USA_Chigaco        93                27

Now all I want to do is to remove all the duplicates and give only what is relevant to the countries as keys and each number that is assigned to it in a pair, but the pair needs to be bi-directional.

In other words I need to get results back and then print them like this.

USA_Chicago-USA_LA         27    93   12    14
Aus_Sydney-USA_Chicago     19    15   22    21
CHI_Hong-kong-RSA_Joburg   72    23

I have tried many methods including a normal hash table and the results seem fine, but it does not do the bi-direction, so I will get this instead.

USA_Chicago-USA_LA         12    14
Aus_Sydney-USA_Chicago     19    15   22    21
CHI_Hong-kong-RSA_Joburg   72    23
USA_LA-USA_Chicago         93    27

So the duplicate removal works in one way, but because there is another direction, it will not remove the duplicate "USA_LA-USA_Chicago" which already exists as "USA_Chicago-USA_LA" and will store the same numbers under a swopped name.

The hash table I tried last is something like this. (not exactly as I trashed the lot and had to rewrite it for this post)

 @input= ("USA_Chicago USA_LA 12 14" ,
          "AUS_Sydney USA_Chicago 19 15" ,
          "AUS_Sydney USA_Chicago 22 21" ,
          "CHI_Hong-Kong RSA_Joburg 72 23" '
          "USA_LA USA_Chigaco 93 27");

 my %hash;
 for my $line (@input) {
 my ($c1, $c2, $n1, $n2) = split / [\s\|]+ /x, $line6;
 my $arr = $hash{$c1} ||= [];
    push @$arr, "$n1 $n2";
  }
 for my $c1 (sort keys %hash) {

 my $arr = $hash{$c1};
 my $vals = join " : ", @$arr;
 print "$c1 $vals\n";
  }

So all if A-B exists and so does B-A, use only one but assign the values from the key being removed, to the remaining key. I basically need to do is get rid of any duplicate key in any direction, but assign the values for to the remaining key. So A-B and B-A would be considered a duplicate, but A-C and B-C are not. -_-

4

2 回答 2

5

简单地将目的地标准化。我选择对它们进行排序。

use strictures;
use Hash::MultiKey qw();

my @input = (
    'USA_Chicago USA_LA 12 14',
    'AUS_Sydney USA_Chicago 19 15',
    'AUS_Sydney USA_Chicago 22 21',
    'CHI_Hong-Kong RSA_Joburg 72 23',
    'USA_LA USA_Chicago 93 27'
);

tie my %hash, 'Hash::MultiKey';
for my $line (@input) {
    my ($c1, $c2, $n1, $n2) = split / [\s\|]+ /x, $line;
    my %map = ($c1 => $n1, $c2 => $n2);
    push @{ $hash{[sort keys %map]} }, @map{sort keys %map};

}
__END__
(
    ['CHI_Hong-Kong', 'RSA_Joburg'] => [72, 23],
    ['AUS_Sydney', 'USA_Chicago'] => [19, 15, 22, 21],
    ['USA_Chicago', 'USA_LA'] => [12, 14, 27, 93],
)
于 2013-08-03T23:48:35.037 回答
0

Perl 非常适合创建复杂的数据结构,但学习有效地使用它们需要实践。

尝试:

#!/usr/bin/env perl

use strict;
use warnings;

# --------------------------------------

use charnames qw( :full :short   );
use English   qw( -no_match_vars );  # Avoids regex performance penalty

use Data::Dumper;

# Make Data::Dumper pretty
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Indent   = 1;

# Set maximum depth for Data::Dumper, zero means unlimited
local $Data::Dumper::Maxdepth = 0;

# conditional compile DEBUGging statements
# See http://lookatperl.blogspot.ca/2013/07/a-look-at-conditional-compiling-of.html
use constant DEBUG => $ENV{DEBUG};

# --------------------------------------

# skip the column headers
<DATA>;

my %bidirectional = ();

while( my $line = <DATA> ){
  chomp $line;

  my ( $country1, $country2, $number1, $number2 ) = split ' ', $line;

  push @{ $bidirectional{ $country1 }{ $country2 } }, [ $number1, $number2 ];
  push @{ $bidirectional{ $country2 }{ $country1 } }, [ $number1, $number2 ];

}

print Dumper \%bidirectional;


__DATA__
Country1        Country2           number1           number2
USA_Chicago     USA_LA             12                14
AUS_Sydney      USA_Chicago        19                15
AUS_Sydney      USA_Chicago        22                21
CHI_Hong-Kong   RSA_Joburg         72                23
USA_LA          USA_Chicago        93                27
于 2013-08-04T12:44:53.177 回答