<?php
//Топ N самых часто встречающихся слов и словосочетаний в тексте(из 2-3-х слов)
mb_internal_encoding('Utf-8');

$stopWords = array('и', 'у', 'к', 'с', 'о', 'от', 'в', 'же', 'из', 'на');
$input = 'Эта функция сортирует массив в обратном порядке таким образом, что
сохраняются отношения между ключами и значениями. Сохраняются отношения и
сохраняются отношения и еще сохраняются отношения и опять сохраняются отношения.';

//Функция удаляющая слова и словосочетания являющиеся частью больших словосочений
function removeRepetition($moreWords, $words)
{
    foreach ($moreWords as $moreWord => $moreCount) {
        foreach ($words as $word => $count) {
            //если во втором массиве словосочетания, иначе слова
            if (preg_match('/\w+ \w+/u', $word)) {
                if ((mb_strpos($moreWord, $word) !== false) && ($count == $moreCount)) {
                    unset($words[$word]);
                }
            } else {
                $severalWords = explode(' ', $moreWord);
                $oneWord = array($word);
                $matches = array_intersect($oneWord, $severalWords);
                if ((count($matches) != 0) && ($moreCount == $count)) {
                    unset($words[$word]);
                }
            }
        }
    }
    return $words;
}

//Удаляем лишнее - переносы, запятые, стоп слова.
$input = mb_strtolower($input);
$input = preg_replace('/[\\r\\n]/', ' ', $input);
$input = preg_replace('/,/', '', $input);
foreach ($stopWords as $word) {
    $input = preg_replace("/\\b$word\\b/u", '', $input);
}

$sentences = preg_split('/\./', $input, 0, PREG_SPLIT_NO_EMPTY);

//Формируем словосочетания
foreach ($sentences as $sentence) {
    $words = preg_split('/ /', $sentence, 0, PREG_SPLIT_NO_EMPTY);
    foreach ($words as $key => $word) {
        $oneWords[] = $word;
        //Прерываем цикл на последнем слове.
        if ($key == (count($words) - 1)) {
            break;
        }
        $twoWords[] = $word . ' ' . $words[$key + 1];
        if ($key !== 0) {
            $threeWords[] = $words[$key - 1] . ' ' . $word . ' ' . $words[$key + 1];
        }
    }
}

//Считаем, удаляем все что было найдено 1 раз и сортируем
$countWords = array_diff(array_count_values($oneWords), array(1));
$countTwoWords = array_diff(array_count_values($twoWords), array(1));
$countThreeWords = array_diff(array_count_values($threeWords), array(1));
arsort($countWords, SORT_NUMERIC);
arsort($countTwoWords, SORT_NUMERIC);
arsort($countThreeWords, SORT_NUMERIC);

//Удаляем слова и словосочеания являющиеся часть других
$countWords = removeRepetition($countThreeWords, $countWords);
$countWords = removeRepetition($countTwoWords, $countWords);
$countTwoWords = removeRepetition($countThreeWords, $countTwoWords);

$top = array_merge($countWords, $countTwoWords, $countThreeWords);

//Выводим результат нашей магии
if ($top == '') {
    echo 'Увы, но в данном тексте нет частых слов или словосочетаний встречающихся больше одного раза :(';
} elseif (count($top) == 1) {
    foreach ($top as $words => $count) {
        echo 'Самое частое слово/словосочетание: "' . $words . '", оно встречается - ' . $count .
            ' раз.';
    }
} else {
    arsort($top);
    echo "Самые частые слова/словосочетания:\n";
    foreach ($top as $words => $count) {
        echo $words . " - встречается " . $count . " раз.\n";
    }
}