簡體   English   中英

Prolog-生成隨機字符串

[英]Prolog - Generating a random string

我是Prolog的新手,我正在嘗試構建一個腳本,在其中可以使用Prolog生成隨機字符串。 到目前為止,我還沒有很多運氣。

我這樣做的想法是生成所需的字符列表,根據列表的大小創建一個隨機數,然后嘗試從該列表中提取一個字符。 這可以正常工作,但我還需要能夠連接到一個變量,該變量顯然一無所有。 目前,我只是試圖將字符串的大小限制為5個字符,但將來我會希望更復雜一些(例如5-8個字符)。

這是我到目前為止的內容:

generate :-
    Output = '',
    generate_random_string(Output, 0),
    write(Output).

generate_random_string(Output, 5) :-
    Characters = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    random(0, 14, RandomValue),
    nth0(RandomValue, Characters, RandomCharacter),
    append(RandomCharacter, Output, Concat),
    Output = Concat.

generate_random_string(Output, CharNum) :-
    CharNum \= 5,

    Characters = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    random(0, 14, RandomValue),
    nth0(RandomValue, Characters, RandomCharacter),
    append(RandomCharacter, Output, Concat),
    Count is CharNum + 1,
    Output = Concat,

    generate_random_string(Output, Count).

我相信這會繞過append調用,但是我不確定為什么,盡管我確實知道它在第一次迭代時就中斷了,並且給出了false的結果。 任何幫助,將不勝感激。

由於@PauloMoura在先前的回答中評論說foreach/3可能不是可移植的,因為它不是ISO謂詞,因此這是使用maplist/2的更好解決方案:

characters(['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g']).

generate(L,N) :-  
    length(L,N),
    characters(Char_list),
    length(Char_list, N1),
    maplist( random_char_generat(Char_list, N1), L ).

random_char_generat(Char_list, N, Char):-  random(0, N, X), nth0(X, Char_list, Char ).

在下面列出的術語中,上述解決方案更好:

  • 它適用於生成的隨機字符列表的任何長度。
  • 它適用於可用字符列表的任何長度。
  • 最終,如您在以下示例中看到的那樣,它是純凈的,並且可以用於非常常規的查詢:

?- generate(L,5).
L = ['E', g, c, 'B', 'D'].

?- generate(L,8).
L = [g, g, f, d, 'E', a, g, b].

?- generate(L,N).
L = [],
N = 0 ;
L = [e],
N = 1 ;
L = [e, 'F'],
N = 2 ;
L = ['C', g, 'G'],
N = 3 ;
L = ['D', a, b, e],
N = 4 ;
L = ['F', 'E', 'G', f, b],
....

因此,如注釋中所建議,您應該以這種方式使用atom_concat/3

generate :-
    Output = 'abc',
    generate_random_string(Output,Result,0),
    write(Result).

generate_random_string(Output,Result,5):- !,
    Characters = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    random(0, 14, RandomValue),
    nth0(RandomValue, Characters, RandomCharacter),
    atom_concat(RandomCharacter,Output,Result).

generate_random_string(Output,Result,CharNum) :-
    CharNum \= 5,

    Characters = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    random(0, 14, RandomValue),
    nth0(RandomValue, Characters, RandomCharacter),
    atom_concat(RandomCharacter,Output,Concat),
    Count is CharNum + 1,
    generate_random_string(Concat,Result,Count).

查詢:

?- generate.
feFaaCabc
true

如您所見,如果您輸入一個字符串並想要在其后附加一些字符,程序將輸出一個指定長度的字符串(在您的情況下為5+1因為您從0開始)加上輸入字符串的長度。

使用random_member/2方法可以是以下不同的模塊化方法:

pick_random(_,0,L,L):- !.
pick_random(LC,I,SIn,SOut):-
    I > 0,
    random_member(R,LC),
    atom_concat(SIn,R,Concat),
    I1 is I-1,
    pick_random(LC,I1,Concat,SOut).


random_string(Len,SIn,SOut):-
    LC = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    string_length(SIn,Ls),
    Len1 is Len - Ls,    
    pick_random(LC,Len1,SIn,SOut).

查詢:

?- random_string(4,'gr',S).
S = grAd % note gr is in the string
?- random_string(4,'',S).
S = fdGb

從這個起點很容易使字符串的長度也成為隨機的。

這是一個更簡單的解決方案:

characters(['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g']).

generate(L,N) :-  
      length(L,N),
      characters(Char_list),
      N1 is N-1,
      foreach( (between(0,N1,X), random(0, 14, RandomValue), nth0(RandomValue, Char_list, Char)) , nth0(X,L,Char) ).

請注意,上述解決方案將數字N作為參數,並生成一個N位的隨機字符列表:

?- generate(L,5).
L = [f, e, 'C', 'B', 'A'].

?- generate(L,8).
L = [a, 'E', c, c, 'E', f, 'B', g].

?- generate(L,N).
L = [],
N = 0 ;
L = ['B'],
N = 1 ;
L = [c, 'F'],
N = 2 ;
L = ['E', g, 'C'],
N = 3 ;
L = ['C', c, 'F', 'D'],
N = 4 ;
L = [c, 'B', 'F', 'B', 'B'],
N = 5
....and goes on

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM