使用 F# 进行循环与递归

2024-04-23

这里的示例代码解决了一个项目欧拉问题:

从数字 1 开始,按顺时针方向向右移动 方向 5 x 5 螺旋形成如下:

 21 22 23 24 25 
 20  7  8  9 10  
 19  6  1  2 11    
 18  5  4  3 12 
 17 16 15 14 13

可以验证对角线上的数字之和为 101.

1001 x 1001 中对角线上的数字之和是多少 螺旋也是以同样的方式形成的吗?

但我的问题是函数式编程风格的问题,而不是如何获得答案(我已经有了答案)。我试图通过避免解决方案中的命令式循环来自学一些关于函数式编程的知识,因此想出了以下递归函数来解决问题 28:

let answer = 
    let dimensions = 1001
    let max_number = dimensions * dimensions

    let rec loop total increment increment_count current =
        if current > max_number then total
        else
            let new_inc, new_inc_count =
                if increment_count = 4 then increment + 2, 0
                else increment, increment_count + 1
            loop (total + current) new_inc new_inc_count (current + increment)            
    loop 0 2 1 1

然而,在我看来,我的功能有点混乱。即使考虑到 F# 强制您将变量显式声明为可变且不包含 += 运算符,以下命令式版本也更短、更清晰:

let answer = 
    let dimensions = 1001
    let mutable total = 1
    let mutable increment = 2
    let mutable current = 1

    for spiral_layer_index in {1..(dimensions- 1) / 2} do
        for increment_index in {1..4} do
            current <- current + increment
            total <- total + current 
        increment <- increment + 2
    total

不考虑数学能力更强的人已经通过分析解决了这个问题,是否有更好的方法以函数式的方式来解决这个问题?我还尝试使用 Seq.unfold 创建一个值序列,然后将结果序列通过管道传输到 Seq.sum 中,但这最终比我的递归版本更混乱。


由于您没有描述您要解决的问题,因此该答案仅基于您发布的 F# 代码。我同意功能版本有点混乱,但我相信它可以更清晰。我不太明白嵌套for在你的命令式解决方案中循环:

for increment_index in {1..4} do 
  current <- current + increment 
  total <- total + current  

你没有使用increment_index对于任何东西,所以你可以乘以increment and current四倍并得到相同的结果:

total <- total + 4*current + 10*increment
current <- current + 4*increment

那么你的命令式解决方案就变成了:

let mutable total = 0 
let mutable increment = 2 
let mutable current = 1 

for spiral_layer_index in {1..(dimensions- 1) / 2} do 
  total <- total + 4*current + 10*increment
  current <- current + 4*increment
  increment <- increment + 2 
total 

如果你将其重写为递归函数,它就会变成:

let rec loop index (total, current, increment) = 
  if index > (dimensions - 1) / 2 then total 
  else loop (index + 1) ( total + 4*current + 10*increment,
                          current + 4*increment, increment + 2 )
let total = loop 1 (0, 2, 1)

同样的事情也可以写成使用Seq.fold像这样(这更加“函数式”,因为在函数式编程中,您仅使用递归来实现基本功能,例如fold然后可以重复使用):

let total, _, _=
  {1 .. (dimensions - 1) / 2} |> Seq.fold (fun (total, current, increment) _ ->
    (total + 4*current + 10*increment, current + 4 * increment, increment + 2)) (0, 1, 2)

