$returnintersection が true の場合、任意の 2 つの入力リストに対して交差のようなリストを返す次の perl コードを書きました。それ以外の場合は、いずれか 1 つの共通要素を返し、何もない場合は 0 を返します。
交差点のように、私はワイルドカードの一致を参照しています.1つのリストからの123 *は、他のリストからの12345と一致します。
入力と対応する出力の例を次に示します。
getintersection (
['123*', '999', 'V890', '871'],
['10001', '8789', '999', '1234', 'V89*'],
1
)
will return
('999', 'V890', '1234')
パフォーマンスが向上する方法で記述できるかどうか知りたいですか?私はアルゴリズムがそこにある最高のものではないと確信しています。その複雑さを軽減するのに役立つものは何でも高く評価されます! 非常に一般的に呼ばれるルーチンであるため、そのパフォーマンスは非常に重要です。(パフォーマンス => 速度、いずれかのリストに 1 ~ 3000 の要素を含めることができると仮定)
コード -
sub getintersection {
my ($l1, $l2, $returnintersection) = @_;
if (!$l1 || !$l2) {
return $returnintersection ? undef : 0;
}
my ($small, $large);
if (scalar @$l1 > scalar @$l2 ) {
($small, $large) = ($l2, $l1);
}
else {
($small, $large) = ($l1, $l2);
}
my (%lhash, %l_starred, %s_starred, @intersection);
foreach my $l (@$large) {
$lhash{$l} = 1;
if ($l =~ m/^(.+)\*$/) {
$l_starred{$1} = 1;
}
}
foreach my $s (@$small) {
if ($lhash{$s}) {
return $s if (!$returnintersection);
push @intersection, $s;
}
else {
foreach my $k (keys %l_starred) {
if ($s =~ /^$k/) {
return $s if (!$returnintersection);
push @intersection, $s;
}
}
}
if ($s =~ m/^(.+)\*$/) {
$s_starred{$s} = 1;
}
}
foreach my $s (keys %s_starred) {
foreach my $l (@$large) {
if ($l =~ /^$s/) {
return $l if (!$returnintersection);
push @intersection, $l;
}
}
}
return $returnintersection ? @intersection : scalar @intersection;
}