Как стать автором
Обновить

T9 своими руками

Время на прочтение4 мин
Количество просмотров4.3K
Привет, хабр!

Набирая смс или просто текст на мобильном телефоне довольно давно хотел сделать Т9 алгоритм самому.

Алгоритм понятен, но все не доходили руки.

Сегодня все же собрался и получилось сделать.

Итак первым делом нужно сформулировать то что хотелось получить.

Задача: Сделать аналог клавиатуры мобильного телефона и набирая цифры — получать список слов.
Ограничение: Особых ограничений не делалось, все таки работа для just for fun, но хочется чтобы было в районе 1 секунды парсинг.
В качестве фичи: Поддержка языков.

В качестве базы слов был взят файл с 26,000 слов.

Теперь сам алгоритм:

Мой алгоритм условно разбит на 2 части.
1 часть — выбирает все слова которые начинаются на одну из букв соответствующей цифре.
То есть для цифры 3 выбираются все слова начинающийся на d,e,f.

2 часть — последовательно проходить по всем числам и отсеивать неподходящие слова.

Поддержка языков:
Думаю всем понятно, что поддержка языков осуществляется заменой букв под цифрами.
По этому реализацию покажу ниже.

В качестве демонстрации используется jquery и эмуляция кнопок телефона.

Посмотреть можно здесь

Теперь сам класс на РНР:
class T9_Exception extends Exception {
}

abstract class T9 {
    protected $wordlist = array(); // слова которые загружаются
    protected $enum = array(); // соответсвие букв и цифр
    protected $mb_support = true; // поддержка мбстринг

    public function mb_support( $status = true ) {
        $this->mb_support = $status;
    }
    public function __construct( $filename=null ) {
        if( $filename )
            $this->load($filename); // грузим файл
    }
    public function load( $filename ) {
        if( file_exists($filename) && is_readable($filename)) {
            $this->wordlist = file($filename);
            //array_walk( $this->wordlist, create_function('&$w', '$w=trim($w);')); // замедляет работу пришлось отключить
            return ;
        }
        throw new T9_Exception("Can not read $filename", 100);

    }
    /**
     * Fetch data from wordlist
     * @param string $input
     * @return array
     */

    public function fetch($input) {
        $compare = array();
        $total = count($this->wordlist);
        for($i=0;$i<$total;$i++) {
            $len = strlen($this->enum[$input[0]]);
            for($j=0;$j<$len;$j++) {
                if( $this->mb_support == true ) {
                    if( mb_strpos($this->wordlist[$i], $this->enum[$input[0]][$j]) === 0)
                        $compare[]=$this->wordlist[$i];
                }
                else {
                    if( strpos($this->wordlist[$i], $this->enum[$input[0]][$j]) === 0)
                        $compare[]=$this->wordlist[$i];
                }

            }
        }
        for($i=1;$i<strlen($input);$i++) {
            $found = false;
            $newcompare = array();
            for($k=0;$k<count($compare);$k++) {
                for($j=0;$j<strlen($this->enum[$input[$i]]);$j++) {
                    $letter = $this->enum[ $input[$i] ][$j];
                    if( $this->mb_support == true) {
                        if( mb_strtolower($compare[$k][$i]) == $letter)
                            $newcompare[] = $compare[$k];
                    }
                    else {
                        if( $compare[$k][$i] == $letter)
                            $newcompare[] = $compare[$k];
                    }



                }
            }
            $compare = $newcompare;
        }
        return $compare;
    }
}


class T9_English extends T9 {

    protected $enum = array(
            0 => '',
            1 => '',
            2 => 'abc',
            3 => 'def',
            4 => 'ghi',
            5 => 'jkl',
            6 => 'mno',
            7 => 'pqrs',
            8 => 'tuv',
            9 => 'wxyz',
    );
}

class T9_Russian extends T9 {
    protected $enum = array(
            0 => '',
            1 => '',
            2 => 'абвг',
            3 => 'деёжз',
            4 => 'ийкл',
            5 => 'мноп',
            6 => 'рсту',
            7 => 'фхцч',
            8 => 'шщъы',
            9 => 'ьэюя',

    );
}


UPD: некоторые байты пропали при выводе, по этому выложил исходник так же по этой ссылке:
http://anton.in.ua/demo/t9/t9.txt

Русский словарь проверять не стал, но судя по алгоритму должно работать так же.

Вот такая небольшая разминка для ума.

Всем спасибо за внимание.
Теги:
Хабы:
Всего голосов 12: ↑12 и ↓0+12
Комментарии13

Публикации

Истории

Ближайшие события

19 августа – 20 октября
RuCode.Финал. Чемпионат по алгоритмическому программированию и ИИ
МоскваНижний НовгородЕкатеринбургСтавропольНовосибрискКалининградПермьВладивостокЧитаКраснорскТомскИжевскПетрозаводскКазаньКурскТюменьВолгоградУфаМурманскБишкекСочиУльяновскСаратовИркутскДолгопрудныйОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
24 – 25 октября
One Day Offer для AQA Engineer и Developers
Онлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
26 октября
ProIT Network Fest
Санкт-Петербург
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань