hhayakawaの日記: Perl: 再帰的for文
日記 by
hhayakawa
ループの深さを変数によって変えたい。
再帰関数を使えば、そんなこともできます。
(一緒に考えてくださった方々、ありがとうございました。)
# &rec_for(\&func, \@count, $depth);
# \&func : 実行したい関数へのポインタ
# \@count : ループの変数に格納する値のリスト
# $depth : ループの入れ子の深さ-1 (0で1重ループ,1で2重ループ)
#
# &funcが入れ子のループの変数の配列を引数として実行される
sub rec_for {
my $func_ = shift;
my $count_ = shift;
my $depth = shift;
my @arg = @_;
for my $i(@{$count_}) {
my (@tmp) = (@arg, $i);
if ($depth) {
&rec_for($func_, $count_, $depth-1, @tmp);
} else {
&{$func_}(@tmp);
}
}
}
# 実行したい関数
sub func {
my @arg = @_;
printf("%5d: %s\n", $GLOBAL_COUNT++, join("", @arg));
}
my @count = qw!0 1 2 3 4 5 6 7 8 9 A B C D E F!;
my $GLOBAL_COUNT = 0;
my $depth = 3 -1; # 3重ループ
&rec_for(\&func, \@count, $depth);
# 同じことを別の書き方をすると次のようになる
my @arg;
for $arg[0](@count) {
for $arg[1](@count) {
for $arg[2](@count) {
&func(@arg);
}
}
}
再帰関数を使えば、そんなこともできます。
(一緒に考えてくださった方々、ありがとうございました。)
# &rec_for(\&func, \@count, $depth);
# \&func : 実行したい関数へのポインタ
# \@count : ループの変数に格納する値のリスト
# $depth : ループの入れ子の深さ-1 (0で1重ループ,1で2重ループ)
#
# &funcが入れ子のループの変数の配列を引数として実行される
sub rec_for {
my $func_ = shift;
my $count_ = shift;
my $depth = shift;
my @arg = @_;
for my $i(@{$count_}) {
my (@tmp) = (@arg, $i);
if ($depth) {
&rec_for($func_, $count_, $depth-1, @tmp);
} else {
&{$func_}(@tmp);
}
}
}
# 実行したい関数
sub func {
my @arg = @_;
printf("%5d: %s\n", $GLOBAL_COUNT++, join("", @arg));
}
my @count = qw!0 1 2 3 4 5 6 7 8 9 A B C D E F!;
my $GLOBAL_COUNT = 0;
my $depth = 3 -1; # 3重ループ
&rec_for(\&func, \@count, $depth);
# 同じことを別の書き方をすると次のようになる
my @arg;
for $arg[0](@count) {
for $arg[1](@count) {
for $arg[2](@count) {
&func(@arg);
}
}
}
Perl: 再帰的for文 More ログイン