我试图找到具有最小距离((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)
提前感谢!
答案 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