我的文件包含以下条目:
1,2
2,3
4,5
1,3
1,4
5,6
...
这告诉id:第一列与第二列匹配。现在我想找到只有所有组合的所有id组。即需要输出以下内容:
1,2,3
4,5
1,4
5,6
我尝试为解决方案编写一个perl脚本:
while(<STDIN>) {
if(m/^(\d+),(\d+)/) {
$dub{$1}{$2} = 1;
$dub{$2}{$1} = 1;
$hs{$1} = 1;
$hs{$2} = 1;
}
}
$i=0;
foreach $a (keys %dub) {
$grp[$i]{$a} = 1;
foreach $b (keys %{$dub{$a}}) {
$grp[$i]{$b} = 1;
foreach $c (keys %hs) {
if($c == $a || $c == $b) { next; }
$flag = 1;
foreach $d (keys %{$grp[$i]}) {
if(!$dub{$d}{$c}) {
$flag = 0;
last;
}
}
$grp[$i]{$c} = 1 if($flag);
}
$i++;
}
}
for($i=0; $i<=$#grp; $i++) {
print join(",", (keys %{$grp[$i]}))."\n";
}
但这需要花费大量时间来执行。 以上脚本是否有更好的解决方案,算法或性能调整? LAMP中的任何解决方案都值得赞赏。 感谢
编辑:
想一想: (1,2)定义为“1和2相似” (2,3)定义为“2和3相似” (1,4)定义为“1和4相似” (1,3)定义为“1和3相似”
从这些相似之处我得出结论,组(1,2,3)彼此相似但不是组(1,2,3,4)。 为了形成组(1,2,3,4),数据中应该有其他条目如(2,4)和(3,4)。
最后,我想在给定的坐标集中找到所有组。
答案 0 :(得分:0)
这对我有用:
use Data::Dump;
my @results;
my ($last_a, $last_b) = (0,0);
while(<DATA>) {
chomp;
my ($a, $b) = split /,/;
if( $last_b == $a ) {
my $last_item = $results[$#results];
push @$last_item, $b;
}
else {
push @results, [$a, $b];
}
($last_a, $last_b) = ($a, $b);
}
dd @results; # ([1, 2, 3], [4, 5], [1, 3], [1, 4], [5, 6])
__DATA__
1,2
2,3
4,5
1,3
1,4
5,6
答案 1 :(得分:0)
您还没有真正描述过我们应该使用的算法。我无法理解为什么你的输入产生“1,2,3”和“1,4”而不仅仅是“1,2,3,4”。
但这是你想要的吗?
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my %data;
while (<DATA>) {
chomp;
my ($k, $v) = split /,/;
push @{ $data{$k} }, $v;
}
foreach (sort keys %data) {
say "$_,", join ',', @{ $data{$_ } };
}
__DATA__
1,2
2,3
4,5
1,3
1,4
5,6
答案 2 :(得分:0)
根据我的理解,{1,2,3}属于同一组,因为所有人都指向彼此({1,2},{2,3},{1,3}存在)。因此,我们可以将此问题减少到在无向图中找到派系,这是NP完全问题。因此,每种解决方案对大数据的效率都非常低。