404 Blog Not Found:perl - 配列の∪と∩に想定内の返事が。
2010-05-01 - methaneの日記一方、Pythonはsetの演算子を定義した。
もちろんPerlでも定義できます。
以下、実例。
#!/usr/bin/perl use strict; use warnings; package Set; sub main::set { __PACKAGE__->new(@_) } # exportの代わり use overload ( '@{}' => \&array_ref, '""' => \&string, '|' => \&union, '&' => \&intersection, '-' => \&difference, '^' => \&symmetric_difference, '<=' => \&issubset, '>=' => \&issuperset, ); sub new { my $class = shift; my %self = map { $_ => 1 } @_; bless \%self, $class; } sub copy { bless { %{ $_[0] } }, __PACKAGE__ } sub array { keys %{ $_[0] } } sub array_ref { [ shift->array ] } sub string { 'set(' . join( ", ", sort shift->array ) . ')' } sub len { 0 + @{ $_[0] } } sub union { bless { %{ $_[0] }, %{ $_[1] } }, __PACKAGE__; } sub intersection { my %result; $_[0]->{$_} && $result{$_}++ for $_[1]->array; bless \%result, __PACKAGE__; } sub difference { my %result = %{ $_[0] }; delete @result{ $_[1]->array }; bless \%result, __PACKAGE__; } sub symmetric_difference { ( $_[0] | $_[1] ) - ( $_[0] & $_[1] ); } sub issubset { $_[1]->{$_} or return for $_[0]->array; return 1; } sub issuperset { $_[1]->issubset( $_[0] ) } package main; local ( $,, $\ ) = ( ", ", "\n" ); # to prettyprint my $a = set( 1, 2, 3, 4 ); my $b = set( 3, 4, 5, 6 ); print $a; print $b; print $a->len; print $a | $b; print $a & $b; print $a - $b; print $a ^ $b; print( ( $a <= $b ) ? "true" : "false" ); print( ( $a & $b ) <= $a ? "true" : "false" ); print( ( $a | $b ) >= $a ? "true" : "false" );
とりあえず
にある演算子は、in
を除き全て実装してあります。Hashで実装しているので、x in set
相当は$set->{$x}
で出来ます。
ArrayでなくHashで実装したおかげでunion
やdifference
の実装が面白いことになってます。overloadの実習として適度な車輪の再発明でしょう。
ちょっと残念なのが、( $a & $b ) <= $a
としないと演算子の優先順位の関係で()が必要なこと。上の例ではpythonにあわせたのですが、&|
ではなく*+
をつかった方が良かったかも
再発明がいやな人には、Set::Arrayというモジュールが既に存在します。
Dan the (Perl Monger|Occasional Pythonista)
このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。