1 回答

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超8個(gè)贊
請(qǐng)注意,您只使用$needleLen流中的最新字符。所以你可以維護(hù)一個(gè)$needleLen由字符組成的滑動(dòng)窗口,并根據(jù)需要推進(jìn)它。此外,$haystackLen現(xiàn)在是未知的,應(yīng)該用 EOF 檢查代替。
O(n)下面的代碼效率低下,因?yàn)闊o論我們是按字符滑動(dòng)窗口n還是僅按 1 個(gè)滑動(dòng)窗口,滑動(dòng)窗口總是需要時(shí)間。為了實(shí)現(xiàn)最佳的滑動(dòng)復(fù)雜度,$window應(yīng)該將其實(shí)現(xiàn)為循環(huán)字符緩沖區(qū)。
// sample call
var_dump(BoyerMooreSearch(STDIN, 'foo'));
function BoyerMooreSearch($resource, $needle) {
$needleLen = strlen($needle);
$table = computeSkipTable($needle);
// build the first window
if (($window = buildWindow($resource, $needleLen)) === false) {
// special case: the text is shorter than the pattern
return false;
}
$i = 0;
while (true) {
// check for a match
$j = $needleLen - 1;
while ($j >= 0 && $needle[$j] == $window[$j]) {
$j--;
}
if ($j < 0) {
return $i;
}
// determine slide distance
$t = $i;
$last = substr($window, -1);
if (array_key_exists($last, $table)) {
$i = $i + max($table[$last], 1);
} else {
$i += $needleLen;
}
// slide the window
if (($window = slideWindow($window, $resource, $i - $t)) === false) {
return false;
}
}
return false;
}
/**
* Initializes the sliding window to length $len.
*
* @return string A string of length $len or false if the $resource contains
* less than $len characters.
*/
function buildWindow ($resource, $len) {
$result = '';
while ($len--) {
$result .= fgetc($resource);
}
return feof($resource) ? false : $result;
}
/**
* Slides $window by $count positions into $resource.
*
* @return string The new window or false on EOF.
*/
function slideWindow(&$window, $resource, $count) {
$window = substr($window, $count) // discard the first $count chars
. fread($resource, $count); // and read $count new chars
return feof($resource) ? false : $window;
}
- 1 回答
- 0 關(guān)注
- 164 瀏覽
添加回答
舉報(bào)