我有一个函数的下面开始,我不确定,我怎么应该回到中间的数字(即既不是最大也不是最小号):如何在Haskell
middleNumber :: Int -> Int -> Int -> Int
middleNumber a b c
| ...
我有一个函数的下面开始,我不确定,我怎么应该回到中间的数字(即既不是最大也不是最小号):如何在Haskell
middleNumber :: Int -> Int -> Int -> Int
middleNumber a b c
| ...
我建议你将功能分为两步:首先,对三个数字进行排序。然后,采取中间元素。对于第一步,还要考虑是否可以一次完成一步;每一步都会使它更接近于完全排序,然后再递回以使它更接近。
“中间数字”大于其中一个数字,但小于另一个数字。而且只有一个中间数字。要解决这个最机械的方法是开始
middleNumber a b c
| a < b && a > c = a
检查a
是小于b
但大于c
中间的数字。
现在,如果a
是中间的数字,但它实际上比和b
更大比少c
?还有另一名警卫。如果b
是中间数字呢?还有另外两名警卫。如果c
是中间数字呢?总共有6种不同的情况,还有2名警卫。
(顺便说一句,表达| a < b && a > c = a
被称为保护。如果你没有牢牢把握又是什么警卫,那么我建议LYAH # Guards)
当然也有更好的方法来写功能,但出于理解的目的,能够手动和系统地分解所有可能的情况并确定在每种情况下应该做什么是很好的。 How To Design Programs是学习如何以这种方式进行系统化的好书。
强制性的Rube - 戈德堡回答:
import Control.Applicative
middleNumber a b c = sum $ [sum, negate.minimum, negate.maximum] <*> [[a,b,c]]
[编辑]
这里是另一个版本:
middleNumber a b c = fst $ maximumBy (compare `on` abs.snd) [(a,b-c),(b,c-a),(c,a-b)]
我敢肯定,我们可以把这种箭头语法进一步混淆,但是我把这个任务留给了感兴趣的读者。
我做了一个快速蛮力方法,但是这是肯定不是最好的解决
import Data.List
middleNum :: Int -> Int -> Int -> Int
middleNum a b c = (\[_,m,_] -> m) $ sort $ a:b:c:[]
显然,这是一个可怕的想法,因为它明确地依赖于那里是列表中的3项,但它做的工作
谢谢,我会给一个去:) – maclunian 2011-05-24 20:56:46