检查素数的正则表达式[转]

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

检查素数与否的正则表达式算法

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

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

首先,咱们看到这个表达式中有“|”,也就是说这个表达式能够分红两个部分:/^1?$/ 和 /^(11+?)\1+$/code

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

可见这个正规则表达式是取非素数,要获得素数还得要对整个表达式求反。经过上面的分析,咱们知道,第二部分是最重要的,对于第二部分,举几个例子,blog

 

示例一:判断天然数8。咱们能够知道,8转成咱们的格式就是“11111111”,对于(11+?),其匹配了“11”,因而还剩下“111111”,而\1+$正好匹配了剩下的“111111”,由于,“11”这个模式在“111111”出现了三次,符合模式匹配,返回true。因此,匹配成功,因而这个数不是质数。ci

示例二:判断天然数11。转成咱们须要的格式是“11111111111”(十一个1),对于(11+?),其匹配了“11”(前两个1),还剩下“111111111”(九个1),而\1+$没法为“11”匹配那“九个1”,由于“11”这个模式并无在“九个1”这个串中正好出现N次。因而,咱们的正则表达式引擎会尝试下一种方法,先匹配“111”(前三个1),而后把“111”做为模式去匹配剩下的“11111111”(八个1),很明显,那“八个1”并无匹配“三个1”屡次。因此,引擎会继续向下尝试……直至尝试全部可能都没法匹配成功。因此11是素数。字符串

经过示例二,咱们能够获得这样的等价数算算法,正则表达式会匹配这若干个1中有没有出现“二个1”的整数倍,“三个1”的整数倍,“四个1”的整数倍……,而,这正好是咱们须要的算素数的算法。如今你们明白了吧。get

下面,咱们用perl来使用这个正规则表达式不停地输出素数:(关于perl的语法我就很少说了,请注意表达式前的取反操做符)string

1
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}$

你们不妨本身作作练习,为何上述的两个正则表达式能够判断方程是否有解。若是没法参透其中的奥妙的话,你能够读读这篇英文文章

(全文完)

(转载本站文章请注明做者和出处 酷 壳 – CoolShell.cn ,请勿用于任何商业用途)

相关文章
相关标签/搜索