wdebeaumの答えは、以下のものではなく、使用するソリューションですが、私はそれを行うことで何かを学びました。おそらく他の誰かもそうするでしょう。私が自分のものを書いた後、数千の要素のリストでテストすることにしました。
b.pl:
#!/usr/bin/perl
use strict;
use warnings;
my @itemlist = <>;
for(@itemlist) { chomp; }
my $regex;
if(defined $ENV{wdebeaum}) {
# wdebeaum's solution
my $alternation = join('|', map(quotemeta, @itemlist));
$regex = qr/(?:$alternation).|.(?:$alternation)/;
} else {
# my solution
$regex = join "|", map {qq{(?:\Q$_\E.)|(?:.\Q$_\E)}} @itemlist;
}
my @result = grep !/$regex/, @itemlist;
print scalar @itemlist, "\t", scalar @result, "\n";
5000 のランダムな単語のリストを生成しました。
sort -R /usr/share/dict/american-english|head -5000 > some-words
小さなリストの場合、両方のソリューションがうまくいくようです。
$ time head -200 some-words | wdebeaum=1 ./b.pl
200 198
real 0m0.012s
user 0m0.004s
sys 0m0.004s
$ time head -200 some-words | ./b.pl
200 198
real 0m0.068s
user 0m0.060s
sys 0m0.004s
しかし、より大きなリストの場合は、wdebeum の方が明らかに優れています。
$ time cat some-words | wdebeaum=1 ./b.pl
5000 1947
real 0m0.068s
user 0m0.064s
sys 0m0.000s
$ time cat some-words | ./b.pl
5000 1947
real 0m8.305s
user 0m8.277s
sys 0m0.012s
違いの理由は、両方の正規表現に同じ数の可能なパスがあるにもかかわらず、.
wdebebaum には 2 つしかないのに対し、正規表現にはパスと同じ数の sがあるため、試行する必要があるより多くのパスがあるためだと思います.