in reply to Computing Subsets
Here's another option using smart matching:
use Modern::Perl; my $a = "AB:APPLE:BOY:ZOO:ZOOM"; my $b = "APPLE:ZOO"; my $c = "BOY:GIRL"; say isSubset( $b, $a ); #Returns 1 say !isSubset( $c, $a ); #Returns 1 sub isSubset { my @small = split ':', $_[0]; my @big = split ':', $_[1]; @small ~~ [ grep $_ ~~ @big, @small ]; }
Update: The subroutine below might be more efficient, since it's not building a list (the results are the same):
sub isSubset { my $count = my @small = split ':', $_[0]; my @big = split ':', $_[1]; do { $count-- when @big } for @small; !$count; }
Here's an interesting read: How fast is Perl's smart match operator for searching scalar in an array?.
UpdateUpdate: Ran a benchmark on three subroutines having different set/subset algorithms:
use Modern::Perl; use Benchmark qw(cmpthese); my $a = "AB:APPLE:BOY:ZOO:ZOOM"; my $b = "APPLE:ZOO"; my $c = "BOY:GIRL"; sub isSubset { my @small = split ':', $_[0]; my @big = split ':', $_[1]; @small ~~ [ grep $_ ~~ @big, @small ]; } sub isSubsetSmarter { my $count = my @small = split ':', $_[0]; my @big = split ':', $_[1]; do { $count-- when @big } for @small; !$count; } sub isSubsetHash { my $count = my @small = split ':', $_[0]; my %big; $big{$_} = 1 for split ':', $_[1]; do { $count-- if $big{$_} } for @small; !$count; } cmpthese( -5, { isSubset => sub { isSubset( $b, $a ) }, isSubsetSmarter => sub { isSubsetSmarter( $b, $a ) }, isSubsetHash => sub { say isSubsetHash( $b, $a ) }, } );
Results:
Rate isSubset isSubsetHash isSubsetSmarter isSubset 143452/s -- -15% -54% isSubsetHash 169263/s 18% -- -45% isSubsetSmarter 309705/s 116% 83% --
The original isSubset is the slowest, but isSubsetSmarter is surprisingly the fastest of the crew--at least with these small data sets.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Computing Subsets
by davido (Cardinal) on May 28, 2012 at 06:05 UTC | |
by Kenosis (Priest) on May 28, 2012 at 06:41 UTC | |
by davido (Cardinal) on May 28, 2012 at 06:56 UTC |