Создание дерева Хафмана в PHP

Я пытаюсь создать Дерево Хафмана, используя PHP.

Это - то, что я имею:

<!DOCTYPE HTML>
<html>
    <body>
        <?php
            $extract = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse elementum imperdiet aliquet. Duis non molestie orci. Ut eget nibh nec augue ultricies porttitor.';
            $characters = count_chars($extract, 1);            
            asort($characters);
            foreach($characters as $character => $occurrence)
            {
               echo 'There';
               if($occurrence > 1)
               {
                   echo ' were ' . $occurrence . ' occurrences of ';
               }
               else
               {
                   echo ' was '. $occurrence . ' occurrence of ';
               }
               echo '"' . chr($character) . '" in the extract.
'; $characterFreq[chr($character)] = $occurrence; } print_r($characterFreq); ?> </body> </html>

Какая продукция:

There was 1 occurrence of "S" in the extract.
There was 1 occurrence of "U" in the extract.
There was 1 occurrence of "h" in the extract.
There was 1 occurrence of "L" in the extract.
There was 1 occurrence of "D" in the extract.
There was 1 occurrence of "," in the extract.
There was 1 occurrence of "q" in the extract.
There was 1 occurrence of "b" in the extract.
There were 3 occurrences of "g" in the extract.
There were 4 occurrences of "a" in the extract.
There were 4 occurrences of "." in the extract.
There were 4 occurrences of "d" in the extract.
There were 5 occurrences of "p" in the extract.
There were 6 occurrences of "c" in the extract.
There were 6 occurrences of "l" in the extract.
There were 7 occurrences of "m" in the extract.
There were 8 occurrences of "n" in the extract.
There were 8 occurrences of "r" in the extract.
There were 9 occurrences of "u" in the extract.
There were 9 occurrences of "o" in the extract.
There were 10 occurrences of "s" in the extract.
There were 15 occurrences of "t" in the extract.
There were 17 occurrences of "i" in the extract.
There were 20 occurrences of "e" in the extract.
There were 22 occurrences of " " in the extract.
Array ( [S] => 1 [U] => 1 [h] => 1 [L] => 1 [D] => 1 [,] => 1 [q] => 1 [b] => 1 [g] => 3 [a] => 4 [.] => 4 [d] => 4 [p] => 5 [c] => 6 [l] => 6 [m] => 7 [n] => 8 [r] => 8 [u] => 9 [o] => 9 [s] => 10 [t] => 15 [i] => 17 [e] => 20 [ ] => 22 )

Я использовал смеси array_slice() , array_splice() и array_unshift() , но испытываю затруднения из-за рекурсии.

Ideally, leaves and branches will be denoted by array indices 0 & 1.

Любые идеи о том, как сделать дерево Хафмана в форме многомерного массива, значительно ценились бы.

0
кто-либо готовый предложить что-либо..?
добавлено автор verbumSapienti, источник
хорошо, по крайней мере это заработало для меня значок перекати-поля!
добавлено автор verbumSapienti, источник

1 ответы

Это - полное решение проблемы в PHP:

function huffmannEncode($string) {
    $originalString = $string;
    $occurences = array();

    while (isset($string[0])) {
        $occurences[] = array(substr_count($string, $string[0]), $string[0]);
        $string = str_replace($string[0], '', $string);
    }

    sort($occurences);
    while (count($occurences) > 1) {
        $row1 = array_shift($occurences);
        $row2 = array_shift($occurences);
        $occurences[] = array($row1[0] + $row2[0], array($row1, $row2));
        sort($occurences);
    }

   //$dictionary is an array that gets filled with the values with a recursive method
    $dictionary = [];
    fillDictionary($dictionary, is_array($occurences[0][1]) ? $occurences[0][1] : $occurences);

   //Generate the final encoded message
    $encoded = '';
    for($i = 0; $i < strlen($originalString); $i++) {
        $encoded .= $dictionary[$originalString[$i]];
    }
    return $encoded;
}

// This function runs recursively to generate the Huffmann tree
function fillDictionary(&$dictionary, $data, $value = '') {
    if (!is_array($data[0][1])) {
        $dictionary[$data[0][1]] = $value.'0';
    } else {
        fillDictionary($dictionary, $data[0][1], $value.'0');
    }
    if (isset($data[1])) {
        if (!is_array($data[1][1])) {
            $dictionary[$data[1][1]] = $value.'1';
        } else {
            fillDictionary($dictionary, $data[1][1], $value.'1');
        }
    }
}

Эта функция вычисляет случаи, и с рекурсивной подфункцией она производит словарь, который назначает двоичный код на каждый характер.

Вот пример:

// Test the functionality:
echo huffmannEncode('hello world');
// Output: 00100010101101110011110010101111
// And the dictionary:
/* 
[e] => 000
[h] => 001
[r] => 010
[w] => 011
[l] => 10
[o] => 110
[ ] => 1110
[d] => 1111
*/
0
добавлено
phpGeeks
phpGeeks
3 620 участник(ов)

Best PHP chat Еще: @dbGeeks - базы данных @phpGeeksJunior - новичкам @moscowProgers - IT Москва @ebanoePhp - весёлый канал о PHP @laravel_pro - Laravel @jobGeeks - вакансии @jsChat - JS Правила: https://t.me/phpGeeks/764859 ДР - 28.03.2016

PHP
PHP
1 309 участник(ов)

Группа про современный PHP. Обсуждаем ООП, TDD, BDD, DDD, SOLID, GRASP и прочие крутые базворды Для ознакомления: https://gist.github.com/mkusher/711bd46f0b62fbae851182e6fb3b1839 Группа PHP для новичков @phpGeeksJunior Вакансии: https://t.me/fordev

PHP — вакансии, поиск работы и аналитика
PHP — вакансии, поиск работы и аналитика
1 251 участник(ов)

Публикуем вакансии и запросы на поиск работы по направлению PHP, Laravel, Symfony, Yii и т.д. Здесь всё: full-time, part-time, remote и разовые подработки. См. также: @qa_jobs, @devops_jobs, @javascript_jobs, @nodejs_jobs, @uiux_jobs, @products_jobs

phpGeeksJunior
phpGeeksJunior
980 участник(ов)

Группа для новичков. Не стесняйтесь задавать вопросы по php. Не флудить!!!! Правила и полезные ссылки https://gist.github.com/exileed/a53dd0617b35a705ff44b38c8028e6a5 Бест от пхпгикс https://t.me/best_of_phpgeeks

phpclub.ru
phpclub.ru
872 участник(ов)

Официальный чат phpclub.ru - остерегайтесь подделок #rules Правила группы - уважайте друг друга. Скриншоты -> ссылками. Код -> pastebin.com. Вакансии строго -> https://goo.gl/4bNxym, в чат ссылку. За рекламу и мат - БАН!

Devall | PHP
Devall | PHP
272 участник(ов)

Пристанище для восходящих звёзд разработки, которые перейдут на более адекватные языки. http://combot.org/chat/-1001014863761 Инвайт: j.mp/devallphp