mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 09:48:40 +00:00
187 lines
4.0 KiB
PHP
Executable File
187 lines
4.0 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Jingga
|
|
*
|
|
* PHP Version 8.2
|
|
*
|
|
* @package phpOMS\System\Search
|
|
* @copyright Dennis Eichhorn
|
|
* @license OMS License 2.0
|
|
* @version 1.0.0
|
|
* @link https://jingga.app
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
namespace phpOMS\System\Search;
|
|
|
|
/**
|
|
* Basic string search algorithms.
|
|
*
|
|
* @package phpOMS\System\Search
|
|
* @license OMS License 2.0
|
|
* @link https://jingga.app
|
|
* @since 1.0.0
|
|
*/
|
|
abstract class StringSearch
|
|
{
|
|
/**
|
|
* @codeCoverageIgnore
|
|
*/
|
|
private function __construct()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Find pattern in string
|
|
*
|
|
* @param string $pattern Pattern
|
|
* @param string $text Text to search in
|
|
*
|
|
* @return int Match position
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public static function knuthMorrisPrattSearch(string $pattern, string $text) : int
|
|
{
|
|
$patternSize = \strlen($pattern);
|
|
$textSize = \strlen($text);
|
|
|
|
$shift = self::knuthMorrisPrattShift($pattern);
|
|
|
|
$i = 1;
|
|
$j = 0;
|
|
while ($i + $patternSize <= $textSize) {
|
|
while ($text[$i + $j] === $pattern[$j]) {
|
|
++$j;
|
|
if ($j >= $patternSize) {
|
|
return $i;
|
|
}
|
|
}
|
|
|
|
if ($j > 0) {
|
|
$i += $shift[$j - 1];
|
|
$j = \max($j - $shift[$j - 1], 0);
|
|
} else {
|
|
++$i;
|
|
$j = 0;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Create shift array
|
|
*
|
|
* @param string $pattern Pattern
|
|
*
|
|
* @return int[]
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private static function knuthMorrisPrattShift(string $pattern) : array
|
|
{
|
|
$patternSize = \strlen($pattern);
|
|
$shift = [];
|
|
$shift[] = 1;
|
|
|
|
$i = 1;
|
|
$j = 0;
|
|
while ($i + $j < $patternSize) {
|
|
if ($pattern[$i + $j] === $pattern[$j]) {
|
|
$shift[$i + $j] = $i;
|
|
++$j;
|
|
} else {
|
|
if ($j === 0) {
|
|
$shift[$i] = $i + 1;
|
|
}
|
|
|
|
if ($j > 0) {
|
|
$i += $shift[$j - 1];
|
|
$j = \max($j - $shift[$j - 1], 0);
|
|
} else {
|
|
++$i;
|
|
$j = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $shift;
|
|
}
|
|
|
|
/**
|
|
* Find pattern in string
|
|
*
|
|
* @param string $pattern Pattern
|
|
* @param string $text Text to search in
|
|
*
|
|
* @return int Match position
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public static function boyerMooreHorspoolSimpleSearch(string $pattern, string $text) : int
|
|
{
|
|
$patternSize = \strlen($pattern);
|
|
$textSize = \strlen($text);
|
|
|
|
$i = 0;
|
|
$j = 0;
|
|
while ($i + $patternSize <= $textSize) {
|
|
$j = $patternSize - 1;
|
|
|
|
while ($text[$i + $j] === $pattern[$j]) {
|
|
--$j;
|
|
if ($j < 0) {
|
|
return $i;
|
|
}
|
|
}
|
|
|
|
++$i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Find pattern in string
|
|
*
|
|
* @param string $pattern Pattern
|
|
* @param string $text Text to search in
|
|
*
|
|
* @return int Match position
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public static function boyerMooreHorspoolSearch(string $pattern, string $text) : int
|
|
{
|
|
$patternSize = \strlen($pattern);
|
|
$textSize = \strlen($text);
|
|
|
|
$shift = [];
|
|
for ($k = 0; $k < 256; ++$k) {
|
|
$shift[$k] = $patternSize;
|
|
}
|
|
|
|
for ($k = 0; $k < $patternSize - 1; ++$k) {
|
|
$shift[\ord($pattern[$k])] = $patternSize - 1 - $k;
|
|
}
|
|
|
|
$i = 0;
|
|
$j = 0;
|
|
while ($i + $patternSize <= $textSize) {
|
|
$j = $patternSize - 1;
|
|
|
|
while ($text[$i + $j] === $pattern[$j]) {
|
|
--$j;
|
|
if ($j < 0) {
|
|
return $i;
|
|
}
|
|
}
|
|
|
|
$i += $shift[\ord($text[$i + $patternSize - 1])];
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
}
|