2011-05-24 59 views
2
返回中间数

我有一个函数的下面开始,我不确定,我怎么应该回到中间的数字(即既不是最大也不是最小号):如何在Haskell

middleNumber :: Int -> Int -> Int -> Int 
middleNumber a b c 
    | ... 

回答

4

我建议你将功能分为两步:首先,对三个数字进行排序。然后,采取中间元素。对于第一步,还要考虑是否可以一次完成一步;每一步都会使它更接近于完全排序,然后再递回以使它更接近。

+0

谢谢,我会给一个去:) – maclunian 2011-05-24 20:56:46

2

“中间数字”大于其中一个数字,但小于另一个数字。而且只有一个中间数字。要解决这个最机械的方法是开始

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是学习如何以这种方式进行系统化的好书。

3

强制性的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)] 

我敢肯定,我们可以把这种箭头语法进一步混淆,但是我把这个任务留给了感兴趣的读者。

+1

import Data.List; middleNumber a b c =(排序[a,b,c])!! 1 – 2011-05-24 22:48:50

+0

'letl = [a,b,c] in delete(minimum l)。删除(最大值)$ l' ...- :-) – sclv 2011-05-25 03:41:06

+0

另一个:'中间值a b c =最小值[最大a b,最大a c,最大b c]'(反转也起作用) – sclv 2011-05-25 18:54:17

0

我做了一个快速蛮力方法,但是这是肯定不是最好的解决

import Data.List 
middleNum :: Int -> Int -> Int -> Int 
middleNum a b c = (\[_,m,_] -> m) $ sort $ a:b:c:[] 

显然,这是一个可怕的想法,因为它明确地依赖于那里是列表中的3项,但它做的工作