生成N个不重复的随机数,比如给定四位数字做种子"0123",
用这个种子的四位数字来表示需要生成的随机数,即相当于
用四进制来表示。
要求生成的数据无重复,乱序,且按格式输出。示例如下:
["0023","0000","0012","0100","0103","0002","0001","0032","0102",
"0003","0013","0121","0020","0030","0031","0131","0021","0111",
"0122","0022","0033","0011","0110","0120","0101","0112","0130",
"0113","0123","0010"]
以下代码以"0123"等标准进制作为种子来实现。如果需要以其它种子来实现,
只需要修改format函数,替换种子即可。
关键参数:Seed, Count, Width
Seed : 种子(根据Seed元素个数来判定进制System)
Count: 需要生成的数字个数
Width : 需要表示的位数,位数不够的前面补0
-module(ct).
-export([test/0, test/3]).
-compile(export_all).
%%test
test() ->
Seed = "0123",
Width = 4,
Count = 30,
test(Seed, Count, Width).
test(Seed, Count, Width) ->
NL = random_nums(Seed, Count, Width),
io:format(" format NL: ~p ~n",[NL]),
ok.
random_nums(Seed, Count, Width) ->
case is_args_reasonable(Seed, Count, Width) of
ok ->
random_numbers(Seed, Count, Width);
{error,_} = Reason ->
Reason
end.
is_args_reasonable(Seed, Count, Width) ->
SeedLen = length(Seed),
LimitWidth = get_limit_width(SeedLen, Count),
is_args_reasonable(Width, LimitWidth).
is_args_reasonable(Width, LimitWidth) when Width >= LimitWidth ->
ok;
is_args_reasonable(_Width, _LimitWidth) ->
{error, overflow}.
get_limit_width(Num, Count) ->
get_limit_width(Num, Count, 1).
get_limit_width(Num, Count, LimitWidth) when Count > Num ->
get_limit_width(Num, Count/Num, LimitWidth+1);
get_limit_width(Num, Count, LimitWidth) ->
LimitWidth.
random_numbers(Seed, Count, Width) ->
L = sub_random_nums(Count),
format(Seed, Width, shuffle(L)).
sub_random_nums(Count) ->
sub_random_numbers(Count, Count,[]).
sub_random_numbers(Upper, Count, L) when Count > 0 ->
KV = {get_random(Upper), Count-1},
sub_random_numbers(Upper, Count-1, [KV|L]);
sub_random_numbers(_Upper, _Count, L) ->
L.
get_random(Upper) when is_integer(Upper) ->
rand(Upper);
get_random(_Upper) ->
rand(1000000).
get_random() ->
rand(1000000).
rand(Upper) ->
{N1, N2, N3} = now(),
No1 = N2 * get_no2(),
No2 = N3 * get_no1(),
No3 = N1 * get_no3(),
{RandomNo, _} = random:uniform_s(Upper,{No1,No2,No3}),
RandomNo-1.
get_no1() ->
list_to_integer(os:getpid()).
get_no2() ->
{_,_,No3} = os:timestamp(),
No3.
get_no3() ->
Pids = os:cmd("ps -e"),
sub_get_no3(Pids, length(Pids), 5, 0).
sub_get_no3(_, _, 0, No) -> No;
sub_get_no3(Pids, Len, Count, No) ->
Location = random:uniform(get_no2()) rem Len + 1,
NChar = lists:nth(Location, Pids),
NNo = case is_integer(NChar) of
true ->
No + NChar;
_ ->
No + list_to_integer(NChar)
end,
sub_get_no3(Pids, Len, Count-1, NNo).
shuffle(L) when is_list(L) ->
{_, NL} = lists:unzip(lists:keysort(1, L)),
NL.
format(Seed, Width, L) when is_list(L) andalso is_integer(Width) ->
System = integer_to_list(length(Seed)),
Wid = integer_to_list(Width),
NL = [lists:flatten(io_lib:format("~"++ Wid ++"." ++ System ++ ".0X",
[X,""])) || X<-L].
本文介绍了一种基于特定种子生成不重复随机数的方法,并通过Erlang代码实现了该算法。该方法使用种子的元素数量确定进制系统,能够生成指定数量、宽度的随机数,确保了数据的无重复性和乱序性。
858

被折叠的 条评论
为什么被折叠?



