抱歉回复晚了,我一直在修改这个问题,因为我不想再得到负面评分(让我感到沮丧)。
这是一个有趣的效率问题。我不知道我的解决方案是否适用于您,但我想分享一下。如果您的数组不经常更改,并且您的数组包含许多重复值,则可能仅在效率上有效。我没有对其进行任何效率检查。
基本上,解决方案是通过将数组值转换为位并在一次操作中对整个数组进行按位比较来删除交叉检查的一个维度。数组值被去重、排序并赋予序列号。然后通过按位或将数组的总序列号存储在单个值中。因此,可以使用一个操作仅检查单个序列号的单个数组,例如:
if ( array & serialno )
需要运行一次以准备数据,然后可以将其保存在缓存或类似位置。然后可以使用此数据,直到您的数据发生更改(例如删除或添加文件/文件夹)。我已经在未定义值上添加了致命退出,这意味着当它发生时必须刷新数据。
祝你好运!
use strict;
use warnings;
my @list1=('a', 'b', 'c');
my @list2=('a', 'b', 'f');
my @list3=('e', 'd', 'a');
my @list4=('f', 'g', 'h');
my @total = (@list1, @list2, @list3, @list4);
my %unique = ();
foreach my $item (@total)
{
$unique{$item} ++;
}
@total = sort keys %unique;
my %serials = ();
for (my $num = 0; $num <= $#total; $num++)
{
$serials{$total[$num]} = $num;
}
my @tx = ();
for my $entry (@list1) { $tx[0] |= 2**$serials{$entry}; }
for my $entry (@list2) { $tx[1] |= 2**$serials{$entry}; }
for my $entry (@list3) { $tx[2] |= 2**$serials{$entry}; }
for my $entry (@list4) { $tx[3] |= 2**$serials{$entry}; }
&print_all;
sub inList
{
my ($value, $list) = @_;
if (! defined ($serials{$value}) ) {
print "$value is not in the predefined list.\n";
exit;
}
return ( 2**$serials{$value} & $tx[$list] );
}
sub yesno
{
my ($value, $list) = @_;
return ( &inList($value, $list) ? "yes":"no" );
}
sub print_all
{
printf "%-6s %-6s %-6s %-6s %-6s\n", "", "List1", "List2", "List3", "List4";
print "-" x 33, "\n";
&table_print(@list1);
&table_print(@list2);
&table_print(@list3);
&table_print(@list4);
}
sub table_print
{
my @list = @_;
for my $entry (@list) {
printf "%-6s %-6s %-6s %-6s %-6s\n", $entry,
&yesno($entry, 0),
&yesno($entry, 1),
&yesno($entry, 2),
&yesno($entry, 3);
}
print "-" x 33, "\n";
}