注意:我不确定这是否真正实现了您想要的。这只是您的命令式解决方案的简化,然后使用递归函数重写它......

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 F# 进行循环与递归 的相关文章

  • 将可区分的联合传递给 InlineData 属性

    我正在尝试对一个解析器进行单元测试 该解析器解析字符串并返回相应的抽象语法树 表示为可区分的联合 我认为使用 Xunit Extensions 属性会非常紧凑InlineData将所有测试用例堆叠在一起
  • 图像分析-光纤识别

    我是图像分析新手 您知道如何以仅获取纤维的方式对该图像进行二值化吗 我尝试过不同的阈值技术等 但没有成功 我不介意应该使用什么工具 但我更喜欢 NET or Matlab PS 我不知道该把答案放在哪里 所以我把它放在StackOverfl
  • Lisp 中的十进制到二进制 - 制作非嵌套列表

    当达到我的递归情况时 我使用list将未来结果附加到当前结果 但由于递归 我最终得到一个嵌套列表 当我有一个导致递归超过五次的数字时 这会导致错误 任何想法如何我可以在一个简单的非嵌套列表中获得结果 例如 CL 用户 100 8 gt BI
  • 生成尾调用操作码

    出于好奇 我尝试使用 C 生成尾部调用操作码 斐波那契数很简单 所以我的 C 示例如下所示 private static void Main string args Console WriteLine Fib int MaxValue 0
  • 递归与迭代算法

    我正在实现欧几里德算法来查找两个整数的 GCD 最大公约数 给出了两个示例实现 递归和迭代 http en wikipedia org wiki Euclidean algorithm Implementations http en wik
  • F#:Microsoft.FSharp.Data.TypeProviders 是否需要配置文件 47?

    这是后续我昨天的帖子 https stackoverflow com questions 30399773 f fsc error fs2024 static linking may not use assembly that target
  • 专家 f# 脚本编译奇怪

    第 209 210 页有一个扩展示例 见下文 我使用的是 F 4 5 总之 我不明白的是 如果我单独键入每个语句 则会有一个声明引发错误 如果我立即提交整个脚本 以及引发错误的声明之后的函数 则一切正常 那么 当我批量提交所有语句时 交互中
  • 递归遍历树视图中的节点?

    我有一个树视图 其中已经填充了另一个过程中的文件 文件夹 我想按照从上到下的确切顺序逐项迭代树视图中的项目 但是 与普通列表不同 我不能仅使用简单的for对此的声明 我必须进入每个节点等 我该怎么做呢 我希望有一种方法可以在不运行递归过程的
  • F# 生成日期序列/数组

    在 F 中我可以轻松做到 let a 1 10 那我为什么不能做 let a DateTime Parse 01 01 2012 let b DateTime Parse 01 01 2020 let dateList a b 它给出了一个
  • F#:模式构成?

    我正在尝试编写一个由另外两个模式组成的模式 但我不确定如何去做 我的输入是字符串列表 文档 我有一个与文档标题匹配的模式和一个与文档正文匹配的模式 该模式应该匹配整个文档并返回标题和正文模式的结果 您可以使用以下命令一起运行两个模式 您在问
  • 一种递归算法,用于在数组中查找总和为给定整数的两个整数

    我需要一个算法来确定数组是否包含两个总和为给定整数的元素 数组已排序 该算法应该是递归的并且运行时间为 O n 递归步骤应该基于总和 这意味着该方法传递总和并根据最终结果返回 true 或 false 如果找到两个元素 返回 true 否则
  • 可以通过Data.Function.fix来表达变形吗?

    我有这个可爱的fixana这里的函数执行速度比她的姐妹快 5 倍左右ana 我有一个criterion报告支持我这一点 ana alg Fix fmap ana alg alg fixana alg fix f gt Fix fmap f
  • 如何在 F# 中使用 LINQ 更新数据库中的表?

    我看过很多有关如何查询数据库的示例 但没有看到有关如何更新记录的示例 下面是我编写的用于检索表的简单代码 但有人可以解释一下如何修改字段 例如lastActiveDate 并更新数据库上的表 谢谢你 周日 open System open
  • 为什么haskell中的递归列表这么慢?

    我对 Haskell 很陌生 我在 Haskell 中定义了一个函数 febs Integral a gt a gt a febs n n lt 0 0 n 1 1 n 2 1 otherwise febs n 1 febs n 2 但是
  • 如何根据递归关系确定递归树的高度?

    如何确定在处理递归运行时时构建的递归树的高度 它与确定普通树的高度有何不同 替代文本 http homepages ius edu rwisman C455 html notes Chapter4 ch4 9 gif http homepa
  • 我应该强制使用 F# 测量单位的类型吗? [风格与一般性]

    这个问题与 F 相关计量单位 https learn microsoft com en us dotnet fsharp language reference units of measure 我应该为我正在使用的单元强制执行类型吗 例如
  • Java-使用递归压平数组

    我一直在练习算法 递归一直是我的弱项 该问题要求将嵌套数组展平为单个数组 如果使用给出 O n 3 给定相同大小的 3d 数组 解决方案的循环 这将很简单 然而 通过递归 我已经挣扎了几个小时 这就是我所拥有的 请注意 我已经尝试过使用我的
  • C语言中的递归是如何工作的?

    我试图了解 C 中递归的工作原理 任何人都可以给我解释控制流吗 include
  • Haskell 排列库函数 - 请澄清一下?

    这是代码permutationsHaskell 中的函数Data List module permutations a gt a permutations xs0 xs0 perms xs0 where perms perms t ts i
  • F# 会自动内联一些函数,即使它们没有标记为“inline”,这是有意的吗?

    看起来 F 会自动内联一些函数 即使它们没有标记为 内联 let a x x 3 let b x x x let funB x y if x gt y then 3 else 1 let funC x let s a x let c fun

