python-从for循环返回false,否则在F#中继续
作者:互联网
我正在出于专业目的学习F#.我知道Python / Django和C#/.NET Core.因此,我想将我用Python编写的一些代码转换为F#.我不确定要挂断电话或只是感到疲倦,以为我可以进行一些协作.我想继续做,但发现那不是一个选择.原始的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现在使用一个辅助子功能(无用的子功能),该子功能获取输入列表其余部分的参数,累积的“堆栈”和当前根值.然后,它递归处理输入列表,像以前一样返回false,在列表末尾返回true,或者通过尾部递归调用正常处理它.
getNewRoot用于封装根值的更新和累积堆栈的调整.
请注意,这是Python的相当接近的翻译版本,这就是为什么它是如此膨胀的原因.最好是回到您尝试实现的本质,并使用F#中的功能编写新的东西.如果其他人想发布更好的版本,请这样做!
标签:f,python 来源: https://codeday.me/bug/20191108/2009181.html