Найти длину маски совпадения начального сегмента на массивах

Для массива с n значениями, например:

$arr[] = 'ABCDEFABC'; $arr[] = 'ABCDEFDEF'; $arr[] = 'ABCDEFGHI'; $arr[] = 'ABCDEFJKL'; 

как я могу найти начальный сегмент, который соответствует всем (или большинству, в приведенном ниже примере) значениям, в данном случае ABCDEF?

РЕДАКТИРОВАТЬ 2: НЕ РЕШАТЬ, СМОТРИТЕ ОТВЕТ.

Хуже того, учитывая следующий массив:

 $arr[] = 'ABCDEFABC'; $arr[] = 'ABCDEFDEF'; $arr[] = 'ABCDEFGHI'; $arr[] = 'ABCDEFJKL'; $arr[] = 'DEFABCABC'; $arr[] = 'DEFABCDEF'; $arr[] = 'DEFABCGHI'; $arr[] = 'DEFABCJKL'; 

как я могу получить:

 $result[] = 'ABCDEF'; $result[] = 'DEFABC'; 

Это сложно. То, что я пытаюсь выполнить, – это поведение strspn () (где порядок «маски» имеет значение, спасибо Zed), примененный к массивам.

EDIT: Чтобы немного уточнить, что я хочу, это найти все общие буквы, которые существуют в одном и том же индексе во всех значениях массива (не уверен, что это упростило или нет!). В этой второй проблеме, поскольку все символы не соответствуют индексу в других значениях, мне нужно сопоставить максимальное количество идентичных начальных сегментов (в данном случае 2: ​​ABCDEF и DEFABC).

Если я правильно понимаю, вы пытаетесь определить набор наиболее длинных общих префиксов, заданных набором строк.

Разбивая его, общий префикс между любыми двумя строками может быть найден как

 function longestCommonPrefix($str1, $str2) { $minLen = min(strlen($str1), strlen($str2)); for ($i = 0; $i < $minLen; $i++) { if ($str1[$i] != $str2[$i]) { return substr($str1, 0, $i); } } return substr($str1, 0, $minLen); } 

Один из способов получить набор префиксов мог бы быть следующим:

 function longestCommonPrefixes($arr) { sort($arr); $prefixes = array(); for ($i = 0; $i < count($arr); $i++) { for ($j = $i+1; $j < count($arr); $j++) { $prefix = longestCommonPrefix($arr[$i], $arr[$j]); if ($prefix == "") break; $prefixes[$prefix] = true; } } return array_keys($prefixes); } 

Обратите внимание, что возвращенные префиксы могут быть префиксами друг друга. То есть, результат может содержать набор строк, таких как array('A', 'AA', 'AAA') .

Объединяя все это:

 $arr = array(); $arr[] = 'ABCDEFABC'; $arr[] = 'ABCDEFDEF'; $arr[] = 'ABCDEFGHI'; $arr[] = 'ABCDEFJKL'; $arr[] = 'DEFABCABC'; $arr[] = 'DEFABCDEF'; $arr[] = 'DEFABCGHI'; $arr[] = 'DEFABCJKL'; print_r(longestCommonPrefixes($arr)); 

доходность

 Array ( [0] => ABCDEF [1] => DEFABC ) 

Я придумал решение для своей первой проблемы:

РЕДАКТИРОВАТЬ: ОШИБКА!

 $arr = array(); // Bug: ABCDEFX $arr[] = 'ABCDEFAXC'; $arr[] = 'ABCDEFDXF'; $arr[] = 'ABCDEFGXI'; $arr[] = 'ABCDEFJXL'; /* $arr[] = 'ABCDEFABC'; $arr[] = 'ABCDEFDEF'; $arr[] = 'ABCDEFGHI'; $arr[] = 'ABCDEFJKL'; */ // ABCDEF $result = implode('', call_user_func_array('array_intersect_assoc', array_map('str_split', $arr))); 

Осталось идти прямо сейчас …