15
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[PHP] 文字列をN-Gramで変換する

15
Last updated at Posted at 2013-12-02

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");
    }
}

(注1):[PHP] 文字列を一文字ずつ配列に格納する

実際の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) "あいうえお"

15
17
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?