考虑这些数据:
12 45 64
12 45 76
12 37 39 87
12 67 90
12 39 60
在这个例子中,只有十个不同的数字。如果我有大量数据,我如何在Perl中计算它?
我有一个从12到45的链接,从45到64,但不是从12到64。
我们没有从45到12的路线,所以12的邻域是4(45,37,67,39),39是2(87,60)
如何计算此数据中所有值的邻域?
修改
另一个要求是我们要忽略任何指向自身的值。例如,考虑我们有这个文件:
1 4 3
1 2 2
2 6 7
在此示例中,邻域1必须为(4,2)
4附近必须是3
2的邻域必须是6(而不是2)
我的意思是我们必须删除匹配和重复。
答案 0 :(得分:3)
my $data = <<'END_DATA';
12 45 64
12 45 76
12 37 39 87
12 67 90
12 39 60
END_DATA
my @lines = split/\n+/, $data;
# map number the list of numbers following it in the sequence
my %neighborhoods = ();
for my $line ( @lines ) {
my @nums = split m/\s+/,$line;
for my $i ( 0 .. $#nums - 1 ) {
$neighborhoods{$nums[$i]}{$nums[$i+1]} = 1;
}
}
foreach my $num ( sort keys %neighborhoods ) {
print "num [$num] neighboorhood (" .
( join "-", keys %{$neighborhoods{$num}} ) .
") count [" . ( scalar keys %{$neighborhoods{$num}} ) .
"]\n";
}
输出:
num [12] neighboorhood (67-39-37-45) count [4]
num [37] neighboorhood (39) count [1]
num [39] neighboorhood (60-87) count [2]
num [45] neighboorhood (64-76) count [2]
num [67] neighboorhood (90) count [1]
答案 1 :(得分:3)
如果我理解正确,您需要计算图表上每个节点附近的节点数。我认为这样做你想要的。
我修改了我的代码,因为你已经解释过应该忽略从节点到自身的向量。
use v5.10;
use warnings;
my %routes;
while (<DATA>) {
my @nodes = /\d+/g;
$routes{$_} //= {} for @nodes;
while (@nodes >= 2) {
my ($from, $to) = @nodes;
$routes{$from}{$to}++ unless $from == $to;
shift @nodes;
}
}
for my $key (sort { $a <=> $b } keys %routes) {
my $val = $routes{$key};
printf "%d - neighbourhood size %d",
$key,
scalar keys %$val;
printf " (%s)", join ', ', keys %$val if %$val;
print "\n";
}
__DATA__
12 45 64
12 45 76
12 37 39 87
12 67 90
12 39 60
1 4 3
1 2 2
2 6 7
<强>输出强>
1 - neighbourhood size 2 (4, 2)
2 - neighbourhood size 1 (6)
3 - neighbourhood size 0
4 - neighbourhood size 1 (3)
6 - neighbourhood size 1 (7)
7 - neighbourhood size 0
12 - neighbourhood size 4 (67, 39, 37, 45)
37 - neighbourhood size 1 (39)
39 - neighbourhood size 2 (60, 87)
45 - neighbourhood size 2 (64, 76)
60 - neighbourhood size 0
64 - neighbourhood size 0
67 - neighbourhood size 1 (90)
76 - neighbourhood size 0
87 - neighbourhood size 0
90 - neighbourhood size 0
答案 2 :(得分:3)
使用Graph::Directed
模块:
use Graph::Directed qw( );
my $graph = Graph::Directed->new();
while (<>) {
my @points = split;
$graph->add_edge(@points[$_-1, $_])
for 1..$#points;
}
for my $vertex ($graph->vertices()) {
my @successors = grep $_ != $vertex, $graph->successors($vertex);
print("$vertex has ".@successors." successors: @successors\n");
}
输入:
1 4 3
1 2 2
2 6 7
输出:
6 has 1 successors: 7
4 has 1 successors: 3
2 has 1 successors: 6
1 has 2 successors: 4 2
3 has 0 successors:
7 has 0 successors:
答案 3 :(得分:0)
这是另一种选择:
use strict;
use warnings;
my ( %hash, %seen );
while (<DATA>) {
my @nums = split;
for my $i ( 0 .. $#nums - 1 ) {
push @{ $hash{ $nums[$i] } }, $nums[ $i + 1 ]
if !$seen{ $nums[$i] }{ $nums[ $i + 1 ] }++;
}
}
for my $num ( sort { $a <=> $b } keys %hash ) {
print "$num has " . @{ $hash{$num} } . " neighbor(s): @{$hash{$num}}\n";
}
__DATA__
12 45 64
12 45 76
12 37 39 87
12 67 90
12 39 60
输出:
12 has 4 neighbor(s): 45 37 67 39
37 has 1 neighbor(s): 39
39 has 2 neighbor(s): 87 60
45 has 2 neighbor(s): 64 76
67 has 1 neighbor(s): 90