#scala #recursion
Вопрос:
Поэтому я работал над алгоритмом, который будет использовать двоичное дерево:
sealed trait BT case object Empty extends BT case class Node(val x: Int, val left: BT, val right: BT) extends BT
и верните двоичное дерево, но без дубликатов, с помощью рекурсивного dfs для поиска по дереву.
def removeRecurring_dfs(bt: BT, found: List[Int]): BT = { def dfs_helper(tree: BT): BT = { tree match case Empty =gt; Empty case Node(x, _, _) if found.contains(x) =gt; dfs_helper(rR(tree)) case Node(x, Empty, Empty) =gt; x::found tree case Node(x, left, Empty) =gt; x::found Node(x, dfs_helper(left), Empty) case Node(x, Empty, right) =gt; x::found Node(x, Empty, dfs_helper(right)) case Node(x, left, right) =gt; x::found Node(x, dfs_helper(left), dfs_helper(right)) } def rR(tree: BT): BT = removeNode(tree, findPath(tree)) dfs_helper(bt) }
Список «найдено» изначально пуст. «removeNode» и «findPath» — это функции, которые помогают мне достичь моей цели. После некоторого тестирования я обнаружил, что
x::found
линия никогда не работает, даже когда срабатывает случай с этой линией. С помощью некоторых действий println оказалось, что сопоставление шаблонов работает так, как я и предполагал.
Я недавно начал играть со scala и не понимаю, что может вызвать такое поведение
Комментарии:
1. Что ж, это может помочь, если перед тем , как пытаться написать двоичное дерево, вы сначала напишете
List
неизменяемое дерево. Таким образом, вы поймете, почемуx :: found
это сработало, это создаст НОВЫЙ список, потому что, как вы знаете, идея чего-то неизменного заключается в том, что оно не мутирует. — В любом случае, вы можете добавить дополнительный параметр в свой алгоритм поиска или использовать изменяемую коллекцию илиvar
— Как я уже сказал, если вы новичок в языке, вам следует начать с чего-то более простого.
Ответ №1:
Как уже указывалось, List
является неизменяемым, поэтому x :: found
создает новый List
элемент с x
добавлением элемента в found
список.
Новое List
должно быть сохранено/отправлено куда-то, иначе оно будет потеряно и соберется мусор.
Я не знаю, что findPath()
должны делать ваши методы и removeNode()
методы, поэтому немного сложно сказать, но, похоже, это то, чего вы пытаетесь достичь. (Синтаксис Scala-3)
sealed trait BT case object Empty extends BT case class Node(x: Int, left: BT, right: BT) extends BT def removeRecurring_dfs(bt: BT): BT = def dfs_helper(tree:BT, found:Set[Int]): (BT,Set[Int]) = tree match case Empty =gt; (Empty, found) case Node(x, left, right) =gt; if found(x) then dfs_helper(rR(tree), found) else val (lftNode, moreFound) = dfs_helper(left, found x) val (rgtNode, totalFound) = dfs_helper(right, moreFound) (Node(x, lftNode, rgtNode), totalFound) def rR(tree: BT): BT = removeNode(tree, findPath(tree)) dfs_helper(bt, Set())._1