J
jeffrey_s
Unregistered / Unconfirmed
GUEST, unregistred user!
使用类似压缩,查表 和 位操作,速度比我前面的稍快一点。基本思想同上一个是一样的。
const MMax = 20000000;
var
Bit: array [0..MMax div 30 + 1] of Byte
function CountPrimeNumber2: Integer;
const
Point: array [0..7] of Byte = (1,7,11,13,17,19,23,29);
Reflect: array [1..30] of Byte =
//1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
(0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,3,4,4,5,5,5,5,6,6,6,6,6,6,7,7);
Offset: array [1..29] of Byte =
// 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
($01,0,0,0,0,0,$02,0,0,0,$04,0,$08,0,0,0,$10,0,$20,0,0,0,$40,0,0,0,0,0,$80);
var
ki, i, kj, j, vi, M, vv: Cardinal;
begin
FillChar(Bit, Sizeof(Bit), $00);
Bit[0] := $01
// 1 不处理
for ki := 0 to Round(Sqrt(MMax)/30) do
for i := 0 to 7 do
if (Bit[ki] and Offset[Point]) = 0 then
begin
vi := ki*30 + Point;
M := MMax div vi - 1;
kj := M div 30
//30 当成 29 处理
j := Reflect[M mod 30 + 1];
while (kj > ki) or ((kj = ki) and (j >= i)) do
begin
if (Bit[kj] and Offset[Point[j]]) = 0 then
begin
vv := vi * (kj * 30 + Point[j]);
Inc(Bit[vv div 30], Offset[vv mod 30]);
end;
if j > 0 then
Dec(j)
else begin
j := 7;
Dec(kj);
end;
end;
end;
Result := 3
//2, 3, 5
for ki := 0 to MMax div 30 - 1 do
for i := 0 to 7 do
if (Bit[ki] and Offset[Point]) = 0 then //Num = ki * 30 + Point
Inc(Result);
ki := MMax div 30;
for i := 0 to 7 do
begin
if ki * 30 + Point > MMax then Exit;
if (Bit[ki] and Offset[Point]) = 0 then //Num = ki * 30 + Point
Inc(Result);
end;
end;
const MMax = 20000000;
var
Bit: array [0..MMax div 30 + 1] of Byte
function CountPrimeNumber2: Integer;
const
Point: array [0..7] of Byte = (1,7,11,13,17,19,23,29);
Reflect: array [1..30] of Byte =
//1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
(0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,3,4,4,5,5,5,5,6,6,6,6,6,6,7,7);
Offset: array [1..29] of Byte =
// 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
($01,0,0,0,0,0,$02,0,0,0,$04,0,$08,0,0,0,$10,0,$20,0,0,0,$40,0,0,0,0,0,$80);
var
ki, i, kj, j, vi, M, vv: Cardinal;
begin
FillChar(Bit, Sizeof(Bit), $00);
Bit[0] := $01
// 1 不处理
for ki := 0 to Round(Sqrt(MMax)/30) do
for i := 0 to 7 do
if (Bit[ki] and Offset[Point]) = 0 then
begin
vi := ki*30 + Point;
M := MMax div vi - 1;
kj := M div 30
//30 当成 29 处理
j := Reflect[M mod 30 + 1];
while (kj > ki) or ((kj = ki) and (j >= i)) do
begin
if (Bit[kj] and Offset[Point[j]]) = 0 then
begin
vv := vi * (kj * 30 + Point[j]);
Inc(Bit[vv div 30], Offset[vv mod 30]);
end;
if j > 0 then
Dec(j)
else begin
j := 7;
Dec(kj);
end;
end;
end;
Result := 3
//2, 3, 5
for ki := 0 to MMax div 30 - 1 do
for i := 0 to 7 do
if (Bit[ki] and Offset[Point]) = 0 then //Num = ki * 30 + Point
Inc(Result);
ki := MMax div 30;
for i := 0 to 7 do
begin
if ki * 30 + Point > MMax then Exit;
if (Bit[ki] and Offset[Point]) = 0 then //Num = ki * 30 + Point
Inc(Result);
end;
end;