N-Gram とはなんぞや
こちらを御覧ください。N-Gram (wikipedia)
アルゴリズム
自作です。いただいたコメントをもとに簡単化しました。
StringConverter.class.php
<?php
class StringConverter
{
/**
* 初期設定
*
* @return object
*/
final private static function _init()
{
if (! defined('SYSTEM_LANG')) {
define('SYSTEM_LANG', 'UTF-8');
}
}
/**
* This is N-gram algorithm.
* N-grapm is ...
* ex) $str = 'ABCDE' ---> when N(2) = 'AB BC CD DE'
* ex) $str = 'ABCDE' ---> when N(3) = 'ABC BCD CDE'
*
* addPlus flag is used by MySQL FULLTEXT INDEX SEARCH.
*
* @return object
*/
final public static function ngramX(string $str='', int $num=0, bool $addPlus=false): string
{
$prefix = $addPlus ? "\x2B" : '';
if ($num < 1) {
return $str;
}
if ($num < 2) {
$_chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
return $prefix.implode($_chars, "\x20".$prefix);
}
self::_init();
$_len = mb_strlen($str, SYSTEM_LANG);
$_items = [];
for ($i=0; $i<=$_len-$num; $i++) {
$_items[] = $prefix.mb_substr($str, $i, $num, SYSTEM_LANG);
}
return implode($_items, "\x20");
}
}
実際のN-Gramでは、
'ABCDE' に対し、N(3) = 'ABC BCD CDE DE E'
となるところですが、このアルゴリズムでは
'ABCDE' に対し、N(3) = 'ABC BCD CDE'
となります。
test
<?php
require_once 'StringConverter.class.php';
var_dump(StringConverter::ngramX('ABCDEF', 3, false)); // string(15) "ABC BCD CDE DEF"
var_dump(StringConverter::ngramX('ABCDEF', 3, true)); // string(19) "+ABC +BCD +CDE +DEF"
var_dump(StringConverter::ngramX('あいうえお', 3, false)); // string(29) "あいう いうえ うえお"
var_dump(StringConverter::ngramX('あいうえお', 3, true)); // string(32) "+あいう +いうえ +うえお"
var_dump(StringConverter::ngramX('ABCDEF', 2, false)); // string(14) "AB BC CD DE EF"
var_dump(StringConverter::ngramX('ABCDEF', 2, true)); // string(19) "+AB +BC +CD +DE +EF"
var_dump(StringConverter::ngramX('あいうえお', 2, false)); // string(27) "あい いう うえ えお"
var_dump(StringConverter::ngramX('あいうえお', 2, true)); // string(31) "+あい +いう +うえ +えお"
var_dump(StringConverter::ngramX('ABCDEF', 1, false)); // string(11) "A B C D E F"
var_dump(StringConverter::ngramX('ABCDEF', 1, true)); // string(17) "+A +B +C +D +E +F"
var_dump(StringConverter::ngramX('あいうえお', 1, false)); // string(19) "あ い う え お"
var_dump(StringConverter::ngramX('あいうえお', 1, true)); // string(24) "+あ +い +う +え +お"
var_dump(StringConverter::ngramX('ABCDEF', 0, false)); // string(6) "ABCDEF"
var_dump(StringConverter::ngramX('ABCDEF', 0, true)); // string(6) "ABCDEF"
var_dump(StringConverter::ngramX('あいうえお', 0, false)); // string(15) "あいうえお"
var_dump(StringConverter::ngramX('あいうえお', 0, true)); // string(15) "あいうえお"