随机推荐

  • 不带单位的 CSS 属性的后备

    考虑 CSS 属性缺少单位 px em pt 的场景 div style width 170 border 1 dotted PaleGreen background color MistyRose The quick brown div
  • php microtime() 格式值

    PHP microtime 返回如下内容 0 56876200 1385731177 that s msec sec 我需要这种格式的值 1385731177056876200 this is sec msec without space
  • C# 的检查点库

    我正在寻找 C 检查点库 有任何想法吗 see http en wikipedia org wiki Application checkpointing http en wikipedia org wiki Application chec
  • 如何使用 Openxlsx 包修改 Excel 工作簿中的现有工作表?

    我正在使用 openxlsx 包来读取和写入 Excel 文件 我有一个固定文件 其中包含一个名为 数据 的工作表 其他工作表中的公式使用该工作表 我想更新此数据表而不触及其他数据表 我正在尝试以下代码 write xlsx x Rev 4
  • 如何在 Tornado 中记录 HTTP 响应?

    我希望能够在龙卷风中记录 HTTP 请求和响应 这似乎很容易通过请求来完成 def log function handler info Method handler request method Host handler request h
  • 适用于新应用程序引擎应用程序的 Python 3.7 本地开发服务器选项

    我有一个在标准 Python3 运行时上部署和运行的应用程序引擎应用程序 我还可以使用普通命令在本地运行它 例如flask run 但我无法像在 2 7 运行时中运行应用程序那样运行它dev appserver py 我正在使用最新的gcl
  • Django_tables2:根据请求动态隐藏列

    我有一个基于具有多个字段的模型的表 我也有两个TemplateColumns 一个用于编辑特定实体 另一个用于删除它 这是我的代码 class EntitetTable tables Table edit tables TemplateCo
  • io.cucumber 和 info.cukes 之间有什么区别

    我正在尝试使用 Cucumber 集成 BDD 但我真的很困惑有什么区别io 黄瓜 and 信息库克斯图书馆 以及使用哪一种以及何时使用 我尝试阅读并理解 github自述文件 md https github com cucumber cu
  • 如何清理提交树中未使用的侧分支?

    如何清理提交树中未使用的侧分支 不是真正的 git 分支 示例 树 假提交哈希 提交消息 可选 指针 0001 last commit master origin master HEAD 0002 old unused merge 0003
  • 使用 Jquery 验证插件 Ajax 远程验证 WordPress 用户名和电子邮件

    有谁知道如何使用 jquery 验证插件验证 WordPress 用户名和电子邮件 我正在尝试使用验证的远程方法检查用户名和电子邮件是否存在 我注意到 WordPress 有 username exists 和 email exists 等
  • Java关闭PDF错误

    我有这个java代码 try PDFTextStripper pdfs new PDFTextStripper String textOfPDF pdfs getText PDDocument load doc doc add new Fi
  • 禁用 UITextfield 的键盘

    我想知道如何禁用 UITextfield 的输入视图 环境textField inputView nil or textField setInputView nil 在 ShouldBeginEditing 中不执行任何操作 并使用user
  • [NSObject:任何对象]?' Xcode 6 Beta 6 中没有名为“下标”的成员

    我正在 Swift 中的 Xcode 6 Beta 6 中构建一个应用程序 但我不断收到此错误 NSObject AnyObject does not have a member named subscript 我不知道如何解决这个问题 我
  • 生成ip和限时下载链接

    有一个用于下载文件的直接链接 用户可以在付款后下载该链接 如下所示 http example com download webapp rar 但我需要生成ip和时间限制的下载链接 以防止其他人窃取该文件 我想在不使用任何数据库的情况下执行此
  • 在哪里将 google-services.json 文件放入 eclipse 项目中?

    我正在尝试实施新的GCM client在安卓上 在某一时刻 您必须启用Google Services对于该应用程序 启用后Cloud Messaging你必须下载该文件google services json并将其放入app or mobi
  • 模块化和抽象反应组件功能

    我下面有一个工作组件 允许所有复选框和复选框 它工作完美 然而 我讨厌这样的想法 每次我想使用此功能时 我都必须携带所有这些代码 我正在寻找一种在反应中使这个模块化的方法 这是 它不会将 输入检查所有 功能的整个功能模块化在一处 我必须在每
  • 如何在 svn 存储库中搜索任何修订版中是否存在文件

    如何搜索名为foo txt曾经提交到我的 svn 存储库 在任何修订版中 右键单击签出文件夹的根目录 gt TortoiseSVN gt 显示日志 您也可以在那里输入文件名
  • 如何用C语言播放MP3文件?

    我正在寻找在 C 中播放 MP3 文件的最简单方法 我正在寻找一个库 在其中我可以只调用文件名上的函数 或者一个将运行并退出的可执行文件 请建议 Using FMOD http www fmod org download 跨平台 这应该像这
  • 通过 ServiceStack api 使用 Linq2Twitter 和缓存的 OAuth 令牌

    我想使用 Linq2Twitter 从 ServiceStack 编写的 REST API 中进行 Twitter API 调用 我有以下信息 消费者钥匙 消费者秘密 当用户在网站上验证我们的应用程序时缓存的 OAuth 令牌 当用户在网站
  • 使用 F# 进行循环与递归

    这里的示例代码解决了一个项目欧拉问题 从数字 1 开始 按顺时针方向向右移动 方向 5 x 5 螺旋形成如下 21 22 23 24 25 20 7 8 9 10 19 6 1 2 11 18 5 4 3 12 17 16 15 14 13