检查素数的正则表达式

标签: 检查 素数 表达式 | 发表时间:2010-07-23 08:22 | 作者:酷壳 - CoolShell.cn Wesley
出处:http://srmeme.com/
玩聚SR还知道:
加星学习!
hawkGoogleReader
酷壳 - CoolShell.cn发表于2010-07-23 08:22:27

一般来说,我们会使用正规表达式来做字符串匹配,今天在网上浏览的时候,看到了有人用正则表达式来检查一个数字是否为素数(质数),让我非常感兴趣,这个正则表达式如入所示:

检查素数的正则表达式/^1?$|^(11+?) +$/

要使用这个正规则表达式,你需要把自然数转成多个1的字符串,如:2 要写成 “11”, 3 要写成 “111”, 17 要写成“11111111111111111”,这种工作使用一些脚本语言可以轻松的完成。

一开始我对这个表达式持怀疑态度,但仔细研究了一下这个表达式,发现是非常合理的,下面,让我带你来细细剖析一下是这个表达式的工作原理。

首先,我们看到这个表达式中有“|”,也就是说这个表达式可以分成两个部分:/^1?$/ 和 /^(11+?)\1+$/

  • 第一部分:/^1?$/, 这个部分相信不用我多说了,其表示匹配“非空串”以及字串中不只一个“1”的字符串。
  • 第二部分:/^(11+?)\1+$/,这个部分是整个表达式的关键部分。把否定条件“^”去掉,其可以分成两个部分,(11+?)\1+$,前半部很简单了,匹配以“11”开头的并重复0或n个1的字符串,后面的部分意思是把前半部分作为一个字串去匹配还剩下的字符串1次或多次(这句话的意思是——剩余的字串的1的个数要是前面字串1个数的整数倍)。

通过上面的分析,我们知道,第二部分是最重要的,对于第二部分,举几个例子,

示例一:判断自然数8。我们可以知道,8转成我们的格式就是“11111111”,对于(11+?),其匹配了“11”,于是还剩下“111111”,而\1+$正好匹配了剩下的“111111”,因为,“11”这个模式在“111111”出现了三次,符合模式匹配,返回true。取反(^),所以,得到false,于是这个数不是质数。

示例二:判断自然数11。转成我们需要的格式是“11111111111”(十一个1),对于(11+?),其匹配了“11”(前两个1),还剩下“111111111”(九个1),而\1+$无法为“11”匹配那“九个1”,因为“11”这个模式并没有在“九个1”这个串中正好出现N次。于是,我们的正则表达式引擎会尝试下一种方法,先匹配“111”(前三个1),然后把“111”作为模式去匹配剩下的“11111111”(八个1),很明显,那“八个1”并没有匹配“三个1”多次。所以,引擎会继续向下尝试……直至返回false。

通过示例二,我们可以得到这样的等价数算算法,正则表达式会匹配这若干个1中有没有出现“二个1”的整数倍,“三个1”的整数倍,“四个1”的整数倍……,而,这正好是我们需要的算素数的算法。现在大家明白了吧。

下面,我们用perl来使用这个正规则表达式不停地输出素数:(关于perl的语法我就不多说了)

perl -e'$|++;(1 x$_)!~/^1?$|^(11+?)\1+$/&&print"$_ "while ++$_'

另外,让我们来举一反三,根据上述的这种方法,我们甚至可以用正则表达式来求证某方式是否有解,如:

  • 二元方程:17x + 12y = 51   判断其是否有解的正则表达式是:^(.*)\1{16}(.*)\2{11}$
  • 三元方程:11x + 2y + 5z = 115 判断其是否有解的正则表达式是:^(.*)\1{10}(.*)\2{1}(.*)\3{4}$

大家不妨自己做做练习,为什么上述的两个正则表达式可以判断方程是否有解。如果无法参透其中的奥妙的话,你可以读读这篇英文文章

(全文完)

玩聚SR 是一个追踪各种社会化媒体,实时发现IT人都在分享和推荐什么的工具。点击阅读八卦频道热文。
手机请登录移动版

相关 [检查 素数 表达式] 推荐:

检查素数的正则表达式

- Wesley - 中文热文榜|最新
hawk 在 GoogleReader 说. 还有 ffan, football, 推荐,查看全部 33 个推荐 34 次分享. 酷壳 - CoolShell.cn发表于2010-07-23 08:22:27. 一般来说,我们会使用正规表达式来做字符串匹配,今天在网上浏览的时候,看到了有人用正则表达式来检查一个数字是否为素数(质数),让我非常感兴趣,这个正则表达式如入所示:.

正则表达式

- - CSDN博客推荐文章
    正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征. 比如 表达式“ab+” 描述的特征是“一个 'a' 和 任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征.     正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址.

新正则表达式

- Bloger - 博客园-首页原创精华区
很多网站需要将好的会员号留着,或用于日后的盈利. 实现方法不是本文讨论范围,本文仅列出用于检测靓号类型的一些正则.   靓号检测:主要可以检测连号(正连 12345、倒连65432)、AABB号、手机号码、日期号(生日号、年度号)、ABBCABB号,3位以上重复号. 更多类型号码检测可以根据以下表达式改造.

Spring笔记 - Spring Expression Language (SpEL表达式)

- - CSDN博客架构设计推荐文章
数字5       . 联合方式  . 浮点型      .

[Java 8] Lambda 表达式实例

- - Java - 编程语言 - ITeye博客
Java 8 中的 Lambda 表达式,允许将函数作为形参传递给另外的函数. 为了更好地理解,我们用实例的方式来演示如何使用 Lambda 表达式. 1、Lambda 表达式 Hello World. 这是一个最简单的 Lambda 表达式的例子. 首先在 main 方法的上面声明了一个接口 HelloWorld,在 main 方法中实现了这个接口,随后调用了接口的唯一方法.

vim中使用正则表达式

- - CSDN博客系统运维推荐文章
使用正则表达式的命令最常见的就是   / (搜索)命令. 另一个很有用的命令就是  :s(替换)命令,将第一个//之间的正则表达式替换成第二个//之间的字符串. :s/正则表达式/替换字符串/选项. 在学习正则表达式时可以利用  / 命令来练习. 元字符是具有特殊意义的字符. 使用元字符可以表达 任意字符、 行首、 行 尾、 某几个字符等意义.

Lambda表达式现状分析

- - InfoQ cn
距明年Java 8发布还有不到一年时间,Brian Goetz发布了最新的 Lambda表达式现状分析,涵盖了Java集合API的改进. Java 8最受期待的特性之一是引入了 Lambda表达式,Java集合API对它的重点支持是确保该类库被广泛使用的关键所在. 如果你不熟悉Lambda表达式的语法,请查看先前的一篇文章 Lambda表达式现状分析以及之前InfoQ的相关报道,以便了解该语法的详细内容.

Java8集合中的Lambda表达式

- - 四火的唠叨
文章系本人原创,转载请保持完整性并注明出自 《四火的唠叨》. 本文翻译自《 Java 8 Explained: Applying Lambdas to Java Collections》. Lambdas表达式是Java 8的主题,在Java平台上我们期待了很久. 但是,如果如果我们不在集合中使用它的话,就损失了很大价值.

js常用正则表达式

- - Web前端 - ITeye博客
js 常用正则表达式表单验证代码方法一:. var re=/正则表达式/;. $("txtid").val.match(/正则表达式/);. 验证数字的正则表达式集(转载). 验证数字:^[0-9]*$. 验证n位的数字:^\d{n}$. 验证至少n位数字:^\d{n,}$. 验证m-n位的数字:^\d{m,n}$.