下面的代码是一种试图解决众所周知的子集和问题的算法。有人给了我这段代码,我对其进行了一些调整和调整,使其可以在Perl中正常运行(上面的代码将运行)。此处,“ a”是一组整数,“ b”是总和,程序尝试查找总和为“ b”的“ a”的子集,然后在最后打印结果。但是,当索引“ a”(集合中的整数数)相对较大(大约200)时,程序将无法打印总和为“ b”的所有“ a”子集。我知道这一点是因为我有意选择了一个子集“ a”,该子集总和也等于一个整数“ b”。该程序无法打印“ a”的任何子集(尽管很明显至少存在一个)。认为这是某种程度的溢出,所以我尝试了输出文件目录,然后再次检查文件,却什么也没发现。有任何想法吗?
sub Solve
{
my ($goal, $elements) = @_;
# For extra speed, you can remove this next line
my (@results, $RecursiveSolve, $nextValue);
$RecursiveSolve = sub {
my ($currentGoal, $included, $index) = @_;
for ( ; $index < @$elements; ++$index) {
$nextValue = $elements->[$index];
# Since elements are sorted, there's no point in trying a
# non-final element unless it's less than goal/2:
if ($currentGoal > 2 * $nextValue) {
$RecursiveSolve->($currentGoal - $nextValue,
[ @$included, $nextValue ],
$index + 1);
} else {
push @results, [ @$included, $nextValue ]
if $currentGoal == $nextValue;
return if $nextValue >= $currentGoal;
}
} # end for
}; # end $RecursiveSolve
$RecursiveSolve->($goal, [], 0);
undef $RecursiveSolve; # Avoid memory leak from circular reference
return @results;
} # end Solve
my @results = Solve(b, [a]
);
print "@$_\n" for @results;
举个例子,我去random.org并生成了一个从1到2000的200个随机整数的集合“ a”,取了这些200个随机整数中的4个,并创建了一个总和“ b”。然后代码如下所示:
sub Solve
{
my ($goal, $elements) = @_;
# For extra speed, you can remove this next line
my (@results, $RecursiveSolve, $nextValue);
$RecursiveSolve = sub {
my ($currentGoal, $included, $index) = @_;
for ( ; $index < @$elements; ++$index) {
$nextValue = $elements->[$index];
# Since elements are sorted, there's no point in trying a
# non-final element unless it's less than goal/2:
if ($currentGoal > 2 * $nextValue) {
$RecursiveSolve->($currentGoal - $nextValue,
[ @$included, $nextValue ],
$index + 1);
} else {
push @results, [ @$included, $nextValue ]
if $currentGoal == $nextValue;
return if $nextValue >= $currentGoal;
}
} # end for
}; # end $RecursiveSolve
$RecursiveSolve->($goal, [], 0);
undef $RecursiveSolve; # Avoid memory leak from circular reference
return @results;
} # end Solve
my @results = Solve(4022, [34, 63, 83, 86, 88, 90, 95, 105, 107, 115, 120, 132, 140, 145, 146, 149, 154, 165, 167, 173, 175, 197, 199, 250, 267, 289, 291, 306, 328, 341, 344, 347, 349, 355, 370, 379, 389, 390, 393, 409, 430, 454, 474, 475, 476, 483, 488, 518, 522, 544, 554, 571, 582, 587, 591, 606, 614, 615, 639, 647, 663, 673, 679, 703, 742, 754, 765, 791, 803, 816, 819, 829, 841, 848, 852, 858, 861, 865, 870, 872, 873, 903, 909, 914, 915, 918, 931, 934, 937, 947, 970, 974, 983, 986, 1008, 1013, 1018, 1019, 1071, 1074, 1093, 1095, 1097, 1101, 1104, 1115, 1118, 1122, 1143, 1154, 1163, 1165, 1166, 1173, 1174, 1175, 1177, 1182, 1188, 1192, 1195, 1196, 1248, 1259, 1270, 1277, 1285, 1296, 1306, 1312, 1314, 1317, 1319, 1325, 1326, 1333, 1341, 1346, 1355, 1372, 1393, 1394, 1402, 1404, 1407, 1412, 1425, 1426, 1432, 1433, 1436, 1437, 1452, 1454, 1489, 1498, 1504, 1505, 1515, 1521, 1525, 1542, 1556, 1569, 1591, 1592, 1599, 1622, 1624, 1658, 1680, 1685, 1686, 1696, 1725, 1738, 1757, 1768, 1776, 1781, 1782, 1807, 1815, 1820, 1853, 1866, 1868, 1882, 1888, 1891, 1895, 1909, 1911, 1924, 1942, 1946, 1975, 1983, 1988, 1997]
);
print "@$_\n" for @results;
有一个明显的“ a”子集,其总和为“ b = 4022”:[389,1071,1248,1314],但是运行代码(已固定集“ a”)在命令上不显示任何内容行,输出文件中也没有任何内容。同样,这可能是内存问题,我不确定该如何解决。