利用正規表示式檢查素數

2021-06-17 21:54:56 字數 1282 閱讀 9226

本帖最後由 遇見sharon 於 2013-8-12 17:09 編輯

一般來說,我們會使用正規表示式來做字串匹配,今天在網上瀏覽的時候,看到了有人用正規表示式來檢查乙個數字是否為素數(質數),讓我非常感興趣,這個正規表示式如入所示:

要使用這個正規則表示式,你需要把自然數轉成多個1的字串,如:2 要寫成 「11」, 3 要寫成 「111」, 17 要寫成「11111111111111111」,這種工作使用一些指令碼語言可以輕鬆的完成。

一開始我對這個表示式持懷疑態度,但仔細研究了一下這個表示式,發現是非常合理的,下面,讓我帶你來細細剖析一下是這個表示式的工作原理。

首先,我們看到這個表示式中有「|」,也就是說這個表示式可以分成兩個部分:/^1?$/ 和 /^(11+?)\1+$/

可見這個正規則表示式是取非素數,要得到素數還得要對整個表示式求反。通過上面的分析,我們知道,第二部分是最重要的,對於第二部分,舉幾個例子,

示例一:判斷自然數8。我們可以知道,8轉成我們的格式就是「11111111」,對於(11+?),其匹配了「11」,於是還剩下「111111」,而\1+$正好匹配了剩下的「111111」,因為,「11」這個模式在「111111」出現了三次,符合模式匹配,返回true。所以,匹配成功,於是這個數不是質數。

示例二:判斷自然數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」的整數倍……,而,這正好是我們需要的算素數的演算法。現在大家明白了吧。

下面,我們用perl來使用這個正規則表示式不停地輸出素數:(關於perl的語法我就不多說了,請注意表示式前的取反操作符)

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

複製**

另外,讓我們來舉一反三,根據上述的這種方法,我們甚至可以用正規表示式來求證某方式是否有解,如:

大家不妨自己做做練習,為什麼上述的兩個正規表示式可以判斷方程是否有解。如果無法參透其中的奧妙的話,你可以讀讀這篇英文文章。

檢查素數的正規表示式

一般來說,我們會使用正規表示式來做字串匹配,今天在網上瀏覽的時候,看到了有人用正規表示式來檢查乙個數字是否為素數 質數 讓我非常感興趣,這個正規表示式如入所示 檢查素數與否的正規表示式 要使用這個正規則表示式,你需要把自然數轉成多個1的字串,如 2 要寫成 11 3 要寫成 111 17 要寫成 1...

正規表示式 正規表示式 總結

非負整數 d 正整數 0 9 1 9 0 9 非正整數 d 0 負整數 0 9 1 9 0 9 整數 d 非負浮點數 d d 正浮點數 0 9 0 9 1 9 0 9 0 9 1 9 0 9 0 9 0 9 1 9 0 9 非正浮點數 d d 0 0 負浮點數 正浮點數正則式 英文本串 a za z...

奇淫怪巧 利用正規表示式判斷素數

最近在學習正規表示式,偶然間看到利用正規表示式判斷乙個數是不是素數的帖子。當時就震驚了,覺得好神奇。那個判斷素數的函式是這樣子的 public static bool isprime int i 有沒有覺得很神奇?我當時就覺得相當的有想象力的一種實現。那讓我們看一下這個正規表示式是如何做判斷素數的。...