用q實現篩法求1-n的質數
篩法是一種求一個範圍內的質數的方法。思路是:先列出1-n之間的全體整數, 然後依次劃去2的倍數(不包括2)、3的倍數...一直到sqrt(n)取整的倍數。 自然地,我們有第一種使用列表的方法:
lsieve:{t:1+til x; //初始化1-x列表
n:2; //要劃去的數字
do["j"$sqrt(x);
k:n-1; //要劃去的數字的索引下標
do["j"$(x%n)-1;
if[x>k+n;t[k:k+n]:0] //所有的倍數都設定標誌0
];
n:n+1
];
t[0]:0; //1不是質數
1+(where t<>0)} //返回所有標誌不為0的元素組成的列表
觀察這個方法,我們發現有一些多餘操作,比如:
1.所有偶數n的倍數在n=2時,都已經劃去了,因此n從3開始,只需要劃奇數n。
2.作為倍數,偶數倍也都在n=2時劃去了,因此n從3開始,只需要劃去它的奇數倍。
3.除2外,所有質數都是奇數,根本不用劃,因此只要構造1-x之間的奇數列表。劃完倍數後補充2即可。
q語言的程式通常在一行中,因此下面給出原始演算法0,改進1,改進1+2,改進1+2+3的語句:
lsieve0:{t:1+til x;n:2;do["j"$sqrt(x);k:n-1;do["j"$(x%n)-1;if[x>k+n;t[k:k+n]:0]];n:n+1;];t[0]:0;1+(where t<>0)}
lsieve1:{t:1+til x;n:2;do["j"$sqrt(x);k:n-1;do["j"$(x%n)-1;if[x>k+n;t[k:k+n]:0]];$[n=2;n:n+1;n:n+2]];t[0]:0;1+(where t<>0)}
lsieve2:{t:1+til x;n:2;do["j"$(sqrt(x)%2)+1;k:n-1;do["j"$(x%n)-1;$[n=2;if[x>k+n;t[k:k+n]:0];if[x>k+n+n;t[k:k+n+n]:0]]];$[n=2;n:n+1;n:n+2]];t[0]:0;1+(where t<>0)}
lsieve3:{t:1+2*til "j"$(x%2);n:3;do["j"$(sqrt(x)%2)+1;k:"j"$((n*n)-1)%2;do["j"$((x%n)%2)-1;if[(x%2)>k;t[k]:0];k:k+n];n:n+2];t[0]:0;2,(1+2*(where t<>0))}
q)\t lsieve0 500000
1761
q)\t lsieve1 500000
1106
q)\t lsieve2 500000
1075
q)\t lsieve3 500000
966
一個老外的天書寫法原文連線
soe:{[t] if[0<count t;$[(t[0]>sqrt last t);:t;[k:t[0]; t:1_t; :k,.z.s raze each[{$[0=x mod y;();:x]}[;k]] t]]]}
sieve:{soe 2+til(x-1)}
q)sieve 53
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53
解釋:
(待補充)
相關文章
- 篩選法求質數
- 電影裡的程式碼之《機械姬》:篩法求質數
- 用切片操作實現的Python篩法Python
- 約束定理+質數篩
- 用一個巨集實現求兩個數中的最大數
- [演算法]: 素數篩法演算法
- 用Axure實現對時間段的篩選
- 求最大質因數
- 用python求第1000個質數的值Python
- JavaScript如何求陣列的質數JavaScript陣列
- 面試官本拿求素數搞我,但被我用素數篩優雅的“回擊“了面試
- 求素數(質數)演算法演算法
- 數論線性篩總結 (素數篩,尤拉函式篩,莫比烏斯函式篩,前n個數的約數個數篩)函式
- c++實現求眾數及其重數C++
- 用whistle實現Abort請求
- 正規表示式實現的從字串中篩選出數字字串
- 用js實現將float型的科學計數法數字還原為正常寫法JS
- 用中值排序基數法實現樹狀結構 (轉)排序
- Flutter實現自定義篩選框Flutter
- 面試官本拿求素數搞我,但被我優雅的“回擊“了(素數篩)面試
- 使用 Promise 實現任務佇列傳送請求,實現最大請求數目限制Promise佇列
- C# 輸入一個整數,求質因數C#
- (演算法)求1到1億間的質數或素數演算法
- Python演算法實現質數(素數)判斷Python演算法
- 特效實現用查表法實現對水波的模擬(轉)特效
- Python實現求第6個默尼森數Python
- 用原型實現Class的各項語法原型
- 求一個數的二進位制數中所含1的個數的程式碼實現
- scheme 求平方根函式 sqrt 牛頓法實現Scheme函式
- 請求引數為物件,mybatis的sql寫法物件MyBatisSQL
- 求兩個正整數的最大公約數與最小公倍數--C#實現C#
- 用SQL實現Farey數列SQL
- 用C#實現二進位制的減法(包括二進位制小數)C#
- 用連結串列的方式實現大數相減-Java實現Java
- Codeforces 893E Counting Arrays:dp + 線性篩 + 分解質因數 + 組合數結論
- 漫遊 javax.servlet 請求引數解析(jetty 實現)JavaServletJetty
- 如何用位運算實現整數的加減法
- Element-UI Table 實現篩選資料功能UI