找到HASKELL中最小的元组列表

时间:2013-03-24 10:17:14

标签: list haskell tuples

我试图找到具有最小距离((x1,x2)和(y1,y2)距离= abs(y2-y1)+ abs(x2-x1)的元组(一个或多个)点。例如:

  

列表将是[(1,2),(3,4),(5,4),(5,6),(9,12)]

     

,具体点是(xpos,ypos)=(4,4)。

然后我的函数应该返回[(3,4),(5,4)]。我试图实现这个但我有一个问题,我认为它与基本情况有关。有没有人可以帮助我?

disSolver xpos ypos coor = abs (xpos - (fst coor)) +abs(ypos-(snd coor))



closestTuple _ _ [] =[]
closestTuple xpos ypos (x:y:xs) = if (disSolver xpos ypos x)<= (disSolver xpos ypos y)
then [x] ++ closestTuple xpos ypos (xs)
else closestTuple xpos ypos (y:xs)

提前感谢!

2 个答案:

答案 0 :(得分:3)

你已经将disSolver分解为自己的功能,这很好。您可以更进一步,并抽象出算法“按某个指定的指标查找最小值”。 closestTuple只是两者的组成。 (除非我使用leventov的distSolver代替你的disSolver,因为类型更好地融合在一起。)

我选择使用函数管道来演示minimaBy而不是显式模式匹配和递归,因为在这种情况下我碰巧认为它更清晰,更不容易出错。

另请注意,我给出minimaBy的类型意味着如果它编译,它会自动摆脱某些错误。我们不能按c类型(对应(a, a)签名中的closestTuple)进行意外排序,因为只声明b来实现Ord。< / p>

(话虽如此,我没有编译或以其他方式测试过此代码,但它只能保证在我的头脑中完美运行:-))

import Control.Arrow ((&&&))
import Data.Function (on)
import Data.List (groupBy, sortBy)
import Data.Maybe (fromMaybe, listToMaybe)
import Data.Ord (comparing)

minimaBy :: Ord b => (c -> b) -> [c] -> [c]
minimaBy f = map fst
           . fromMaybe []
           . listToMaybe
           . groupBy ((==) `on` snd)
           . sortBy (comparing snd)
           . map (id &&& f)

closestTuple :: (Num a, Ord a) => (a, a) -> [(a, a)] -> [(a, a)]
closestTuple = minimaBy . distSolver

文档链接:

答案 1 :(得分:1)

当找到最近点的列表包含正好1个元素时,您错过了这种情况。您closestTuple实施的逻辑似乎也存在错误。

以下是我编写函数的方法:

distSolver :: Num a => (a, a) -> (a, a) -> a
distSolver (px, py) (x, y) = (abs (x - px)) + (abs (y - py))

closestTuple :: (Num a, Ord a) => (a, a) -> [(a, a)] -> [(a, a)]
closestTuple _ [] = []
closestTuple pos (x:xs) = mins (distSolver pos x) [x] pos xs

mins _ mxs _ [] = mxs
mins minDist mxs pos (x:xs)
    | dist < minDist  = mins dist [x] pos xs
    | dist == minDist = mins dist (x:mxs) pos xs
    | otherwise       = mins minDist mxs pos xs
  where dist = distSolver pos x