Я думаю, что самый простой способ будет сделать тип данных, который может описать путь через дерево:
data Path = L Path | R Path | End deriving (Eq, Show)
Этот тип является в основном список, но с двумя конструкторами prepend, чтобы сказать вам, либо идти влево, либо идти вправо. Это позволяет вам искать элементы по пути, или вы можете написать функцию, которая дает вам список всех путей в дереве.
-- Note that this can fail: lookupNode (Leaf 1) (L End) == Nothing
lookupNode :: Tree -> Path -> Maybe Tree
allPaths :: Tree -> [Path]
Если вы можете написать функцию allPaths
, то вы можете написать функцию, которую вы хотите на нем. Чтобы начать, просто начать с перечисления базовых случаев:
allPaths (Leaf _) = [End]
allPaths (Node _ left right) = _
Чтобы заполнить отверстие _
, подумайте о том, что это значит перечислить все пути, начинающиеся на Node
и рекурсии вниз left
. Вы должны были бы иметь L
в начале всех этих путей, так что вы можете поместить следующее в там
allPaths (Node _ left right) = (map L $ allPaths left)
Кроме того, вам нужно будет обрабатывать right
дерево:
allPaths (Node _ left right) =
(map L $ allPaths left) ++
(map R $ allPaths right)
Так Сейчас:
> let tree =
Node 1
(Node 2 -- L _
(Leaf 3) -- L (L End)
(Node 4 -- L (R _)
(Leaf 5) -- L (R (L End))
(Leaf 6) -- L (R (R End))
)
)
(Leaf 7) -- R End
> allPaths tree
[L (L End),L (R (L End)), L (R (R End)),R End]
Теперь, чтобы найти Leaf
с с четным числом узлов над ними, сначала написать функцию, которая вычисляет путь русификатор го:
pathLength :: Path -> Int
pathLength End = 0
pathLength (L rest) = 1 + pathlength rest
pathLength (R rest) = 1 + pathLength rest
evenNodeCountPaths :: Tree -> [Path]
evenNodeCountPaths tree = filter (even . pathLength) $ allPaths tree
Примечание: Можно сделать это с
data Dir = L | R | End
type Path = [Dir]
Но это может привести к неправильным путям, как [End, End, L, R, End], который только не имеет никакого смысла. По этой причине я решил пойти по списку data Path
. Вы должны написать свою собственную функцию pathLength
, но эта формулировка делает невозможным наличие неверных путей.
спасибо. Я никогда бы не справился сам по себе, мне даже было трудно понять, почему ваше решение даже работает вначале. – banzai