以下是代码:
public static boolean isPrime(int n) {
return !new String(new char[n]).matches(".?|(..+?)\\1+");
}
有人可以告诉我正则表达式用英语翻译的内容并解释它的工作原理吗?
答案 0 :(得分:2)
回想一下素数是什么以及它不是什么。首先,这会否定正则表达式匹配,因此正则表达式匹配复合数字。
首先创建一个长度为 n 的字符串,只要它们与.
匹配,它的字符就无关紧要。
这意味着该号码为0
或1
(不是素数):
.?
或它必须有两个除数大于一:
(..+?)\1+
第一个除数由捕获组(..+?)
处理,它将匹配至少两个字符(即表示大于或等于2的数字)。 +?
是一个懒惰的量词,因此它会尝试尽可能少地匹配;这可能只是加快了这个过程。
\1
是与第一组匹配的完全相同的反向引用,使用+
至少重复一次。这种重复代表了要检查的数字的第二个因素。因此,如果该组匹配 a 字符而\1+
重复此 b - 1次您自己代表 a ċ< EM> b'/ em>的。如果匹配, n 是一个复合数,因此不是素数。
正则表达式在尝试创建匹配时进行回溯,因此如果它不能与包含两个字符的\1
一起使用,则会尝试使用三个,四个等等,直到找到匹配项或者该组捕获更多超过一半的字符串。
所以,例如对于14,该组将匹配两个字符,然后\1
将重复七次,模仿要测试的数字的因子。由于这匹配它具有除自身和因子之外的因素,因此不是素数。
5将尝试使用组中的两个字符,然后三个并放弃(因为aaa
在aaaaa
中不能存在多次)。因此,五个是素数。
Here is a more thorough explanation,虽然一旦你用数学的方法弄明白这一点,它就显得非常明显而且微不足道。
答案 1 :(得分:1)
.?
是一个或没有字符
(..+?)
至少有2个字符但是有一个不情愿的限定符(意思是它试图匹配尽可能少的字符),括号表示它是一个捕获组
\\1+
至少重复一次捕获组
这意味着正则表达式只匹配0,1的字符串或2个或更多的任何非平凡倍数(2或更多)
换句话说,如果n可以写为k*l
且k
和l
大于或等于2(非素数的属性之一),则匹配< / p>
然而,这样做更容易
for(int i=2;i*i<=n;i++)if(n%i ==0)return false;
return true;
它完全相同,但会更快停止(sqrt(n)
而不是n
)