erlang生成不重复字符串

借助早上写的生成随机数的代码,修修改改完成了,生成不重复字符串的小程序。

功能:给定Seed ,Count,Width

Seed : "abcd^kj"  任意不同字符列表,小于36个,如果可以重复,则可以选择重复字符

Count :要生成的字符个数

Width:字符占用位数,不足之处以Seed第一位填充

代码实现如下:


-module(ct).
-define(SYSTEM_ELEMENTS, "0123456789ABCDEFGHIJKLMNOPQRSTUVWSYZ").
-define(STANDARD_SYSTEM_ELEMENTS, [{1,"0"},{2,"1"},{3,"2"},
	  {4,"3"},{5,"4"},{6,"5"},{7,"6"},{8,"7"},{9,"8"},
	  {10,"9"},{11,"A"},{12,"B"},{13,"C"},{14,"D"},
	  {15,"E"},{16,"F"},{17,"G"},{18,"H"},{19,"I"},
	  {20,"J"},{21,"K"},{22,"L"},{23,"M"},{24,"N"},
	  {25,"O"},{26,"P"},{27,"Q"},{28,"R"},{29,"S"},
	  {30,"T"},{31,"U"},{32,"V"},{33,"W"},{34,"X"},
	  {35,"Y"},{36,"Z"}]).
-compile(export_all).
-export([test/0, test/3]).

%%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) ->
    System = length(Seed),
    LimitWidth = get_limit_width(System, 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) ->
    random:uniform(Upper);
get_random(_Upper) ->
    random:uniform(10000).
    
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 = length(Seed),
    Farmat = lists:concat(['~', Width, '.', System, '.0X']),
    NL = [lists:flatten(io_lib:format(Farmat, [X,""])) || X <- L],
    case lists:prefix(Seed, ?SYSTEM_ELEMENTS) of
	true  -> NL;
	false -> replace(Seed, NL)
    end.
    
replace(Seed, L) ->
   replace(Seed, L ,[]). 
replace(_Seed, [] ,NL) ->
    NL;
replace(Seed, [H|Tail] ,NL) ->
    NH = sub_replace(Seed, H),
    replace(Seed, Tail, [NH|NL]).
    
sub_replace(Seed, L) ->
   Len = length(L),
   sub_replace(Seed, L , Len, []). 
sub_replace(_, _, 0, NL) -> lists:reverse(lists:concat(NL));
sub_replace(Seed, [H|Tail] , Count, NL) ->
    NH = [lists:nth(locate([H]), Seed)],
    sub_replace(Seed, Tail, Count-1, [NH|NL]).
    
locate(Key) ->
    {Position, _} = lists:keyfind(Key,2,?STANDARD_SYSTEM_ELEMENTS),
    Position.
    

原来erlang下面也有string模块,直接调用就可以了,稍加修改如下:

-module(ct).
-define(SYSTEM_ELEMENTS, "0123456789ABCDEFGHIJKLMNOPQRSTUVWSYZ").
-compile(export_all).
-export([test/0, test/3]).

%%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) ->
    System = length(Seed),
    LimitWidth = get_limit_width(System, 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) ->
    random:uniform(Upper);
get_random(_Upper) ->
    random:uniform(10000).
    
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 = length(Seed),
    Farmat = lists:concat(['~', Width, '.', System, '.0X']),
    NL = [lists:flatten(io_lib:format(Farmat, [X,""])) || X <- L],
    case lists:prefix(Seed, ?SYSTEM_ELEMENTS) of
	true  -> NL;
	false -> replace(Seed, NL)
    end.
    
replace(Seed, L) ->
   replace(Seed, L ,[]). 
replace(_Seed, [] ,NL) ->
    NL;
replace(Seed, [H|Tail] ,NL) ->
    NH = sub_replace(Seed, H),
    replace(Seed, Tail, [NH|NL]).
    
sub_replace(Seed, L) ->
   Len = length(L),
   sub_replace(Seed, L , Len, []). 
sub_replace(_, _, 0, NL) -> lists:reverse(lists:concat(NL));
sub_replace(Seed, [H|Tail] , Count, NL) ->
    NH = string:substr(Seed,string:str(?SYSTEM_ELEMENTS,[H]),1),
    sub_replace(Seed, Tail, Count-1, [NH|NL]).
    




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值