В течение двух недель я делал несколько простых программ на OCaml.Я заметил, что когда мы работаем с рекурсивной структурой T
и хотим получить информацию I
о T
, то в зависимости от информации I
у нас есть два типа рекурсивной функции.
Для простоты предположим, что T
- это двоичное дерево.Поэтому я буду использовать следующий тип:
type 'a tree = Empty | 'a * 'a tree * 'a tree
Теперь предположим, что информация I
может быть вычислена слева направо в двоичном дереве.Когда я говорю слева направо, это означает, что информация I
может быть рассчитана от корня до листьев, не возвращаясь назад.
Для большей ясности, скажем, информация I
, которую мы хотим получить, это просто «число узлов двоичного дерева».Тогда что хорошо с этой информацией, так это то, что когда мы добираемся до всех листьев, мы получаем I
, поэтому мы идем слева направо в том смысле, что начинаем с корня и рекурсивно расходуем его в левое и правое поддерево и в конечный случайэто когда мы добрались до листьев.
Итак, у нас просто есть:
let rec nodes = function
|Empty -> 0 (*it's ok we are done here*)
|Node(_,l,r) -> 1 + nodes l + nodes r
Что очень хорошо, так это то, что когда информация может быть вычислена слева направо, тогда сопоставление с образцом в OCaml является очень сильныминструмент и информацию I
можно рассчитать простым способом.Итак, в общем, у нас есть:
let rec get_information = function
| Empty -> (*here we are done so we return a constant value*)
|Node(_,l,r)-> (*here we apply recusrively the function to the left and right tree*)
Теперь вот моя проблема.Допустим, I
- это информация, которая не может быть рассчитана слева направо, но справа налево.Таким образом, это означает, что для получения информации I
нам нужно начинать с листьев дерева и рекурсивно расширяться до вершины, и мы закончим, только когда доберемся до корня бинарного дерева (поэтому конечный случай - это когда мыдобраться до корня двоичного дерева, а не листьев).
Например, скажем, информация I
такова: «двоичное дерево имеет свойство, которое для каждого узла равно количеству узлов в его левой части».поддерево строго превосходит количество узлов в его правом поддереве ".Если мы хотим решить это за линейное время, то нам нужно начинать с листьев и рекурсивно тратить деньги наверх (обратите внимание, что я не обязательно хочу решить проблему).
Так что для меня этосложно написать функцию, которая получает информацию I
, когда I
- это информация справа налево (она должна начинаться с листьев и расширяться до вершины).Напротив, сопоставление с образцом идеально, когда информация представляет собой информацию слева направо.
Итак, мой вопрос, как это сделать, когда нам нужно написать функцию, которая получает информацию I
(когда I
справа налево)?Существуют ли методы для решения подобных проблем?Можно ли все еще хитро использовать сопоставление с образцом, чтобы получить желаемый результат?