python - 从 for 循环返回 false 否则在 F# 中继续
问题描述
我出于专业目的学习 F#。我知道 Python/Django 和 C#/.NET Core。所以我想把我用 Python 写的一些代码翻译成 F#。我挂断了电话,或者只是很累,不确定,我想我可以进行一些合作。我想这样做,else continue
但发现那不是一个选择。原始python代码:
#!/Users/ryandines/.local/share/virtualenvs/netcoreapp2.0-5nmzfUwt/bin/python
NUMBER_OF_TESTS = input()
INT_MIN = -2**32
def can_represent_bst(pre):
stack = []
root = INT_MIN
for value in pre:
if value < root:
return False
while(stack and stack[-1] < value):
root = stack.pop()
stack.append(value)
return True
for test in range(int(NUMBER_OF_TESTS)):
node_count = int(input())
nodes = list(map(int, input().split(' ')))
print("NODES: " + str(nodes))
if can_represent_bst(pre=nodes):
print("YES")
else:
print("NO")
到目前为止,这就是我在 F# 中编译和工作的结果:
open System
let NumberOfTests = Console.ReadLine() |> int
let root = Int32.MinValue
let seq1 = seq { for i in 0 .. NumberOfTests-1 -> (i, i*i) }
let CanRepresentBST args =
printfn "Passed args: %s" args
let result = args.Split ' '
let IntList = [for i in result -> i |> int32]
for value in IntList do
printfn "%d" value
[<EntryPoint>]
let main argv =
printfn "Hello World from F#!"
printfn "Number of tests: %d" NumberOfTests
printfn "Int min value: %d" root
for _ in seq1 do
let NodeCount = Console.ReadLine()
let Nodes = Console.ReadLine()
printfn "NodeCount: %s" NodeCount
let _ = CanRepresentBST Nodes
0 |> ignore
0
未完成的部分是这样的:
if value < root:
return False
while(stack and stack[-1] < value):
root = stack.pop()
stack.append(value)
可能会睡在上面,但如果有人为我做繁重的工作,我会很高兴,这样我醒来时就可以把它敲掉。
解决方案
这是一个部分解决方案(因为它尝试复制 Python,而不是正确使用 F#):
open System
let NumberOfTests = Console.ReadLine() |> int
let rec getNewRoot value stack root =
let mutable newRoot = root
let mutable acc = stack
while not (List.isEmpty acc) && (List.head acc) < value do
newRoot <- List.head acc
acc <- List.tail acc
(newRoot, acc)
let CanRepresentBST args baseRoot =
printfn "Passed args: %s" args
let intList = args.Split ' ' |> Seq.map int |> Seq.toList
let rec subfunc rem acc root =
match rem with
| [] -> true
| r :: rs ->
if r < root then
false
else
let (newRoot, newAcc) = getNewRoot r acc root
subfunc rs (r :: newAcc) newRoot
subfunc intList [] baseRoot
printfn "Number of tests: %d" NumberOfTests
let root = Int32.MinValue
printfn "Int min value: %d" root
for _ in 1..NumberOfTests do
let NodeCount = Console.ReadLine()
let Nodes = Console.ReadLine()
printfn "NodeCount: %s" NodeCount
if CanRepresentBST Nodes root then
printfn "YES"
else
printfn "NO"
我将其更改为 fsx 交互式脚本以使其更易于测试(使用fsi filename.fsx运行它),但我认为将其转换回已编译的程序应该很容易。
请注意,由于 getNewRoot 函数,许多(如果不是大多数)F# 粉丝不会喜欢这个程序 - 那里有太多的可变性。
我将 root 的定义移到程序的末尾,并让 CanRepresentBST 将其作为参数,以使函数成为纯函数 - 如果您总是以 MinValue 作为 root 开始,您可以在 CanRepresentBST 的顶部声明它。CanRepresentBST 现在使用一个辅助子函数(无用的命名 subfunc),它为输入列表的剩余部分、累积的“堆栈”和当前根值获取参数。然后它递归地处理输入列表,像以前一样返回 false,在列表末尾返回 true,或者使用尾递归调用正常处理它。
getNewRoot 用于封装根值的更新和累加栈的调整。
请注意,这是对 Python 的相当接近的翻译,这就是它膨胀得如此之多的原因。更好的办法是回到您想要实现的目标的本质,并使用您在 F# 中所拥有的东西编写新的东西。如果其他人想发布更好的版本,请这样做!
推荐阅读
- c - 在 C 中,'int *' 是派生数据类型吗?
- java - Swing JFileChooser 只接受 ZIP 和目录
- reactjs - 以这种方式定义反应组件的原因是什么?
- azure - 工作人员使用 celery、redis 和 rabbitMQ 发回结果的 2 分钟延迟
- python - 将行向量添加到 3-D numpy 数组
- html - 将 flexbox 缩小到其子项的大小
- mongodb - 根据 MongoDB 中的条件获取下一个和上一个文档
- linux - 有什么办法可以让进程处于 D 状态或 Z 状态?
- php - APCu 定期重置,零正常运行时间
- javascript - 使用最新版本的 d3-path 配置 jest