- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
本书的第 9 章 Expert F# 3.0 展示了如何在遍历二叉树时使用连续传递样式来避免堆栈溢出。我编写的树遍历代码与书中的代码几乎相同,但仍然出现堆栈溢出。我的代码如下:
type 'a Tree =
| Leaf of 'a
| Branch of 'a Tree * 'a Tree
let rec mkLeftLeaningTree n tree =
if n = 0 then
tree
else
Branch (mkLeftLeaningTree (n - 1) tree, Leaf "right")
let leftLeaningTree1 = Leaf "left"
let leftLeaningTree2 = mkLeftLeaningTree 30000 leftLeaningTree1
let leftLeaningTree3 = mkLeftLeaningTree 30000 leftLeaningTree2
let leftLeaningTree4 = mkLeftLeaningTree 30000 leftLeaningTree3
let leftLeaningTree5 = mkLeftLeaningTree 30000 leftLeaningTree4
let leftLeaningTree6 = mkLeftLeaningTree 30000 leftLeaningTree5
let sizeContAcc tree =
let rec worker acc tree cont =
match tree with
| Leaf _ -> cont (acc + 1)
| Branch (left, right) -> worker acc left (fun acc ->
worker acc right cont)
worker 0 tree id
将其加载到 F# 交互环境中并计算表达式 sizeContAcc leftLeaningTree6
会导致堆栈溢出。这是为什么?
最佳答案
不幸的是,这可能无法帮助您实际解决问题,但也许它提供了一些查找位置的指示。首先,代码和设置。我减小了树本身的大小以使其能够在 Windows 上运行。其余的是.NET 4.6,64位,win7,在VS2015 Update3。
type 'a Tree =
| Leaf of 'a
| Branch of 'a Tree * 'a Tree
[<EntryPoint>]
let main argv =
///https://stackoverflow.com/questions/40477122/why-does-traversing-a-large-binary-tree-result-in-a-stack-overflow-even-when-usi
let rec mkLeftLeaningTree n tree =
if n = 0 then
tree
else
Branch (mkLeftLeaningTree (n - 1) tree, Leaf "right")
let leftLeaningTree1 = Leaf "left"
let leftLeaningTree2 = mkLeftLeaningTree 15000 leftLeaningTree1
let leftLeaningTree3 = mkLeftLeaningTree 15000 leftLeaningTree2
let leftLeaningTree4 = mkLeftLeaningTree 15000 leftLeaningTree3
let leftLeaningTree5 = mkLeftLeaningTree 15000 leftLeaningTree4
let leftLeaningTree6 = mkLeftLeaningTree 15000 leftLeaningTree5
let leftLeaningTree7 = mkLeftLeaningTree 15000 leftLeaningTree6
let leftLeaningTree8 = mkLeftLeaningTree 15000 leftLeaningTree7
let leftLeaningTree9 = mkLeftLeaningTree 15000 leftLeaningTree8
let leftLeaningTree10 = mkLeftLeaningTree 15000 leftLeaningTree9
let leftLeaningTree11 = mkLeftLeaningTree 15000 leftLeaningTree10
let leftLeaningTree12 = mkLeftLeaningTree 15000 leftLeaningTree11
let leftLeaningTree13 = mkLeftLeaningTree 15000 leftLeaningTree12
let leftLeaningTree14 = mkLeftLeaningTree 15000 leftLeaningTree13
let leftLeaningTree15 = mkLeftLeaningTree 15000 leftLeaningTree14
let leftLeaningTree16 = mkLeftLeaningTree 15000 leftLeaningTree15
let leftLeaningTree17 = mkLeftLeaningTree 15000 leftLeaningTree16
let leftLeaningTree18 = mkLeftLeaningTree 15000 leftLeaningTree17
let leftLeaningTree19 = mkLeftLeaningTree 15000 leftLeaningTree18
let leftLeaningTree20 = mkLeftLeaningTree 15000 leftLeaningTree19
let leftLeaningTree21 = mkLeftLeaningTree 15000 leftLeaningTree20
let leftLeaningTree22 = mkLeftLeaningTree 15000 leftLeaningTree21
let leftLeaningTree23 = mkLeftLeaningTree 15000 leftLeaningTree22
let leftLeaningTree24 = mkLeftLeaningTree 15000 leftLeaningTree23
let leftLeaningTree25 = mkLeftLeaningTree 15000 leftLeaningTree24
let leftLeaningTree26 = mkLeftLeaningTree 15000 leftLeaningTree25
let leftLeaningTree27 = mkLeftLeaningTree 15000 leftLeaningTree26
let leftLeaningTree28 = mkLeftLeaningTree 15000 leftLeaningTree27
let leftLeaningTree29 = mkLeftLeaningTree 15000 leftLeaningTree28
let leftLeaningTree30 = mkLeftLeaningTree 15000 leftLeaningTree29
let leftLeaningTree31 = mkLeftLeaningTree 15000 leftLeaningTree30
let sizeContAcc tree =
let rec worker acc tree cont =
match tree with
| Leaf _ -> cont (acc + 1)
| Branch (left, right) -> worker acc left (fun acc ->
worker acc right cont)
worker 0 tree id
sizeContAcc leftLeaningTree31 |> printfn "%A"
printfn "%A" argv
0 // return an integer exit code
这是用尾调用编译的,在Release模式下优化:
C:\Program Files (x86)\Microsoft SDKs\F#\4.0\Framework\v4.0\fsc.exe -o:obj\Release\ConsoleApplication8.exe --debug:pdbonly --noframework --define:TRACE --doc:bin\Release\ConsoleApplication8.XML --optimize+ --platform:x64 -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp.NETFramework\v4.0\4.4.0.0\FSharp.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6\mscorlib.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6\System.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6\System.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6\System.Numerics.dll" --target:exe --warn:3 --warnaserror:76 --vserrors --LCID:1033 --utf8output --fullpaths --flaterrors --subsystemversion:6.00 --highentropyva+ --sqmsessionguid:057b9ccf-c89e-4da6-81ab-5295156e7a19 "C:\Users\userName\AppData\Local\Temp.NETFramework,Version=v4.6.AssemblyAttributes.fs" AssemblyInfo.fs Program.fs 1> ConsoleApplication8 -> C:\Users\userName\Documents\Visual Studio 2015\Projects\StackOverflow6\ConsoleApplication8\bin\Release\ConsoleApplication8.exe
对于 31 棵树来说,这是可行的:
.\ConsoleApplication8.exe
450001
现在让我们在 Debug模式下编译它:
C:\Program Files (x86)\Microsoft SDKs\F#\4.0\Framework\v4.0\fsc.exe -o:obj\Debug\ConsoleApplication8.exe -g --debug:full --noframework --define:DEBUG --define:TRACE --doc:bin\Debug\ConsoleApplication8.XML --optimize- --tailcalls- --platform:anycpu32bitpreferred -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp.NETFramework\v4.0\4.4.0.0\FSharp.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6\mscorlib.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6\System.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6\System.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6\System.Numerics.dll" --target:exe --warn:3 --warnaserror:76 --vserrors --LCID:1033 --utf8output --fullpaths --flaterrors --subsystemversion:6.00 --highentropyva+ --sqmsessionguid:057b9ccf-c89e-4da6-81ab-5295156e7a19 "C:\Users\userName\AppData\Local\Temp.NETFramework,Version=v4.6.AssemblyAttributes.fs" AssemblyInfo.fs Program.fs 1> ConsoleApplication8 -> C:\Users\userName\Documents\Visual Studio 2015\Projects\StackOverflow6\ConsoleApplication8\bin\Debug\ConsoleApplication8.exe
而且,哎呀:
> .\ConsoleApplication8.exe
Process is terminated due to StackOverflowException.
那么有什么区别呢?
在发布版本中,如果反编译 IL,则有 9 个 tail
调用,我认为这是由某种 while 循环表示的。
IL_0073: ldloc.s 6
IL_0075: tail.
IL_0077: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic<!a>(class [mscorlib]System.Collections.IComparer, !!0, !!0)
在调试版本中,这将丢失:
L_007d: ldloc.s 6
IL_007f: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic<!a>(class [mscorlib]System.Collections.IComparer, !!0, !!0)
IL_0084: ret
要获得更简单的测试示例,您可以查看此 Question因为它同时具有算法的递归和尾递归版本。
关于f# - 为什么即使使用连续传递风格,遍历大型二叉树也会导致堆栈溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40477122/
尝试使用集成到 QTCreator 的表单编辑器,但即使我将插件放入 QtCreator.app/Contents/MacOS/designer 也不会显示。不过,相同的 dylib 文件确实适用于独
在此代码示例中。 “this.method2();”之后会读到什么?在返回returnedValue之前会跳转到method2()吗? public int method1(int returnedV
我的项目有通过gradle配置的依赖项。我想添加以下依赖项: compile group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', v
我将把我们基于 Windows 的客户管理软件移植到基于 Web 的软件。我发现 polymer 可能是一种选择。 但是,对于我们的使用,我们找不到 polymer 组件具有表格 View 、下拉菜单
我的项目文件夹 Project 中有一个文件夹,比如 ED 文件夹,当我在 Eclipse 中指定在哪里查找我写入的文件时 File file = new File("ED/text.txt"); e
这是奇怪的事情,这个有效: $('#box').css({"backgroundPosition": "0px 250px"}); 但这不起作用,它只是不改变位置: $('#box').animate
这个问题在这里已经有了答案: Why does OR 0 round numbers in Javascript? (3 个答案) 关闭 5 年前。 Mozilla JavaScript Guide
这个问题在这里已经有了答案: Is the function strcmpi in the C standard libary of ISO? (3 个答案) 关闭 8 年前。 我有一个问题,为什么
我目前使用的是共享主机方案,我不确定它使用的是哪个版本的 MySQL,但它似乎不支持 DATETIMEOFFSET 类型。 是否存在支持 DATETIMEOFFSET 的 MySQL 版本?或者有计划
研究 Seam 3,我发现 Seam Solder 允许将 @Named 注释应用于包 - 在这种情况下,该包中的所有 bean 都将自动命名,就好像它们符合条件一样@Named 他们自己。我没有看到
我知道 .append 偶尔会增加数组的容量并形成数组的新副本,但 .removeLast 会逆转这种情况并减少容量通过复制到一个新的更小的数组来改变数组? 最佳答案 否(或者至少如果是,则它是一个错
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
noexcept 函数说明符是否旨在 boost 性能,因为生成的对象中可能没有记录异常的代码,因此应尽可能将其添加到函数声明和定义中?我首先想到了可调用对象的包装器,其中 noexcept 可能会产
我正在使用 Angularjs 1.3.7,刚刚发现 Promise.all 在成功响应后不会更新 angularjs View ,而 $q.all 会。由于 Promises 包含在 native
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我正在编写一个玩具(物理)矢量库,并且遇到了 GHC 坚持认为函数应该具有 Integer 的问题。是他们的类型。我希望向量乘以向量以及标量(仅使用 * ),虽然这可以通过仅使用 Vector 来实现
PHP 的 mail() 函数发送邮件正常,但 Swiftmailer 的 Swift_MailTransport 不起作用! 这有效: mail('user@example.com', 'test
我尝试通过 php 脚本转储我的数据,但没有命令行。所以我用 this script 创建了我的 .sql 文件然后我尝试使用我的脚本: $link = mysql_connect($host, $u
使用 python 2.6.4 中的 sqlite3 标准库,以下查询在 sqlite3 命令行上运行良好: select segmentid, node_t, start, number,title
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我是一名优秀的程序员,十分优秀!