En primer lugar, tenga en cuenta que esta expresión regular se aplica a los números representados en un sistema de conteo unario, es decir
1 is 1
11 is 2
111 is 3
1111 is 4
11111 is 5
111111 is 6
1111111 is 7
y así sucesivamente. Realmente, se puede usar cualquier caracter (de ahí el .
s en la expresión), pero usaré "1".
En segundo lugar, tenga en cuenta que esta expresión regular coincide con compuestos (no primos) números; por lo tanto, la negación detecta la primalidad.
Explicación:
El primer medio de la expresión,
.?
dice que las cadenas "" (0) y "1" (1) son partidos, es decir, no primer (por definición, though arguable.)
La segunda mitad, en inglés simple, dice s:
Haga coincidir el string más corto cuya longitud sea al menos 2, por ejemplo, "11" (2). Ahora, mira si podemos hacer coincidir toda la cadena repitiéndola. ¿Coincide "1111" (4)? ¿Coincide "111111" (6)? ¿"11111111" (8) coincide? Y así. De lo contrario, inténtelo nuevamente para la siguiente cadena más corta, "111" (3). Etc.
Ahora puede ver cómo, si la cadena original no puede ser igualada como múltiples de sus subseries, entonces, por definición, es primordial!
BTW, el operador no codicioso ?
es lo que hace que el "algoritmo" comience desde el más corto y cuente hacia arriba.
Eficiencia:
Es interesante, pero ciertamente no es eficiente, por varios argumentos, algunos de los cuales voy a consolidarse por debajo de:
Como notas @TeddHopp, el pozo -el enfoque conocido de tamiz-de-Eratosthenes no se molestaría en verificar múltiplos de enteros como 4, 6 y 9, habiendo sido "visitados" mientras se verificaban múltiplos de 2 y 3. Por desgracia, este enfoque de expresiones regulares comprueba exhaustivamente cada entero más pequeño.
Como señala @PetarMinchev, podemos "cortocircuitar" el esquema de comprobación de múltiplos una vez que llegamos a la raíz cuadrada del número. Deberíamos poder hacerlo porque un factor mayor que la raíz cuadrada debe asociarse con un factor menor que la raíz cuadrada (ya que de lo contrario dos factores mayores que la raíz cuadrada producirían un producto mayor que el número), y si esto existe un factor mayor, entonces ya deberíamos haber encontrado (y por lo tanto, igualado) el factor menor.
Como @Jesper y la nota @ Brian con concisión, desde una perspectiva no-algorítmica, considere cómo una expresión regular comenzaría por la asignación de memoria para almacenar la cadena, por ejemplo, char[9000]
para 9000. Bueno, eso fue fácil, ¿no? ;)
Como notas de @Foon, existen métodos probabilísticos que pueden ser más eficientes para números más grandes, aunque pueden no ser siempre correctos (apareciendo pseudoprimas en su lugar). Pero también hay pruebas determinísticas que son 100% precisas y mucho más eficientes que los métodos basados en tamices. Wolfram's tiene un buen resumen.
Ver: http://stackoverflow.com/questions/3329766/how-does-this-regular-expression-work – NullUserException
OK, retiro mi comentario. Es realmente extraño –
@NullUserException Gracias por el enlace. Supongo que veré si alguien puede responder la segunda parte de mi pregunta. – arshajii