以递归的方式找到所有可能的路径
Find all possible paths in a recursive way
抱歉,因为这个问题对很多人来说可能听起来很菜鸟,但我绝对不擅长递归,需要一些帮助。
这是模型:
struct Chain {
let initialId: Int
let chains: [SubChain]
}
struct SubChain {
let id: Int
let subChains: [SubChain]
init(_ id: Int, subChains: [SubChain] = []) {
self.id = id
self.subChains = subChains
}
}
一个例子:
let chain = Chain(
initialId: 1,
chain: [
SubChain(
2,
subChains: [
SubChain(3),
SubChain(4)
]
),
SubChain(
5,
subChains: [
SubChain(6),
SubChain(
7,
subChains: [
SubChain(8)
]
)
]
),
]
)
现在我想找到所有可能的路径,即:
1 -> 2 -> 3
1 -> 2 -> 4
1 -> 5 -> 6
1 -> 5 -> 7 -> 8
我在 Chain
开始写这个,但我不知道如何递归地写这个。
var straightChain: [[Int]] {
var result: [[Int]] = []
for subChain in chain {
for c in subChain.subChains {
var subResult: [Int] = [initialId, subChain.id]
result.append(subResult)
}
}
return result
}
你能帮帮我吗?感谢您的帮助
链和子链不需要两种不同的结构类型。
对于递归,你需要做一个函数,它必须总是有一个基本情况,以及一个减少的情况问题每次都下降一点,调用自己
struct Node {
let id: Int
let children: [Node]
}
let n = Node(
id: 1,
children: [
.init(id: 2, children: [
.init(id: 3, children: []),
.init(id: 4, children: [])
]),
.init(id: 5, children: [
.init(id: 6, children: []),
.init(id: 7, children: [
.init(id: 8, children: [])
])
])
])
func paths(from n: Node) -> [[Int]] {
if n.children.isEmpty {
return [[n.id]]
}
else {
var result: [[Int]] = []
for childPath in n.children.flatMap(paths(from:)) {
result.append([n.id] + childPath)
}
return result
}
}
paths(from: n)
您可能想让您的结构通用化:
struct Node<T> {
let id: T
let children: [Node<T>]
}
let example = Node<Int>(....etc)
func paths<T>(from n: Node<T>) -> [[T]] {
// Base case, this stops the recursion so it doesn't go on forever
if n.children.isEmpty {
return [[n.id]]
}
else {
// reduce the problem a bit by working on just the children of this node, adding in our value later on
var result: [[T]] = []
// recursive call to our own function, which now has a smaller problem to work on and will always be closer to the base case
for childPath in n.children.flatMap(paths(from:)) {
result.append([n.id] + childPath)
}
return result
}
}
如果您愿意,您可以将子路径表达为结构的扩展,例如:
extension Node {
func subPaths() -> [[T]] {
if children.isEmpty {
return [[id]]
}
else {
var result: [[T]] = []
for childPath in children.flatMap({ [=12=].subPaths() }) {
result.append([id] + childPath)
}
return result
}
}
}
n.subPaths()
或者也许:
extension Node {
func subPaths() -> [[T]] {
if children.isEmpty {
return [[id]]
}
else {
return children.flatMap({ [=13=].subPaths() })
.map { [id] + [=13=] }
}
}
}
这是您问题的答案
下面是子链的递归
func findAllPossibleSubChain(_ chain: SubChain) -> [[Int]] {
if chain.subChains.count == 0 {
return [[chain.id]]
}
var result : [[Int]] = []
for sub in chain.subChains {
let temp = findAllPossibleSubChain(sub)
for val in temp {
// Recursion for the subChain if have array
result.append([chain.id] + val)
}
}
return result
}
主要
var result : [[Int]] = []
// Because of chain only have 1
if chain.chains.count == 0 {
result = [[chain.initialId]]
} else {
for sub in chain.chains {
let temp = findAllPossibleSubChain(sub)
for val in temp {
result.append([chain.initialId] + val)
}
}
}
print("result: ", result) // result: [[1, 2, 3], [1, 2, 4], [1, 5, 6], [1, 5, 7, 8]]
抱歉,因为这个问题对很多人来说可能听起来很菜鸟,但我绝对不擅长递归,需要一些帮助。
这是模型:
struct Chain {
let initialId: Int
let chains: [SubChain]
}
struct SubChain {
let id: Int
let subChains: [SubChain]
init(_ id: Int, subChains: [SubChain] = []) {
self.id = id
self.subChains = subChains
}
}
一个例子:
let chain = Chain(
initialId: 1,
chain: [
SubChain(
2,
subChains: [
SubChain(3),
SubChain(4)
]
),
SubChain(
5,
subChains: [
SubChain(6),
SubChain(
7,
subChains: [
SubChain(8)
]
)
]
),
]
)
现在我想找到所有可能的路径,即:
1 -> 2 -> 3
1 -> 2 -> 4
1 -> 5 -> 6
1 -> 5 -> 7 -> 8
我在 Chain
开始写这个,但我不知道如何递归地写这个。
var straightChain: [[Int]] {
var result: [[Int]] = []
for subChain in chain {
for c in subChain.subChains {
var subResult: [Int] = [initialId, subChain.id]
result.append(subResult)
}
}
return result
}
你能帮帮我吗?感谢您的帮助
链和子链不需要两种不同的结构类型。
对于递归,你需要做一个函数,它必须总是有一个基本情况,以及一个减少的情况问题每次都下降一点,调用自己
struct Node {
let id: Int
let children: [Node]
}
let n = Node(
id: 1,
children: [
.init(id: 2, children: [
.init(id: 3, children: []),
.init(id: 4, children: [])
]),
.init(id: 5, children: [
.init(id: 6, children: []),
.init(id: 7, children: [
.init(id: 8, children: [])
])
])
])
func paths(from n: Node) -> [[Int]] {
if n.children.isEmpty {
return [[n.id]]
}
else {
var result: [[Int]] = []
for childPath in n.children.flatMap(paths(from:)) {
result.append([n.id] + childPath)
}
return result
}
}
paths(from: n)
您可能想让您的结构通用化:
struct Node<T> {
let id: T
let children: [Node<T>]
}
let example = Node<Int>(....etc)
func paths<T>(from n: Node<T>) -> [[T]] {
// Base case, this stops the recursion so it doesn't go on forever
if n.children.isEmpty {
return [[n.id]]
}
else {
// reduce the problem a bit by working on just the children of this node, adding in our value later on
var result: [[T]] = []
// recursive call to our own function, which now has a smaller problem to work on and will always be closer to the base case
for childPath in n.children.flatMap(paths(from:)) {
result.append([n.id] + childPath)
}
return result
}
}
如果您愿意,您可以将子路径表达为结构的扩展,例如:
extension Node {
func subPaths() -> [[T]] {
if children.isEmpty {
return [[id]]
}
else {
var result: [[T]] = []
for childPath in children.flatMap({ [=12=].subPaths() }) {
result.append([id] + childPath)
}
return result
}
}
}
n.subPaths()
或者也许:
extension Node {
func subPaths() -> [[T]] {
if children.isEmpty {
return [[id]]
}
else {
return children.flatMap({ [=13=].subPaths() })
.map { [id] + [=13=] }
}
}
}
这是您问题的答案
下面是子链的递归
func findAllPossibleSubChain(_ chain: SubChain) -> [[Int]] {
if chain.subChains.count == 0 {
return [[chain.id]]
}
var result : [[Int]] = []
for sub in chain.subChains {
let temp = findAllPossibleSubChain(sub)
for val in temp {
// Recursion for the subChain if have array
result.append([chain.id] + val)
}
}
return result
}
主要
var result : [[Int]] = []
// Because of chain only have 1
if chain.chains.count == 0 {
result = [[chain.initialId]]
} else {
for sub in chain.chains {
let temp = findAllPossibleSubChain(sub)
for val in temp {
result.append([chain.initialId] + val)
}
}
}
print("result: ", result) // result: [[1, 2, 3], [1, 2, 4], [1, 5, 6], [1, 5, 7, 8]]