1亿以内素数的个数_一亿中有多少个质数?

续接前文,通过erlang的并发方式计算并获取质数序列

%% @author ANDY

%% @doc @todo Add description to eg003.

-module(eg003).

-compile({no_auto_import,[length/1]}).

%%

====================================================================

%% API functions

%%

====================================================================

-export([sum/1,

ranges/3,

is_prime_number/1,

pns_2toN/1,

pns_NtoM/2,

rangeN/2,

c_pns_NtoM/4,

get_pn_lst/2,

get_pn_NtoM/2,

all_the_proper_divisors/1,

sum_proper_divisors/1,

list_perfect_numbers/1,

list_amicable_numbers/1,

list_amicable_numbers/2,

list_prime_numbers/1,

list_nums/1,

list_of_prime_numbers_2toN/1,

length/1,

show/1]).

%%

====================================================================

%% Internal functions

%%

====================================================================

%辅助函数,对列表求和

sum(Alist) -> sum(Alist, 0).

sum([], N) -> N;

sum([H|T], N) -> sum(T, H + N).

%range(N, N) -> [N];

%range(Min, Max) -> [Min | range(Min + 1, Max)].

%range({A, B}) -> range(A, B).

%辅助函数,生成整数序列

range(A, B) -> range(B, A, []).

range(N, N, L) -> [N|L];

range(Max, Min, L) -> range(Max - 1, Min, [Max | L]).

%辅助函数,生成间距S的整数序列

ranges(A, B, S) -> ranges(B, A, [], S).

ranges(Max, Min, L, _) when Max < Min -> L;

ranges(Max, Min, L, S) when Max < Min + S -> [Min|L];

ranges(Max, Min, L, S) -> ranges(Max, Min + S, [Min | L],

S).

%获得N的全部约数

all_the_proper_divisors(N) -> % N > 6!

Range = range(1, N div 2),

[X || X

%获得N的全部约数的和

sum_proper_divisors(N) ->

sum(all_the_proper_divisors(N)).

%获得2至N的质数序列,记作方式1

list_prime_numbers(N) -> % N > 1

[X || X

=:= 1].

%获得6至N的完全数序列

list_perfect_numbers(N) -> % N > 6

[X || X

sum_proper_divisors(X)].

%获得6至N的亲和数序列

list_amicable_numbers(N) -> % N > 6

[{X, sum_proper_divisors(X)} || X

N),

X

< sum_proper_divisors(X),

X

=:= sum_proper_divisors(sum_proper_divisors(X))].

%获得Min至Max的亲和数序列

list_amicable_numbers(Min, Max) -> % N > 6

[{X, sum_proper_divisors(X)} || X

range(Min, Max),

X

< sum_proper_divisors(X),

X

=:= sum_proper_divisors(sum_proper_divisors(X))].

%辅助函数,显示数据

show(Value) -> io:format("It is ~p~n", [Value]).

%测试函数

list_nums(N) ->

show([{X, sum_proper_divisors(X)} || X

range(6, N)]).

%实现获取2至N的质数序列,记作方式2

list_of_prime_numbers_2toN(N) -> list_of_prime_numbers(range(2,

N)).

list_of_prime_numbers([H]) -> [H];

list_of_prime_numbers([H|T]) -> [H |

list_of_prime_numbers(update_list(H, T))].

update_list(H, T) -> reverse(update_list(H, T, [])).

update_list(_, [], L) -> L;

update_list(H, [He|T], L) ->

case (He rem H =:= 0) of

true -> update_list(H, T,

L);

false -> update_list(H, T,

[He|L])

end.

%辅助函数,获得序列的逆序

reverse(L) -> reverse(L, []).

reverse([], L) -> L;

reverse([H|T], L) -> reverse(T, [H|L]).

%辅助函数,获得序列的长度

length(L) -> length(L, 0).

length([], R) -> R;

length([_|T], R) -> length(T, R + 1).

%辅助函数,判断整数N是否为偶数

even(N) -> if N rem 2 == 0 -> true;

N rem 2 /= 0 -> false

end.

%子函数,判断整数N是否为质数,记作方式3

is_prime_number(N) ->

case even(N) of

true -> if N == 2 ->

true;

N /= 2 -> false

end;

false -> T =

trunc(math:sqrt(N)),

if N == 3 -> true;

N

/= 3 -> is_pn0(3, T, N)

end

end.

is_pn0(V, T, N) when T < V + 2 -> if N rem V == 0 ->

false;

N rem V /= 0 -> true

end;

is_pn0(V, T, N) -> if N rem V == 0 -> false;

N rem V /= 0 -> is_pn0(V + 2, T, N)

end.

%获得2至N的质数序列

pns_2toN(N) -> % N > 2

L = [E || E

is_prime_number(E) == true],

[2|reverse(L)].

%获得N至M的质数序列

