Задать вопрос
@BjornBorn

Почему код некорректно работает с кириллицей?

Нужно посчитать процентное содержание каждого символа в тексте.

// исходная строка
$string = 'тестовая строка';

// строка с удаленными пробелами
$string = str_replace(' ', '', $string);

// строка, где удалены все повторяющиеся символы
$uniqueSymbols = implode(array_unique(mb_str_split($string, 1)));

// перебираем строку через цикл for
for ($i = 0; $i < mb_strlen($uniqueSymbols); $i++) {
         // символ строки           формула
    echo $uniqueSymbols[$i] .' - '. round((mb_substr_count($string, $string[$i]) / mb_strlen($string)) * 100, 1) . ' %<br><br>';
}


Если вводить английские символы, то всё работает корректно, но если вводить символы на кириллице, то вместо символов показывает кракозябры, а вместо процентов "0".
  • Вопрос задан
  • 233 просмотра
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 1
pickHabr
@pickHabr
Костыльных дел мастер
Потому что кириллица, когда ты берешь $uniqueSymbols[$i] ты берешь не итую букву, а итый байт

$letter = mb_substr($uniqueSymbols, $i, 1);
echo $letter .' - '. round((mb_substr_count($string, $letter) / mb_strlen($string)) * 100, 1) . ' %<br><br>';
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Неэффективность этого решения просто вопиёт к небу. Перебирать строку столько раз, сколько в ней букв - это же кощунство. Неужели нельзя за один проход посчитать символы, а за второй вывести их веса? И получить условные O(n*3) вместо O(n*3 + n^2).
$len = mb_strlen($string);
$counts = array_count_values(mb_str_split($string));
foreach ($counts as $letter => $count) {
    echo "$letter: " . round($count / $len * 100, 1). "\n";
}

И заодно не придётся выковыривать из строки отдельные символы, которые мы уже выковыряли через mb_str_split.

А для практики будет полезнее реализовать подсчет символов самостоятельно, без использования встроенной функции РНР
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
IT ATLAS Москва
от 250 000 до 500 000 ₽