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 = []
我打算在这个列表上使用过滤器,但是不适用于doubles.In --给定的列表-- 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目前工作得很好,但是我不能使用递归,所以我需要重新工作。
工作
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
非常感谢切普纳
发布于 2016-11-03 06:56:35
您可以使用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
发布于 2016-11-03 10:04:14
以下不是最优雅的,但可以作为灵感(至少在您的示例中是这样的):
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
中。
https://stackoverflow.com/questions/40403807
复制相似问题