[92.0,81.0,81.0,41.0,69.0,95.0,82.0,25.0,92.0,18.0,60.0,68.0,29.0,75.0,87.0,24.0,99.0,93.0,76.0,49.0,36.0]
测试列表在
之上基本上我给了一个数字列表,我要提取三个组,然后应用一个函数来得到我的答案。我不能使用导入或递归。
“获取双打列表,将每个连续的三个双打组视为三角形三边的长度,使用triangle_area计算其面积;并且在处理列表中的所有双打后,将所有计算的区域返回为双打名单。“
triangle_area :: Double -> Double -> Double -> Double
triangle_area a b c = sqrt (s * (s - a) * (s - b) * (s - c)) where s = (a + b + c) / 2.0
triangle_areas :: [Double] -> [Double]
triangle_areas xs = []
我打算在该列表上使用过滤器,但不能使用双打。在给定列表中,三个集合表示triangle_area函数的(a,b,c)。然后我需要将triangle_area函数应用于这些数字。
不确定如何做到这一点
所以给出[92.0,81.0,81.0,41.0,69.0,95.0,82.0,25.0,92.0,18.0,60.0,68.0,29.0,75.0,87.0,24.0,99.0,93.0,76.0,49.0,36.0]
上面列表之后的区域应该是 [3066.9,1258.5,986.4,510.9,1052.0,1106.7,712.6]
这是另一种尝试 但它不起作用
triangle_area :: Double -> Double -> Double -> Double
triangle_area a b c = sqrt (s * (s - a) * (s - b) * (s - c)) where s = (a + b + c) / 2.0
splitEvery :: Int -> [a] -> [[a]]
splitEvery n = takeWhile (not.null) . map (take n) . iterate (drop n)
triangle_areas :: [Double] -> [Double]
triangle_areas [] = []
triangle_areas (a:b:c:xs) = triangle_area a b c : triangle_areas xs
基本上我想做splitEvery 3 [1..9],然后在那些分解列表中使用triangle_area。
triangle_areas 目前效果很好,但我无法使用递归,所以我需要返工。
WORKING
splitEvery :: Int -> [a] -> [[a]]
splitEvery n = takeWhile (not.null) . map (take n) . iterate (drop n)
triangle_area [a,b,c] = sqrt (s * (s - a) * (s - b) * (s - c))
where s = (a + b + c) / 2.0
triangle_areas = map triangle_area . splitEvery 3
非常感谢切普纳
答案 0 :(得分:3)
您可以使用map
的定义来获取灵感。
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
map
将其函数应用于一个参数;你想将你的函数应用于三个参数。
triangle_areas :: [Double] -> [Double]
triangle_areas xs = map3 triangle_area xs
where map3 f (s1:s2:s3:rest) = f s1 s2 s3 : map3 f rest
-- map3 _ [s1, s2] = ???
-- map3 _ [s1] = ???
map3 _ [] = []
我将map3
作为部分函数,对于剩下1或2个值的列表,它是未定义的。
您的splitEvery
没问题;您只需要修改triangle_area
的定义,以便它可以将3元素列表作为输入。
triangle_area [a,b,c] = sqrt (s * (s - a) * (s - b) * (s - c))
where s = (a + b + c) / 2.0
现在,您可以将其映射到splitEvery
的输出。
triangle_areas = map triangle_area . splitEvery 3
答案 1 :(得分:0)
以下不是最优雅的,但可以作为灵感(至少它适用于你的例子):
triangle_areas :: [Double] -> [Double]
triangle_areas =
fst .
foldl (\(r, sides) x ->
if length sides == 2
then (r ++ [triangle_area (sides !! 0) (sides !! 1) x], [])
else (r, sides ++ [x]))
([],[])
它的工作原理是累积计算出的面积和当前三角形的边,其面积将在下一个计算。这是在元组(r, sides)
中完成的。当我们得到三角形的三个边(在列表sides
中累积2个,在参数x
中累积第三个)时,我们
计算区域并将其添加到结果列表中,否则我们保持结果列表不变并将当前侧(参数x
)添加到sides
。