pns_NtoM(N, M) ->

case even(N) of

true -> if N == 2

->

[E || E

[2];

N /= 2 ->

[E || E

true]

end;

false -> [E || E

ranges(N, M, 2), is_prime_number(E) == true]

end.

%子函数, 获得N至M的质数序列

c_pns_NtoM(Pid, N, M, V) ->

case even(N) of

true -> if N == 2

->

L = [E || E

++ [2],

Pid ! {lst, L, V};

N /= 2 ->

L = [E || E

true],

Pid ! {lst, L, V}

end;

false ->

L = [E || E

Pid ! {lst,

L, V}

end.

%子函数, 获得完整质数序列

get_pn_lst(L, N) ->

receive

{lst, M, V} when V == N + 1

->

{ok, File} =

file:open("res.txt", write),

io:format(File,

"~p~n~nlength: ~p~n", [[M|L], sum([length(E) || E

file:close(File);

%io:format("~p~n",

[[M|L]]);

{lst, M, _} ->

get_pn_lst([M|L], N + 1)

end.

%子函数,询问并发过程是否结束

%asking_for(Pid, V, From) ->

% Pid ! {'is_ok?', V, self()},

% receive

% {ok, L} -> From ! {ok,

L};

% _ -> asking_for(Pid, V,

From)

% end.

%辅助函数,对区间[N, M]等距分段

rangeN(N, M) ->

T0 = M - N + 1,

T1 = trunc(math:sqrt(T0)),

T2 = T0 div T1,

[{N + (I - 1) * T2, N + I * T2 - 1} || I

range(1, T1 - 1)] ++ [{N + (T1 - 1) * T2, M}].

%获得N至M的质数序列,使用方式3,较方式2及1代价更小2

get_pn_NtoM(N, M) ->

L = rangeN(N, M),

V = length(L),

Pid = spawn(?MODULE, get_pn_lst, [[], 0]),

[spawn(?MODULE, c_pns_NtoM, [Pid, E1, E2, V]) ||

{E1, E2}

%L1 = [rangeN(E1, E2) || {E1, E2}

%[[reverse(pns_NtoM(E1, E2)) || {E1, E2}

NL] || NL

%[reverse(pns_NtoM(E1, E2)) || {E1, E2}

L]

%eg003:get_pn_NtoM(2, 10000000)

获得2至1千万内的质数序列

尽管1千万中的质数获得成功了,但是计算一亿内的质数时没有能够成功获得成功的输出!较好的并发方式仍在未来;为了获得1亿内的质数,采取了如下的方案:

// ANDY

// Using FSharp

// 初学F#,使用基础知识获取质数序列

//(*

// 开胃菜---"小玩具", 获得列表长度的3种实现

let rec len lst =

match lst

with

| [] ->

0

| h :: t

-> 1 + len t

let len2 lst =

let rec len0

lst r =

match lst with

| [] -> r

| h :: t -> len0 t (r + 1)

len0 lst

0

let len3 (lst:'T list) = lst.Length

//*)

// 主菜: 方式一

//部分一:判断n是否是质数

let isPrimeNumber n =

let

quickJuage x =

let t = x |> float |> sqrt |> int

let lst = [3..2..t]

let rec inJuage (alst: int list) =

match alst with

|[] -> true

|h::t when x % h = 0 -> false

|h::t -> inJuage t

inJuage lst

match n

with

|_ when n =

2 -> true

|_ when n %

2 = 0 -> false

|_ -> quickJuage n

//辅助功能,获得分段序列

let ranges n m =

let t0 = m -

n + 1

let t1 = t0

|> float |> sqrt |> int

let t2 = t0

/ t1

[for i in

[1..t1-1] -> (n + (i - 1) * t2, n + i * t2 - 1)] @ [(n + (t1 -

1) * t2, m)]

//部分二:获得区间内的质数序列

let arrOfPrimeNumsNtoM n m =

let arr =

match n with

|_ when n = 2 -> Array.append [|2|] [|3..2..m|]

|_ when n % 2 = 0 -> [|n + 1..2..m|]

|_ -> [|n..2..m|]

Array.filter

isPrimeNumber arr

//强化,获得序列包含元素数目

let moreArrOfPrimeNumsNtoM n m =

let res =

arrOfPrimeNumsNtoM n m

(res,

res.Length)

//计算n至m中的质数序列

let thePrimeNumsNtoM n m =

let lst =

ranges n m

let rec go

lst arr =

match lst with

|[] -> arr

|(a, b) :: t -> go t (Array.append arr (arrOfPrimeNumsNtoM a

b))

go lst

[||]

//为了获得一亿内的质数,根据方式一的思想,设计的特别版本

let outputPrimeNumsNtoM n m =

let arr =

match n with

|_ when n = 2 -> Array.append [|2|] [|3..2..m|]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值