Greatest

All about 非主流脑残技术

导航

一个判断是否为质数的正则表达式

这个神奇的正则表达式就是:/^1?$|^(11+?)\1+$/ 

首先这个东西的出处在这里:http://www.noulakaz.net/weblog/2007/03/18/a-regular-expression-to-check-for-prime-numbers/

原来这个正则表达式是Perl的,在上面的地址中,那个作者用Ruby改写了。为了让大家看得明白,这里我用Javascript改写一下:

function isprime(n)
{
    
var s = '';
    
for(i=0;i<n;++i) s+='1';
    
return !/^1?$|^(11+?)\1+$/.test(s);
}

 

下面,我将一半翻译,一半自己的理解来解释一下这个正则表达式为什么能判断是否为质数。

先看一下上面的isprime 函数,它将按照n,生成一个n个'1'的字符串,然后交给这个正则表达式来判断。这个正则表达式匹配任何“非质数”个"1"的字符串。

此正则表达式分成由"|"分割两部分 /^1?$/和/^(11+?)\1+$/。

 

/^1?$/ 很明显是匹配空字符串或者"1",也就是n==0或n==1,这2个不是质数。

 

下面来解析一下后面那部分,/^(11+?)\1+$/ 。

它首先匹配(11+?),然后\1是对前面(11+?)匹配部分的引用,也就是\1+的意思就是前面(11+?)匹配的部分至少重复1次。

其次,(11+?) 匹配的是至少两个1,也就是"11","111","1111"这样的字符串。

这样就很明显了,如果X=(11+?)匹配的内容(假定为x个"1"),那么后半部分的正则表达式就可以写成/XX+/也就是至少2个X(假定为k个X)。那么,整个就是匹配k*x个1(x>=2,k>=2),很明显k*x不是质数,而且也不会是2.而且由于正则表达式匹配的方式,它会通过backtrace穷举所有可能的k和x来匹配输入的n个"1",所以如果不匹配那就只剩下质数了。

posted on 2010-07-21 11:09  Greatest  阅读(5311)  评论(15编辑  收藏  举报