查詢n內的所有素數,首先想到的就是:
對整數n從2開始到sqrt(n),進行整除計算,能整除則計算n+1,然後迴圈。方法簡單,但效率低下。1000,000內的素數個數:
#!/usr/bin/perl -w
usestrict;
my$num=1000001;my
$count=0
;while($num>1
)
$count++ if($j>$i
);
$num-=2;}
$count,"
\n";
[root@centos1 pl_script]# timeperl
test.pl
78497
real 0m21.230s
user 0m21.150s
sys 0m0.049s
對比c程式的同等演算法:
#include #include#define num 1000000main()
if(j>k)cnt++;
} printf(
"%d\n
",cnt);
}
執行效率:
[root@centos1]# time ./prime78497
real 0m0.376s
user 0m0.355s
sys 0m0.017s
c語言果然快,不算好的演算法速度也是槓槓的。
改進演算法:排除所有素數的倍數,剩下的就是素數了。
使用乙個陣列,下標與1000,000內的數一一對應,
1、將陣列中所有偶數下標值置0;
2、從3開始,將所有3的倍數下標置0;
3、迴圈,將全部素數的倍數下標置0
**如下:
#!/usr/bin/perl -w
usestrict;
use constant num=>1000000;#
新建陣列,下標與數字一一對應,並排除偶數
my@arr=map(0..num);
$arr[1]=0;#
從3開始,排除3的倍數
for(my
$i=3;$i
<=sqrt(num);$i+=2)}
#選出不為0的
@arr=grep@arr
scalar(@arr),"
\n";
測試輸出:
[root@centos1 pl_script]# timeperl
prime.pl
78497
real 0m2.714s
user 0m2.422s
sys 0m0.266s
c同等演算法:
#include #include#define num 1000000
char arr[num+1
];main()
效率如飛:
[root@centos1]# time ./enhance_prime78497
real 0m0.069s
user 0m0.046s
sys 0m0.022s
趣味:正規表示式計算質數:
^1?$|^(11+?)\1+$
表示式中有「|」,也就是說這個表示式可以分成兩個部分:/^1?$/ 和 /^(11+?)\1+$/
第一部分:/^1?$/, 其表示匹配「空串」以及字串中只有乙個「1」的字串。
第二部分:/^(11+?)\1+$/,這個部分是整個表示式的關鍵部分。其可以分成兩個部分,(11+?)和\1+$,前半部很簡單了,匹配以「11」開頭的並重複0或n個1的字串,後面的部分意思是把前半部分作為乙個字串去匹配還剩下的字串1次或多次(這句話的意思是——剩餘的字串的1的個數要是前面字串1個數的整數倍)。
要使用這個正規則表示式,需要把自然數轉成多個1的字串,如:2 要寫成 「11」, 3 要寫成 「111」,以下是perl表示式:
perl -e '$|=1;(1x$_)!~/^1?$|^(11+?)\1+$/ && print"$_ " while ++$_'
快速查詢素數
題目 時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 現在給你乙個正整數n,要你快速的找出在2.n這些數裡面所有的素數。輸入給出乙個正整數數n n 2000000 但n為0時結束程式。測試資料不超過100組 輸出將2 n範圍內所有的素數輸出。兩個數之間用空格隔開 樣例輸入 5...
快速查詢素數
快速查詢素數 時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述現在給你乙個正整數n,要你快速的找出在2.n這些數裡面所有的素數。輸入給出乙個正整數數n n 2000000 但n為0時結束程式。測試資料不超過100組 輸出將2 n範圍內所有的素數輸出。兩個數之間用空格隔開 樣例輸...
快速查詢素數
我們以前判斷素數是從2到這個數的平方根一直檢查是否是素數。include include include includeusing namespace std int main if f 1 printf yes n else printf no n 現在如果數很大的話我們可以把每個數的倍數去掉就行...