dax*_*xim 6 perl functional-programming
给定,将数组切成p大小≥1的部分:
my @a = 'A'..'F';
# p = 1
my @p1 = [@a];
# ["A" .. "F"]
# p = 2
my @p2;
for my $x (0..@a-2) {
push @p2, [
[@a[0..$x]],
[@a[$x+1..@a-1]],
];
}
# [["A"], ["B" .. "F"]],
# [["A", "B"], ["C" .. "F"]],
# [["A", "B", "C"], ["D", "E", "F"]],
# [["A" .. "D"], ["E", "F"]],
# [["A" .. "E"], ["F"]],
# p = 3
my @p3;
for my $x (0..@a-3) {
for my $y ($x+1..@a-2) {
push @p3, [
[@a[0..$x]],
[@a[$x+1..$y]],
[@a[$y+1..@a-1]],
];
}
}
# [["A"], ["B"], ["C" .. "F"]],
# [["A"], ["B", "C"], ["D", "E", "F"]],
# [["A"], ["B", "C", "D"], ["E", "F"]],
# [["A"], ["B" .. "E"], ["F"]],
# [["A", "B"], ["C"], ["D", "E", "F"]],
# [["A", "B"], ["C", "D"], ["E", "F"]],
# [["A", "B"], ["C", "D", "E"], ["F"]],
# [["A", "B", "C"], ["D"], ["E", "F"]],
# [["A", "B", "C"], ["D", "E"], ["F"]],
# [["A" .. "D"], ["E"], ["F"]],
# p = 4
my @p4;
for my $x (0..@a-4) {
for my $y ($x+1..@a-3) {
for my $z ($y+1..@a-2) {
push @p4, [
[@a[0..$x]],
[@a[$x+1..$y]],
[@a[$y+1..$z]],
[@a[$z+1..@a-1]],
];
}
}
}
# [["A"], ["B"], ["C"], ["D", "E", "F"]],
# [["A"], ["B"], ["C", "D"], ["E", "F"]],
# [["A"], ["B"], ["C", "D", "E"], ["F"]],
# [["A"], ["B", "C"], ["D"], ["E", "F"]],
# [["A"], ["B", "C"], ["D", "E"], ["F"]],
# [["A"], ["B", "C", "D"], ["E"], ["F"]],
# [["A", "B"], ["C"], ["D"], ["E", "F"]],
# [["A", "B"], ["C"], ["D", "E"], ["F"]],
# [["A", "B"], ["C", "D"], ["E"], ["F"]],
# [["A", "B", "C"], ["D"], ["E"], ["F"]],
Run Code Online (Sandbox Code Playgroud)
如何抽出越来越多的嵌套循环将其转换为子slices(Int $p, Array @a)?我想我需要某种更高阶foreach.
您可能会寻找递归解决方案?
对于p = 1 slices,仅返回所有项目。对于p > 1,它获取前n个项目,并针对每个 1 <= n < 项目数连接p - 1的项目。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dump qw(dump);
my @a = 'A' .. 'F';
for (my $i = 1; $i <= 4; $i++) {
warn("p = $i\n");
dump(slices($i, @a));
};
sub slices
{
my $p = shift();
my @a = @_;
my @ret;
if ($p == 1) {
push(@ret, [[@a]]);
}
else {
for (my $i = 0; $i < $#a; $i++) {
foreach (slices($p - 1, @a[($i + 1) .. $#a])) {
push(@ret, [([@a[0 .. $i]], @{$_})]);
}
# or shorter:
#push(@ret, map({[([@a[0 .. $i]], @{$_})]} slices($p - 1, @a[($i + 1) .. $#a])));
}
}
return @ret;
}
Run Code Online (Sandbox Code Playgroud)
输出:
Run Code Online (Sandbox Code Playgroud)p = 1 [["A" .. "F"]] p = 2 ( [["A"], ["B" .. "F"]], [["A", "B"], ["C" .. "F"]], [["A", "B", "C"], ["D", "E", "F"]], [["A" .. "D"], ["E", "F"]], [["A" .. "E"], ["F"]], ) p = 3 ( [["A"], ["B"], ["C" .. "F"]], [["A"], ["B", "C"], ["D", "E", "F"]], [["A"], ["B", "C", "D"], ["E", "F"]], [["A"], ["B" .. "E"], ["F"]], [["A", "B"], ["C"], ["D", "E", "F"]], [["A", "B"], ["C", "D"], ["E", "F"]], [["A", "B"], ["C", "D", "E"], ["F"]], [["A", "B", "C"], ["D"], ["E", "F"]], [["A", "B", "C"], ["D", "E"], ["F"]], [["A" .. "D"], ["E"], ["F"]], ) p = 4 ( [["A"], ["B"], ["C"], ["D", "E", "F"]], [["A"], ["B"], ["C", "D"], ["E", "F"]], [["A"], ["B"], ["C", "D", "E"], ["F"]], [["A"], ["B", "C"], ["D"], ["E", "F"]], [["A"], ["B", "C"], ["D", "E"], ["F"]], [["A"], ["B", "C", "D"], ["E"], ["F"]], [["A", "B"], ["C"], ["D"], ["E", "F"]], [["A", "B"], ["C"], ["D", "E"], ["F"]], [["A", "B"], ["C", "D"], ["E"], ["F"]], [["A", "B", "C"], ["D"], ["E"], ["F"]], )
(可能需要一些调整。比如检查 1 <= p <= 项目数。)
| 归档时间: |
|
| 查看次数: |
122 次 |
| 最近记录: |