звезду на гитхабе ляпни ему, не поленись можно но не нужно пока единственно что, это для рекурсивной функции хорошо бы использовать обёртку, чтобы она уже вызывала рекурсию, чтобы только нужные для обёртки параметры передавать. --- Добавлено --- да, это сейчас считается верным подоходом
Словарь в действии. Вот 12 Спасибо, а я наоборот не люблю верблюда, мозг не привык, дополнительное усилие приходится делать, чтобы читать. Не дождусь когда закончу уже то, для чего это дерево создавалось. В действущей редакции функция выглядит так. Спойлер PHP: public function &trie_traverse_node(int $id, string $concat, array &$res = []): array { list($bits, $refs) = $this->node_get_children($id); //on the last node (leaf) save $concat to the res if (isset($bits[$this->codepage['flag']])){ $res[] = $concat; } //if there is no references return result if (empty($refs)) { return $res; } $bits = array_keys($bits); //recurse call node traverse on each node_id and pass $concat arg by concatenating it a new char foreach ($refs as $i => $node_id) { $string = $concat . $this->codepage_flip[$bits[$i]]; $this->trie_traverse_node($node_id, $string, $res); } return $res; } Поробовал сделать с одной точкой выхода, но мне показалось, что становится менее понятно, стараюсь избегать даже else у if, если это возможно.
А там реально все 3 аргумента нужные. В первом передается id узла, который надо пройти, поскольку в самом узле нет информации о том, какую букву он собой представляет, то во втором аргументе буква узла, в третьем аргумента передается ссылка на результирующий массив, в который собирается весь путь от начального узла до листьев дерева. При первом вызове ты указываешь первый узел с которого надо начать и букву этого узла, если третий аргумент не задан, то будет пустой массив. Ко второму аргументу на каждой следущем рекурсивном вызове от каждого пройденного узла добавляется его буква, в результате, когда дело доходит до листа (до узла, у которого в битовой маске поднят 48 бит), в этой строке как раз весь путь.
третий аргумент нужен только для работы рекурсии - внутреннего метода со своей внутренней механикой и внутренней необходимостью сущестования третьего аргумента. Для внешнего метода торчащего наружу он не нужен. т.е. логично сделать как-то так: function ajaja($arg1, $arg2) { return ololo($arg1, $arg2, null); } Это раз Два, мне например непонятно, когда и как вызывать твой метод, если из него самого не следует его буква. В каком случае его использовать? Почему нельзя вызвать просто по id? Или просто по букве?
Метод внутренний, он паблик только для удобства. Будет внешний метод, который по букве сможет траверс делать. Дело в том, что если писать в узле его букву - это ещё 6 доп. Байт на маску. Если представить узлы ящичками в шкафу, то в ящичках нет ничего кроме букв следующих ящичков и ссылок на их номера. Чтобы понять какие именно буквы в самых первых ящичках эти ящички идут в алфавитном порядке. Т.е. первая буква "а" с индексом узла 0. traverse_node(0, 'а') выдаст всю ветку дерева на букву 'а'. P.s. Нормально, но не по канону. Сейчас понял как можно переделать.
Потому что для нулевого узла известно, что тут 'а'. А когда ты не с первого узла начинаешь, к примеру надо выдать все слова начинающиеся на 'бар', надо делать так traverse_node(6443, 'бар') Отдаст массив всех слов с началом на бар. Естественно сначала ещё надо узнать, какой индекса у узла буквы р. --- Добавлено --- Так и сделаю после. Данные функции очень частотные, поэтому я стараюсь их оставлять такими полуфабрикатами, чтобы не дублировать работу по возможности нигде.