gpt4 book ai didi

haskell - 如何从我的函数中计算总和?

转载 作者:行者123 更新时间:2023-12-02 07:03:08 25 4
gpt4 key购买 nike

我有一个文件 (points.txt),其中定义了一些笛卡尔坐标:

A 1.0 2.2
B 2.1 3.0
C 3.5 4.0
D 4.0 5.0

我有第二个文件 (routes.txt),其中包含基于 points.txt 中的点定义的路线。

route1 ACDB
route2 ABC

我需要找到每条路线的长度。到目前为止,我已经计算了两点之间的距离,如下所示:

type Point = (String, Float, Float)

distance_points :: IO ()
distance_points = do s <- readFile "pontos.txt"
putStr "Fom: "
p1 <- getLine
putStr "To: "
p2 <- getLine
print ( distance (search_point p1 (map words (lines s))) (search_point p2 (map words (lines s))))

search_point :: String -> [[String]] -> Point
search_point pt ([p,c1,c2]:xs) = if pt == p then (p, read(c1)::Float, read(c2)::Float)
else search_point pt xs

distance :: Point -> Point -> Float
distance (s1,x1,y1) (s2,x2,y2) = sqrt ((x1-x2)^2 + (y1-y2)^2)

如何计算路线的完整距离?

另外,如果我有几条路线,如何找到最长的一条?

提前致谢。

最佳答案

第 1 步:分离纯代码和非纯代码,直到最后才写入 IO。

最简单的方法是先用纯代码解决你的问题,然后再添加文件读取。否则你会忍不住写很多 IO 代码。

如果将名称与坐标分开会更容易:

type Coordinates = (Float,Float)
type Name = Char -- You had String, which is also fine
type Point = (Name, Coordinates)
type Points = [Point] -- or Map String Point from Data.Map

然后有一些练习数据:

sampleData :: Points
sampleData = [('A',(1.0,2.2), .....

第 2 步:编写一个函数,它接受一组点和一对点名称并返回一个距离

首先,您需要一个函数,它接受一个名称并为您提供一些坐标。

coordinates :: Points -> Name -> Coordinates

如果我们使用[Point],最简单的方法是使用lookup。 (您可以在 hoogle like this 上或通过输入 like this 找到有关函数的信息,尽管没有明显的方法让您知道您想要一个 Maybe,并且当您只是搜索 [(a,b)] -> b,查找是很长的路要走。)

如果您在此步骤中需要帮助,请发表评论。

使用它你将能够编写

distBetween :: Points -> Name -> Name -> Float

第 3 步:将表示路径的名称列表转换为点名称对列表

getPath :: String -> [(Name,Name)]

或者(更酷)使用 zipWith 来获取距离。之后,应用 sum 应该很容易解决问题。

制作这个配对列表的好方法是使用我们用于斐波那契数的技巧 (fibs = 0 : 1 : zipWith (+) fibs (tail fibs))用它的尾部发挥作用。如果你还没有遇到它,zip像这样工作:

 ghci> zip [1..5] "Hello Mum"
[(1,'H'),(2,'e'),(3,'l'),(4,'l'),(5,'o')]
zip "Hello" "ello"
[('H','e'),('e','l'),('l','l'),('l','o')]
*Main> zip "Hello" (tail "Hello")
[('H','e'),('e','l'),('l','l'),('l','o')]

太棒了 - 这正是您需要的技巧。

第四步:最后将代码读取文件写成你需要的数据类型

你需要像这样的函数

readPointsFile :: FilePath -> IO Points
readPointsFile fileName = do
....
....
return (map readPoint pointStrings)

然后你可以将它粘在一起,例如:

pathLengthFile :: FilePath -> FilePath -> IO Float
pathLengthFile pointsFilename pathFilename = do
points <- readPointsFile pointsFilename
path <- readPathFile pathFilename
return (getPathLength points path)

注意这一点中几乎没有任何逻辑。你用纯代码做所有真正的移植。


私下里,我是一个巨大的Applicative 粉丝,并且想要import Control.Applicative 并将其写成

pathLengthFile pointsFile pathFile = 
getPathLength <$> readPointsFile pointsFile <*> readPathFile pathFile

但那是以后的另一课。 :)

关于haskell - 如何从我的函数中计算总和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17014607/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com