Простая библиотека римских цифр PHP
Эта библиотека включает в себя пару простых фильтров для преобразования string
с римским числом в int
, которое представляет входные данные как десятичное, и десятичное int
число в string
с римским числом в качестве результата.
use Romans Filter RomanToInt ;
$ filter = new RomanToInt ();
$ result = $ filter -> filter ( ' MCMXCIX ' ); // 1999
use Romans Filter IntToRoman ;
$ filter = new IntToRoman ();
$ result = $ filter -> filter ( 1999 ); // MCMXCIX
Этот пакет использует Composer в качестве репозитория по умолчанию. Вы можете установить его, добавив имя пакета в раздел require
composer.json
, указав на последнюю стабильную версию.
{
"require" : {
"wandersonwhcr/romans" : " ^1.0 "
}
}
Кроме того, Romans использует семантическое управление версиями. Следующие версии пакетов поддерживают эти выпуски PHP:
1.0.*
: PHP ^7.0
(Август)1.1.*
: PHP ^7.0
(Тиберий)1.2.*
: PHP >=7.4
(Калигула)1.3.*
: PHP >=7.4
(Клавдий)1.4.*
: PHP >=7.4
(Nero)1.5.*
: PHP >=8.0
(Гальба) Эту библиотеку можно использовать в качестве зависимости для проектов, что упрощает интеграцию с библиотеками или платформами. Если вы хотите добавить больше элементов в этот список, пожалуйста, откройте задачу или создайте запрос на включение, добавив свой проект в алфавитном порядке.
Пакет Romans
использует подход Lexer-Parser и детерминированный конечный автомат (DFA) для преобразования римского числа в int
с использованием библиотеки Grammar Token.
use Romans Grammar Grammar ;
use Romans Lexer Lexer ;
use Romans Parser Parser ;
$ grammar = new Grammar ();
$ lexer = new Lexer ( $ grammar );
$ parser = new Parser ( $ grammar );
$ tokens = $ lexer -> tokenize ( ' MCMXCIX ' );
/*
$tokens = [
0 => 'M' // Grammar::T_M
1 => 'C', // Grammar::T_C
2 => 'M', // Grammar::T_M
3 => 'X', // Grammar::T_X
4 => 'C', // Grammar::T_C
5 => 'I', // Grammar::T_I
6 => 'X', // Grammar::T_X
];
*/
$ result = $ parser -> parse ( $ tokens ); // 1999
Фильтр RomanToInt
использует Lexer для токенизации входных данных и Parser для построения int
числа. При обнаружении ошибок лексер или синтаксический анализатор выбрасывают исключения, чтобы уведомить о проблеме с помощью определенного кода.
use Romans Filter RomanToInt ;
use Romans Lexer Exception as LexerException ;
use Romans Parser Exception as ParserException ;
$ filter = new RomanToInt ();
try {
$ filter -> filter ( $ input );
} catch ( LexerException $ e ) {
// Unknown Token (LexerException::UNKNOWN_TOKEN)
} catch ( ParserException $ e ) {
// Invalid Token Type (Not String) (ParserException::INVALID_TOKEN_TYPE)
// Unknown Token (ParserException::UNKNOWN_TOKEN)
// Invalid Roman (ParserException::INVALID_ROMAN)
}
Вы можете использовать эту структуру для проверки римских чисел, добавив блок try..catch для проверки правильности $input
. Кроме того, вы можете проверить, можно ли отфильтровать целое int
к римскому, используя фильтр IntToRoman
.
use Romans Filter IntToRoman ;
use Romans Filter Exception as FilterException ;
$ filter = new IntToRoman ();
try {
$ filter -> filter ( $ input );
} catch ( FilterException $ e ) {
// Invalid Integer (< 0) (FilterException::INVALID_INTEGER)
}
Нулевое значение представлено как string
"N"
, начальная буква nulla или nihil , латинское слово, означающее «ничего» (см. ссылки).
use Romans Filter RomanToInt ;
use Romans Filter IntToRoman ;
$ filter = new RomanToInt ();
$ result = $ filter -> filter ( ' N ' ); // 0 (Zero)
$ filter = new IntToRoman ();
$ result = $ filter -> filter ( 0 ); // N
Этот пакет использует интерфейс кэширования PSR-6 для улучшения выполнения, в основном в циклах (например, while
или foreach
) с использованием библиотек кэша. Можно использовать любую реализацию PSR-6, и мы предлагаем пакет Symfony Cache.
use Romans Filter IntToRoman ;
use Romans Filter RomanToInt ;
use Symfony Component Cache Adapter ArrayAdapter ;
$ cache = new ArrayAdapter ();
$ filter = new RomanToInt ();
$ filter -> setCache ( $ cache );
$ result = $ filter -> filter ( ' MCMXCIX ' ); // 1999
$ result = $ filter -> filter ( ' MCMXCIX ' ); // 1999 (from cache)
$ filter = new IntToRoman ();
$ filter -> setCache ( $ cache );
$ result = $ filter -> filter ( 1999 ); // MCMXCIX
$ result = $ filter -> filter ( 1999 ); // MCMXCIX (from cache)
Вы можете использовать Docker Compose для создания образа и запуска контейнера для разработки и тестирования этого пакета.
docker-compose build
docker-compose run --rm romans composer install
docker-compose run --rm romans composer test
В этом разделе описываются методы, используемые этим пакетом для преобразования римских чисел в int
и наоборот.
Подход Lexer-Parser был выбран потому, что проверка и чтение римских чисел более упрощены: лексер отвечает за чтение и преобразование входных данных в токены, проверяя содержимое на уровне символов; а анализатор отвечает за преобразование токенов в числа, проверку содержимого на уровне позиции и преобразование в int
через DFA.
В Википедии говорится, что «лексический анализ — это процесс преобразования последовательности символов в последовательность токенов», то есть «это структура, представляющая лексему, которая явно указывает на ее категоризацию для целей синтаксического анализа». Даже в Википедии говорится, что «синтаксический анализ или синтаксический анализ — это процесс анализа символов, соответствующих правилам формальной грамматики».
Эта структура упрощает разработку структуры, ответственной за чтение входной string
, преобразование ее в другую структуру в соответствии с определенной кодировкой и ее положением внутри ввода.
DFA был разработан для проверки правильности string
с римским номером. Этот метод был выбран потому, что другие реализации просто преобразуют входные данные без проверки правил, например четыре символа последовательно.
Текущее определение автомата объявлено ниже.
M = (Q, Σ, δ, q0, F)
Q = { a, b, c, d, e, f, g, y, z }
Σ = { I, V, X, L, C, D, M, N }
q0 = g
F = { z }
z -> ε
y -> $z
a -> y | Iy | IIy | IIIy
b -> a | IVy | Va | IXy
c -> b | Xb | XXb | XXXb
d -> c | XLb | Lc | XCb
e -> d | Cd | CCd | CCCd
f -> e | CDd | De | CMd
g -> f | Ny | Mg
Этот пакет имеет открытый исходный код и доступен по лицензии MIT, описанной в разделе ЛИЦЕНЗИЯ.