Recursion 递归搜索树
这段代码试图构建一个简单的树结构,然后搜索匹配项。有些还可以Recursion 递归搜索树,recursion,tree,julia,Recursion,Tree,Julia,这段代码试图构建一个简单的树结构,然后搜索匹配项。有些还可以 mutable struct Tree node::String children::Vector end Tree(str::String) = Tree(str, []) Tree(a::Vector) = Tree("root", a) function Base.show(io::IO, tree::Tree, level = 0) print(io, "\t" ^ level * tree.no
mutable struct Tree
node::String
children::Vector
end
Tree(str::String) = Tree(str, [])
Tree(a::Vector) = Tree("root", a)
function Base.show(io::IO, tree::Tree, level = 0)
print(io, "\t" ^ level * tree.node * "\n")
for child in tree.children
show(io, child, level + 1)
end
end
function Base.length(t::Tree, counter = 1)
for child in t.children
if child != nothing
counter += 1
counter = length(child, counter)
end
end
return counter
end
function buildtree(path)
root = Tree(splitpath(path)[end])
if isdir(path)
for f in readdir(path)
push!(root.children, buildtree(joinpath(path, f)))
end
end
return root
end
function findfirstitem(t::Union{Tree, Array}, key)
result = missing
# if a number, return some of the children
if isa(key, Int) || isa(key, UnitRange)
return t.children[key]
end
# or look for a matching node/key
if isa(key, String)
for child in t.children
if occursin(key, child.node)
return child.node
end
if isa(child, Union{Tree, Array})
findfirstitem(Tree(child.node, child.children), key)
end
end
end
return result
end
filetree = buildtree(homedir() * "/.julia/registries/General/A")
顶层查询工作正常
julia> findfirstitem(filetree, "A")
"ACME"
julia> findfirstitem(filetree, 2:4)
3-element Array{Any,1}:
ADCME
Compat.toml
Deps.toml
Package.toml
Versions.toml
---------------------------
AIBECS
Compat.toml
Deps.toml
Package.toml
Versions.toml
---------------------------
AIControl
Compat.toml
Deps.toml
Package.toml
Versions.toml
---------------------------
julia> findfirstitem(filetree, "ACME")
"ACME"
但递归并不像我想的那样展开:
julia> findfirstitem(filetree, "Compat")
missing
我的头开始被这个递归弄痛了…这个函数不应该被赋予查看儿童的任务,因为这是由递归处理的
function findfirstitem(t::Union{Tree, Array}, key)
# if a number, return some of the children
if key isa Int || key isa UnitRange
return t.children[key]
end
# or look for a matching node/key
if key isa String
if occursin(key,t.node)
return t
else
for child in t.children
found = findfirstitem(child, key)
if !ismissing(found)
return found
end
end
end
end
return missing
end
但这取决于您对搜索算法的期望。它应该先搜索深度还是广度?该函数不应该被赋予查看子对象的任务,因为这是由递归处理的
function findfirstitem(t::Union{Tree, Array}, key)
# if a number, return some of the children
if key isa Int || key isa UnitRange
return t.children[key]
end
# or look for a matching node/key
if key isa String
if occursin(key,t.node)
return t
else
for child in t.children
found = findfirstitem(child, key)
if !ismissing(found)
return found
end
end
end
end
return missing
end
但这取决于您对搜索算法的期望。它应该先搜索深度还是广度?在我看来,如果child是数组,findfirstitemTreechild.node、child.children、key将失败?顺便说一句,为什么不为该部分使用dispatch?我也试图将children字段设置为::Tree,但这些递归类型定义很难,因此使用联合。在我看来,如果child是数组,findfirstitemTreechild.node、child.children、key将失败?顺便说一句,为什么不为该部分使用dispatch呢?我试图使children字段也成为::Tree,但是这些递归类型定义很难,因此使用union。