我必须在具有此函数定义f :: [Int] -> Int
的列表中计算每个连续对的差异之间的乘积,例如:
f [3, 1, 4, 2, 5] = (3 - 1) * (1 - 4) * (4 - 2) * (2 - 5)
= 36
我必须递归地执行此操作,我知道如何处理数组中元素的产品,但是如何从列表中选择元组并将它们的差异乘以下一个元组的差异,任何提示都将受到赞赏。到目前为止,我有这个:
f :: [Int] -> Int
f [] = 1
f (x:xs) = x * f xs
但这只给了我元素的产物。
答案 0 :(得分:5)
使用对
创建中间结构a = [3, 1, 4, 2, 5]
zip a (tail a)
或更好地使用
zipWith (-) a (tail a)
将为您提供差异并继续使用该产品。
如果需要实现自己的递归解决方案,则需要逐个使用输入元素。基本情况应该很容易,您必须考虑null情况和单个元素的情况(可能是相同的!)
附加提示,为此基本案例编写函数
f (x:y:xs) = (x-y) * f ???
和这个终端案例(如果行为相同,可能会合并)。
f [] = ???
f [x] = ???
答案 1 :(得分:2)
怎么样:
import Data.List
f l = product [a-b | (a:b:_) <- tails l ]
该函数的工作方式如下:tails
生成 - 顾名思义 - 给定列表l
的所有尾部,因此对于[3, 1, 4, 2, 5]
,[[3,1,4,2,5],[1,4,2,5],[4,2,5],[2,5],[5],[]]
(a:b:_)
}。现在我们使用a
进行模式匹配,这意味着只会考虑包含至少两个项目的列表,此外前两个元素将与b
和a-b
统一。现在我们使用[3,1,4,2,5]
生成一个新列表。因此[2,-3,2,-3]
的列表为f
。现在你只需拿走产品。
修改强>
Num a => [a] -> a
的签名是[Int] -> Int
,比import Data.List
f :: [Int] -> Int
f l = product [a-b | (a:b:_) <- tails l ]
更通用。因此,您可以简单地通过以下方式向下转发:
FOO='Hi" a/b/c:'
BAR='hello'
if [ "$FOO" == "$BAR" ] ; then
echo "yes"
fi
答案 2 :(得分:2)
注意:这篇文章是用literate Haskell写的。您可以将其保存为ListProduct.lhs并在GHCi中尝试。
为了修复你的功能,我们必须考虑一些情况。首先,如果列表为空,会发生什么?我们返回1
:
> f :: [Int] -> Int
> f [] = 1
现在,我们必须考虑具有更多元素的列表。例如,列表可以包含至少一个元素:
f (x:xs) = ...
然而,这并不是真的有用。我们需要两个个连续元素,以便相互减去它们。但是,我们可以通过模式再次匹配剩余列表来实现:
f (x : (y : xs))
与f (x : y : xs)
相同,因为(:)
是右关联的。我们最终得到:
> f (x : y : xs) = (x - y) * f rest
其余的是什么?它不能是xs
。如果我们使用xs
,我们就无法在以下情况下获得正确的结果:
f [1,2,3,4] = (1 - 2) * f [3,4]
= (1 - 2) * (3 - 4) * f []
-- ^^^^^^
-- (2 - 3) is missing!
因此rest
需要同时拥有y
和 xs
:
> where rest = y : xs
我们可以确认这是按预期工作的:
f [1,2,3,4] = (1 - 2) * f [2,3,4]
= (1 - 2) * (2 - 3) * f [3,4]
= (1 - 2) * (2 - 3) * (3 - 4) * f [4]
因此,正确处理我们至少有两个元素的情况。
我们只有一个元素的列表怎么样?好吧,有一个元素,你不能减去另一个元素。正如您在上面所看到的那样,我们总会在f [x]
处为某些x
提供f [x] = 1
。因此,明智的选择是f [a] = 1
:
_
但是,由于我们实际上并不关注该元素,因此我们可以将> f _ = 1
用作通配符:
f []
请注意,这与f
的结果相同。所以我们可以将f :: [Int] -> Int
f (x : y : xs) = (x - y) * f (y : xs)
f _ = 1
写成
True
但这取决于你。
length
。请勿使用True
,仅使用模式匹配。编写一个函数,对于包含至少四个元素的列表返回False
,否则返回f [1,2,3,4,5] = (1 * 2 * 3) + (2 * 3 * 4) + (3 * 4 * 5)
。仅使用模式匹配,不使用其他功能。
编写一个返回三连续产品总和的函数,例如
#m1 li {
list-style: none;
display: inline-block;
padding-right: 18px;
padding-left: 18px;
font-size: 18px;
}
#m2 li {
list-style: none;
display: inline-block;
padding-right: 18px;
padding-left: 18px;
font-size: 18px;
}
#m1 {
display: inline-block;
float: left;
}
#m2 {
display: inline-block;
float: left;
}
答案 3 :(得分:0)
虽然这种问题通常更容易拉链,但折叠工作也是如此:
f (x:xs) = fst $ foldl (\(p,n) m -> (p*(n-m),m)) (1,x) xs