gpt4 book ai didi

C++ 到 F# 的平滑转换

转载 作者:可可西里 更新时间:2023-11-01 18:28:47 25 4
gpt4 key购买 nike

大家好,我有以下来自 C++ 的代码。

for (int i=0; i < nObstacles; i++)
{
int x,y;
bool bAlreadyExists;
do {
x = rand() % nGridWidth;
y = rand() % nGridHeight;
} while (HasObstacle(x, y));
SetObstacle(x, y, true);
}

我可以毫无问题地将它直接翻译成 F#。

let R = new System.Random()
for i=0 to nObstacles do
let mutable bGoodToGo = false;
let mutable x =0;
let mutable y = 0
while not bGoodToGo do
x <-R.Next(nWidth)
y <-R.Next(nHeight)
bGoodToGo <- IsEmptyAt x y
board.[x,y]<-Obstacle;

当然,这可能会让你们中的大多数人畏缩,因为这不是 F# 的使用方式。这段代码有一些 F# 的“不合理”概念,例如 do-while 循环和可变数据。

但我感兴趣的是使用不可变数据的“正确”F# 翻译,以及某种等效的 do-while。

最佳答案

作为第一步,您可以了解如何在 for 循环中简化 while 循环。一种选择是使用 Seq.initInfinite 生成一个序列,该序列将为您提供任意数量的随机 X、Y 坐标。然后您可以使用 Seq.find 找到第一个引用空板字段的。

我还更改了 isEmpty 以获取一个元组(以便您可以使用部分函数应用程序作为参数传递给 Seq.find)并且我更改了一些名称以遵循更多标准 F# 风格(您通常不会使用匈牙利语命名符号):

let isEmpty (x, y) = board.[x,y] = -1

let rnd = new System.Random()
for i = 0 to obstacleCount do
let x, y =
// Generate infinite sequence of random X Y coordinates
Seq.initInfinite (fun _ -> rnd.Next(width), rnd.Next(height))
// Find first coordinate that refers to empty field
|> Seq.find isEmpty
// We still have mutation here
board.[x,y] <- Obstacle

我认为这是一个非常优雅的功能性解决方案。它可能比命令式解决方案慢一点,但关键是函数式风格使您在学习后更容易编写和更改实现(您始终可以使用命令式风格作为优化)。

为了避免所有可变状态,您需要先为障碍物生成位置,然后初始化数组。例如,您可以递归地向集合添加新坐标,直到它具有所需的长度。然后你可以使用 Array2D.init 生成数组:

let rec generateObstacles obstacles =
if Set.count obstacles = obstacleCount then obstacles
else
// Try generating new coordinate and add it to the set
// (if it is already included, this doesn't do anything)
obstacles
|> Set.add (rnd.Next(width), rnd.Next(height))
|> generateObstacles

let obstacles = generateObstacles Set.empty
Array2D.init width height (fun x y ->
if obstacles.Contains(x, y) then Obstacle else Empty)

这并不是真的更短,而且会慢一点,所以我会坚持使用第一个解决方案。然而,这是一个很好的展示递归和集合的练习......

关于C++ 到 F# 的平滑转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5399153/

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