Хабы: Программирование, Регулярные выражения, Алгоритмы
Как-то я исследовал способы наиболее эффективного определения простоты числа и наткнулся на показанный выше код.
Он меня заинтриговал. Хоть это, возможно, и не самый эффективный способ, но определённо один из наименее очевидных, поэтому мне стало любопытно. Каким образом соответствие регулярному выражению .?|(..+?)1+
должно показать, что число непростое (после его преобразования в унарную систему счисления)?
Если вы заинтересовались, продолжайте чтение, я проанализирую это регулярное выражение и объясню, что же в нём происходит. Объяснение не зависит от языка программирования, однако я приведу версии показанного выше Java
-кода на Python
, JavaScript
и Perl
и объясню, почему они немного различаются.
Я объясню, как регулярное выражение ^.?$|^(..+?)1+$
способно отфильтровывать все простые числа. Почему это выражение, а не .?|(..+?)1+
(использованное в примере кода на Java
)? Это связано с тем, как работает String.matches(), о чём я расскажу ниже.
Хотя по этой теме есть несколько постов, я считаю, что они недостаточно глубоки и в них приводится лишь высокоуровневое объяснение, недостаточно хорошо излагающее важные подробности. В своей статье я попытаюсь объяснить подробности, чтобы их мог понять любой. Моя цель — сделать этот код понятным каждому, будь вы гуру регулярных выражений или впервые о них услышали.
Читать далее