素数筛法系列之3 减少筛次数
来源:互联网 发布:网络安全法的心得体会 编辑:程序博客网 时间:2024/06/10 14:51
//筛法加速
接上一节, 筛某个素数的倍数的时候只需筛掉奇数倍数, 这样计算量可
可减少一般, 再进一步优化, 不筛3的倍数, 只筛6k+1, 6k+5 之类素数,
计算量只有原来2/3.
static void crossOutFactorMod6(uchar bitarray[], const uint64 start,
const int leng, int factor)
{
int s1 = factor - start % factor;
if (s1 % 2 == 0) {
s1 += factor;
} else if (start <= factor) {
s1 += 2 * factor;
}
//筛除3的倍数
const int bits = leng >> 1;
if (factor <= 3) {
for (s1 >>= 1; s1 <= bits; s1 += factor) {
SET_BIT(bitarray, s1);
}
return ;
}
const int mrid6 = ((start + s1) / factor) % 6;
s1 >>= 1;
int s2 = s1;
if (mrid6 == 1) {
s2 += factor * 2;
} else if (mrid6 == 3) {
s1 += factor;
s2 += factor * 2;
} else {
s2 += factor;
}
//6k + 1, 6k + 5 number will be corssed out
for (factor *= 3; s2 <= bits;) {
SET_BIT(bitarray, s1); s1 += factor; //6k + 1
SET_BIT(bitarray, s2); s2 += factor; //6k + 5
}
if (s1 <= bits) {
SET_BIT(bitarray, s1);
}
}
//比上面的模6进一步, 采用模30的筛法, 计算量再减小1/5.(1/3 ----> 8/30)
static void crossOutFactorMod30(uchar bitarray[], const uint64 start,
const int leng, int factor)
{
int offset = factor - start % factor;
if (offset % 2 == 0) {
offset += factor;
} else if (start <= factor) {
offset += 2 * factor;
}
//筛除3,5的倍数
const int bits = leng >> 1;
if (factor <= 5) {
for (offset >>= 1; offset <= bits; offset += factor) {
SET_BIT(bitarray, offset);
}
return ;
}
int rid30 = (offset + start) / factor % 30;
//找到第一个数为30k + 1的数offset
while (rid30 < 31 & offset < leng) {
SET_BIT(bitarray, offset / 2); offset += factor * 2;
rid30 += 2;
}
//按模30余1,7,11,13,1,19,23,29的筛
offset >>= 1;
while (offset + 15 * factor <= bits) {
SET_BIT(bitarray, offset); offset += factor * 3; //30k + 1
SET_BIT(bitarray, offset); offset += factor * 2; //30k + 7
SET_BIT(bitarray, offset); offset += factor * 1; //30k + 11
SET_BIT(bitarray, offset); offset += factor * 2; //30k + 13
SET_BIT(bitarray, offset); offset += factor * 1; //30k + 17
SET_BIT(bitarray, offset); offset += factor * 2; //30k + 19
SET_BIT(bitarray, offset); offset += factor * 3; //30k + 23
SET_BIT(bitarray, offset); offset += factor * 1; //30k + 29
}
//筛除剩下几个.
uint m = 0x13212123;//模30余数, 4bit压缩
while (offset <= bits) {
SET_BIT(bitarray, offset); offset += factor * (m & 15);
//循环移位
m = (m >> 4) | (m << 28);
}
}
测试表明这两个函数实现比原来奇数版本快近1/3, 基本符合预期.
在循环里面每次筛的更多,减小循环也提高性能(相当于收到循环展开)
- 素数筛法系列之3 减少筛次数
- 素数筛法系列
- 素数筛法系列之4 预先删除小素数
- 素数筛法系列之1 简单筛法实现
- 素数筛法系列之2 分段筛法思想
- 素数筛法系列之5 完整实现
- 素数筛法系列之5 完整实现2
- HDU-#1239、2136、2138 HDU素数筛法系列
- 排序法系列之三---选择排序
- 排序法系列之七---基数排序法C++代码实现
- 排序法系列之四---合并排序法
- 5-2-3 素数-减少循环次数-平方根使用方法-i++-构造素数表--2x-3x-4x-...
- 排序法系列之六---堆排序(C++代码实现)
- 排序法系列之五---快速排序法(C++代码实现)
- 排序法系列之一-----冒泡排序法
- 数据库性能提升之减少访问数据库次数
- 数据库性能提升之减少访问数据库次数
- .net 性能优化之减少连接数据次数
- 关于weblogic10.3下weblogic.utils.NestedRuntimeException: Cannot parse POST parameters of request问题
- Android WebView的缓存!!!
- C++新手必问之头文件
- 读文有感 :别和傻逼较劲,他们会把你也降格为傻逼,然后用经验打败...
- Hsql模糊查询3种方式
- 素数筛法系列之3 减少筛次数
- hdu1753----大明A+B
- 在myeclilpse7.5中启动tomcat7.0.6报错java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory的解决方案
- Iis6.0 ,ii5.1下asp.net mvc 部署
- POJ-Anagrammatic Distance-字母距离
- VB获取指定长度的随机字符串
- 在VS2005 /VS2008下调试应用程序的两种途径
- 求模线性方程的一个有力定理
- TUP对话大师系列:微软技术大师Jeffrey Richter(现场实录)