Безопасное многобайтовое число различных символов в строке - PullRequest
2 голосов
/ 11 октября 2011

Я не хочу находить умный и эффективный способ подсчета количества различных буквенных символов в одной строке. Пример:

$str = "APPLE";
echo char_count($str) // should return 4, because APPLE has 4 different chars 'A', 'P', 'L' and 'E'

$str = "BOB AND BOB"; // should return 5 ('B', 'O', 'A', 'N', 'D'). 

$str = 'PLÁTANO'; // should return 7 ('P', 'L', 'Á', 'T', 'A', 'N', 'O')

Он должен поддерживать строки UTF-8!

Ответы [ 5 ]

11 голосов
/ 11 октября 2011

Если вы имеете дело с UTF-8 (что вам действительно следует учитывать, imho), ни одно из опубликованных решений (с использованием strlen, str_split или count_chars) не будет работать, так как все они обрабатывают один байт как один символ (который является очевидно, что это не так для UTF-8).

<?php

$treat_spaces_as_chars = true;
// contains hälöwrd and a space, being 8 distinct characters (7 without the space)
$string = "hällö wörld"; 
// remove spaces if we don't want to count them
if (!$treat_spaces_as_chars) {
  $string = preg_replace('/\s+/u', '', $string);
}
// split into characters (not bytes, like explode() or str_split() would)
$characters = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);
// throw out the duplicates
$unique_characters = array_unique($characters);
// count what's left
$numer_of_characters = count($unique_characters);

Если вы хотите выбросить все несловарные символы:

<?php

$ignore_non_word_characters = true;
// contains hälöwrd and PIE, as this is treated as a word character (Greek)
$string = "h,ä*+l•π‘°’lö wörld"; 
// remove spaces if we don't want to count them
if ($ignore_non_word_characters) {
  $string = preg_replace('/\W+/u', '', $string);
}
// split into characters (not bytes, like explode() or str_split() would)
$characters = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);
// throw out the duplicates
$unique_characters = array_unique($characters);
// count what's left
$numer_of_characters = count($unique_characters);

var_dump($characters, $unique_characters, $numer_of_characters);
5 голосов
/ 11 октября 2011

Просто используйте count_chars :

echo count(array_filter(count_chars($str)));

Массив, возвращаемый из count_chars(), также скажет вам, сколько каждого символа содержится в строке.

1 голос
/ 11 октября 2011

count_chars возвращает карту всех символов ascii, сообщая вам, сколько их в строке.Вот отправная точка для вашей собственной реализации.

function countchars($str, $ignoreSpaces) {
  $map = array();
  $len = strlen($str);
  for ($i=0; $i < $len; $i++) {
    if (!isset($map[$str{$i}])) {
      $map[$str{$i}] = 1;
    } else {
      $map[$str{$i}]++;
    }    
  }

  if ($ignoreSpaces) {
    unset($map[' ']);
  }

  return $map;
}

print_r(countchars('Hello World'));
0 голосов
/ 11 октября 2011

Я так понимаю,

$chars = array_count_values(str_split($input));

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

1007 *
0 голосов
/ 11 октября 2011

Вот функция, которая сделает это, используя магию ассоциативных массивов.Работает за линейное время.(большой O = log(n))

function uniques($string){
   $arr = array();
   $parts = str_split($string);
   foreach($parts as $part)
      $arr["$part"] = "yup";
   return count($arr);
}

$str = "APPLE";
echo uniques($str);  // outputs 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...