这是在 Haskell 中如何做到的:
import Data.List(sortBy, subsequences)
import Data.Function(on)
lowestSumTargetFactor :: (Ord b, Num b) => [b] -> b -> [b]
lowestSumTargetFactor xs target = do
let l = filter (/= []) $ sortBy (compare `on` sum)
[x | x <- subsequences xs, product x == target]
if l == []
then error $ "lowestSumTargetFactor: " ++
"no subsequence product equals target."
else head l
这是发生了什么:
[x | x <- subsequences xs, product x == target] 构建一个由列表xs 的所有子序列组成的列表,其乘积等于target。在您的示例中,它将构建列表[[2,6],[6,2],[2,2,3]]。
然后sortBy (compareonsum) 部分按列表元素的总和对该列表列表进行排序。它将返回列表[[2,2,3],[2,6],[6,2]]。
然后我 filter 该列表,删除任何 [] 元素,因为 product [] 返回 1(还不知道这样做的原因)。这样做是因为 lowestSumTargetFactor [1, 1, 1] 1 将返回 [] 而不是预期的 [1]。
然后我问我们建立的列表是否是[]。如果不是,我使用函数head 返回该列表的第一个元素(在您的情况下为[2,2,3])。如果是,则返回所写的错误。
Obs1:在上面出现的地方,$ 只是表示它后面的所有内容都用括号括起来。
Obs2:lowestSumTargetFactor :: (Ord b, Num b) => [b] -> b -> [b] 部分只是函数的类型签名。这意味着该函数接受一个由bs 组成的列表,第二个参数b 并返回另一个由bs 组成的列表,b 是完全有序数据类型Ord 类的成员,和Num 类,基本的数字类。
Obs3:我还是个初学者。更有经验的程序员可能会更高效、更优雅地完成此操作。