读了night_stalker老兄的
Ruby算法求优化:spoj PRIME1,深感自己对Ruby的性能特性了解的太少了。也试了些办法不过最多也就得到了10%左右的性能提升,没啥意义。
想想,干脆用F#来试试看。这个是F# 1.9.6.2,运行环境是HP nx9040/Windows 7 Beta Build 7000。随手写了一份代码,先通过记录已知的非质数得到sqrt(n)以内的质数表ps,然后用筛选法求m..n之间的质数:
#light
let primesBetween m n =
let pmax = int << sqrt << float <| n
let rec loop i ps kn =
if i > pmax then ps
else
let kn_next = List.fold_left (fun (acc : int Set) e -> acc.Add(e)) kn [i..i..pmax]
loop (i + 2) (if kn.Contains(i) then ps else i :: ps) kn_next
let ps = loop 3 [2] (Set [])
let mm = if m <= 2 then 3 else if m % 2 = 0 then m + 1 else m
let cand1 = List.init ((n - mm >>> 1) + 1) (fun i -> (i <<< 1) + mm)
let cand2 = cand1 |> List.filter (fun e ->
None = List.tryfind (fun p -> e % p = 0 && e <> p) ps)
if m <= 2 then 2 :: cand2 else cand2
open System.Diagnostics
let watch = new Stopwatch()
watch.Start()
let primes = primesBetween 999900000 1000000000
watch.Stop()
printfn "%A" primes
printfn "%A" watch.ElapsedMilliseconds
在我的机器上运行,速度居然跟Ruby 1.9.1差不多 OTL
引用
5425L
把第8行的List.fold_left和[i..i..pmax]换成对应的Seq版,Seq.fold和{i..i..pmax},速度只有很细微的提升。瓶颈是出在什么地方我也没弄清楚。
呜,太慢了。不过慢的主要原因应该还是我写的太糟糕了。
这种事情还是应该开多线程并行计算的好。改用比较原始的筛选法就有机会并行。以后有空再玩玩 T T
分享到:
相关推荐
算法-区间内的真素数(信息学奥赛一本通-T1411).rar
用来随机生成两个2~100之间的随机数a和b,找出区间[a,b] (a)内的素数,并用列表保存,输出前5个素数和该5个素数的均值,保留两位小数。如果该区间内不足5个素数,重新生成区间并重复以上过程。以
程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。 代码如下:#include <stdio>#include <math.h> void main(){ int low,high,t=0; printf(“请...
针对传统配分函数难以处理分割子区间长度s不为时间序列长度T的约数或者T为质数的情况,采用类似多重分形去趋势波动法(MFDFA)的操作方式,提出修正配分函数法....
计算前 m 个函数 J'm 的前 k 个零的表。 这里Jm是整数阶m的第一类Bessel函数,而J'm是其导数。 这些函数出现在许多涉及圆柱几何的问题中。 使用了一个简单的二分算法,因为它允许构造区间来支撑每个连续的根。
4 3 区间内的重复内容 54 4 4 区间的最大总和 55 4 5 查询区间中的最小值:线段树 55 4 6 计算区间的总和:树状数组(Fenwick 树)57 4 7 有 k 个独立元素的窗口 59 第 5 章 区间 61 5 1 区间树(线段树) 61 5 2 ...
轻松构建矩阵,找到素数形式和区间类向量。 比较音高或音高类别集与各种相似关系 探索非标准音调类空间。 要求 没有对sator的要求。 安装 Sator在上可用,因此安装它的最简单方法是使用 : pip install sator ...
(1) 编制一个函数sab(a,b,n),其功能是求函数f(x)在[a,b]上的定积分,其中n为区间[a,b]的等分数。要求该函数在一个独立的文件中。 (2) 编制一个主函数以及计算被积函数值的函数f(x),在主函数中调用(1)中的函数计算...
<br>实验四 综合(课程设计) 内容及步骤: 1、假定一维数组a[n]中的每个元素值均在[0,200]区间内,用C++编写一个算法,分别统计出落在[0,20],[21,50],[51,80],[81,130],[131,200]等各区间内的元素...
实例227 T分布常用计算 285 10.3 Commons IO组件简介 286 实例228 简化文件(夹)删除 286 实例229 简化文件(夹)复制 287 实例230 简化文件(夹)排序 288 实例231 简化文件(夹)过滤 289 实例232 简化文件的读写...