S
S
Sergey2015-02-03 13:50:46
PHP
Sergey, 2015-02-03 13:50:46

How to correctly use a link to remember the parent?

Good day. I'm trying to implement the Aho-Korasik algorithm, I made a drill, everything works fine, I implemented the removal of values ​​from the drill. After trying to load test values ​​~56k words, the interpreter gave me a message that the memory limit available for one script (128 mb) was exceeded. After some thought, I came to the conclusion that I was using links incorrectly. Instead of storing the address to the value in the array, the value itself (read the array) located at this link is written there. Here's a code example to make it clearer:

public function insert($key, $value) {
        $current_node = &$this->root;

        for ($i = 0; $i < mb_strlen($key, 'UTF-8'); $i++) {
            $char = mb_substr($key, $i, 1, 'UTF-8');

            $parent = &$current_node; // по идее должен указывать на родителя

            if (isset($current_node['children'][(string)$char])) { // если существует переход по букве
                $current_node = &$current_node['children'][(string)$char]; // обновляем текущее состояние (тут проблема)
                if (isset($current_node['isLeaf']))
                    unset($current_node['isLeaf']);
            } else {
                $current_node['children'][(string)$char] = []; // если нет перехода, то создаем его
                $current_node = &$current_node['children'][(string)$char]; // обновляем текущее состояние (и здесь проблема)
            }

            $current_node['parent'] = &$parent; // устанавливаем родителя данного узла

            if ($i == (mb_strlen($key, 'UTF-8') - 1)) { // обработка последнего символа в ключе
                $current_node['value'] = $value;
                if (!isset($current_node['children'])) {
                    $current_node['isLeaf'] = true;
                }
            }
        }
    }

With such a creation of boron, memory overrun occurs, as I already described at the very beginning. How to be?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Shamanov, 2015-02-06
@SilenceOfWinter

At a minimum, you need to get rid of redundant code:
Replace

for ($i = 0; $i < mb_strlen($key, 'UTF-8'); $i++) {
            $char = mb_substr($key, $i, 1, 'UTF-8');

to split the string into an array of characters (mb_split) and bypass it with a loop (foreach).
Replace
if (isset($current_node['isLeaf']))
                    unset($current_node['isLeaf']);

on
Well and
$current_node = &$current_node['children'][(string)$char];
clearly not the best solution.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question