[英]Prolog - Generating a random string
I'm very new to Prolog and I'm trying to build a script where I can generate a random string with Prolog. 我是Prolog的新手,我正在尝试构建一个脚本,在其中可以使用Prolog生成随机字符串。 So far I've not had much luck. 到目前为止,我还没有很多运气。
My thought for doing this was to generate a list of characters that are required, create a random number based on the size of the list and try and pull a character from that list. 我这样做的想法是生成所需的字符列表,根据列表的大小创建一个随机数,然后尝试从该列表中提取一个字符。 This works fine but I also need to be able to concatenate onto a variable which will obviously start out as nothing. 这可以正常工作,但我还需要能够连接到一个变量,该变量显然一无所有。 For now I am just trying to limit the size of the string to 5 characters but in the future I will want something a bit more complicated (such as between 5 - 8 characters). 目前,我只是试图将字符串的大小限制为5个字符,但将来我会希望更复杂一些(例如5-8个字符)。
Here is what I have so far: 这是我到目前为止的内容:
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).
I believe this is breaking around the append call but I'm not really sure why, although I do know it is breaking on the first iteration and it gives a result of false. 我相信这会绕过append调用,但是我不确定为什么,尽管我确实知道它在第一次迭代时就中断了,并且给出了false的结果。 Any help towards this would be much appreciated. 任何帮助,将不胜感激。
Since @PauloMoura commented in the previous answer that foreach/3
may not be portable since it is not an ISO predicate, here is a better solution using maplist/2
: 由于@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 ).
The solution above is better in the terms listed below: 在下面列出的术语中,上述解决方案更好:
?- 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],
....
So, as suggested in the comments, you should use atom_concat/3
, in this way: 因此,如注释中所建议,您应该以这种方式使用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).
Query: 查询:
?- generate.
feFaaCabc
true
As you can see, if you input a string and you want to append some chars to it, the program will output a string of length specified (in your case 5+1
because you start from 0) plus the lenght of the input string. 如您所见,如果您输入一个字符串并想要在其后附加一些字符,程序将输出一个指定长度的字符串(在您的情况下为5+1
因为您从0开始)加上输入字符串的长度。
A different and modular way to do this could be the following, using random_member/2
: 使用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).
Query: 查询:
?- random_string(4,'gr',S).
S = grAd % note gr is in the string
?- random_string(4,'',S).
S = fdGb
From this starting point is quite easy to make also the lenght of the string random. 从这个起点很容易使字符串的长度也成为随机的。
Here is a more simple solution: 这是一个更简单的解决方案:
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) ).
Note that the above solution takes as an argument an Number N and produces an N-digit random char list: 请注意,上述解决方案将数字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.