Найти длину начального сегмента, совпадающего с маской на массивах - PullRequest
1 голос
/ 09 августа 2009

Дан массив с 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 () (где порядок «маски» имеет значение, спасибо, Зед), примененное к массивам.

РЕДАКТИРОВАТЬ: Чтобы немного прояснить ситуацию, я хочу найти все общие буквы, которые существуют в одном и том же индексе, во всех значениях массива (не уверен, что это стало проще или нет!) , В этой второй проблеме, поскольку все символы не соответствуют индексу в других значениях, мне нужно соответствовать максимальному количеству идентичных начальных сегментов (в данном случае 2: ​​ABCDEF и DEFABC).

Ответы [ 2 ]

2 голосов
/ 09 августа 2009

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

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

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
)
0 голосов
/ 09 августа 2009

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

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

$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)));

Осталось идти ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...