Как бы я go о реализации Бойера-Мура поиска для потоков? Я понимаю, как реализовать это для данной строки, где мы знаем длину всей строки. Однако, что если мы не имеем представления о размере строки (, т.е. это поток байтов произвольной длины ).
Я пытаюсь реализовать это в PHP, поэтому любой код в PHP было бы полезно.
Вот реализация поиска Бойера-Мура, который у меня есть в PHP:
function BoyerMooreSearch($haystack, $needle) {
$needleLen = strlen($needle);
$haystackLen = strlen($haystack);
$table = computeSkipTable($needle);
for ($i = $needleLen - 1; $i < $haystackLen;) {
$t = $i;
for ($j = $needleLen - 1; $needle[$j] == $haystack[$i]; $j--, $i--) {
if($j == 0) {
return $i;
}
}
$i = $t;
if(array_key_exists($haystack[$i], $table)) {
$i = $i + max($table[$haystack[$i]], 1);
} else {
$i += $needleLen;
}
}
return false;
}
function computeSkipTable($string) {
$len = strlen($string);
$table = [];
for ($i=0; $i < $len; $i++) {
$table[$string[$i]] = $len - $i - 1;
}
return $table;
}
Это прекрасно работает, если мы дадим ему строку сена, такую как "barfoobazquix"
и строка иглы типа "foo"
, она вернет 3
, как и ожидалось. Однако, что если входной стог сена был потоком, разделенным на 4 байта. Первый блок будет "barf"
, который не будет соответствовать, второй будет "ooba"
, который также не будет соответствовать, и так далее ...
В этом сценарии мы никогда не сможем найдите подстроку "foo"
в любом из буферизованных фрагментов потока с текущей реализацией. Я изо всех сил стараюсь адаптировать текущую реализацию так, чтобы она работала, даже если строка поиска была разбита на несколько частей.