Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 序言在两个单词中找到相似的字母_Prolog - Fatal编程技术网

Prolog 序言在两个单词中找到相似的字母

Prolog 序言在两个单词中找到相似的字母,prolog,Prolog,我有这样的问题,我需要找到由两个单词中的字母组成的最长单词,这些字母的顺序必须与原始单词相同,例如xared和pppaed必须返回aed。我不知道如何在Prolog中实现这一点 sl(A, B, C) :- atom_chars(A, Alist), atom_chars(B, Blist), intersection(Alist, Blist, Clist), atom_chars(C, Clist). 试运行: ?- sl(xabred, pppaed, X

我有这样的问题,我需要找到由两个单词中的字母组成的最长单词,这些字母的顺序必须与原始单词相同,例如
xared
pppaed
必须返回
aed
。我不知道如何在Prolog中实现这一点

sl(A, B, C) :-
    atom_chars(A, Alist),
    atom_chars(B, Blist),
    intersection(Alist, Blist, Clist),
    atom_chars(C, Clist).
试运行:

?- sl(xabred, pppaed, X).
X = aed.

如果我正确理解了需求,那么请求的是一个谓词,它将(重述)在两个给定字符串中找到最长的子字符串(实际上是原子)。如果在相同的最长长度上有多个,则需要列出所有。这表示结果是一个包含一个或多个单词的列表

这是一个可以做这项工作的刺戳,但是它看起来有点“笨拙”和低效,特别是如果你考虑了很长的字符串:

% Give a list of the longest matching words (substrings)
matchwords(W1, W2, Results) :-
    setof(R, matchw(W1, W2, R), RSet), % Collect all the matching substrings
                                       % and their lengths
    reverse(RSet, Set),                % Order by longest first
    highest(Set, Results).             % keep only the highest ones

% match atom-string W1 and W2 yielding atom-string Result of length N
matchw(W1, W2, N-Result) :-
    atom_chars(W1, A1),
    atom_chars(W2, A2),
    matchl(A1, A2, R),
    length(R, N),
    atom_chars(Result, R).

% find a matching sublist between the first two lists
matchl([H|T1], [H|T2], [H|T]) :-
    matchl(T1, T2, T).
matchl([H1|T1], [H2|T2], R) :-
    H1 \= H2,
    ( matchl(T1, [H2|T2], R) ; matchl([H1|T1], T2, R) ).
matchl([], _, []).
matchl([_|_], [], []).

% Keep the highest elements at the front of a list of N-W pairs
highest([_-W], [W]).
highest([N1-W1,N2-_|_], [W1]) :-
    N1 > N2.
highest([N1-W1,N2-W2|T], [W1|WT]) :-
    N1 = N2,
    highest([N2-W2|T], WT).
举几个例子:

| ?- matchwords(xabred, pppaed, Matches).

Matches = [aed] ? a

(2 ms) no
| ?- matchwords(abcdef, acbedf, Matches).

Matches = [acef,acdf,abef,abdf] ? a

no
这归结起来就是一个问题。上面的代码并不试图实现本文中提供的强制解决方案。

让我们首先找到任何常见的字符子序列(我假设我们正在处理字符列表):

这将生成所有回溯解决方案:

?- common([a, b, c, d], [e, c, d, b], Cs).
Cs = [b]
Yes (0.00s cpu, solution 1, maybe more)
Cs = [c, d]
Yes (0.00s cpu, solution 2, maybe more)
Cs = [c]
Yes (0.00s cpu, solution 3, maybe more)
Cs = [d]
Yes (0.02s cpu, solution 4, maybe more)
Cs = []
Yes (0.03s cpu, solution 5)
您现在可以使用findall/3或setof/3收集所有解决方案,并过滤掉最长的解决方案。或者,下面显示如何修改代码,使其首先返回最长的解决方案:

ordered_common(Xs, Ys, Cs) :-
    le_min_length(Xs, Ys, Cs),
    common(Xs, Ys, Cs).

le_min_length([_|Xs], [_|Ys], [_|Zs]) :-
    le_min_length(Xs, Ys, Zs).
le_min_length(_, _, []).
这样,一旦搜索提供了您喜欢的解决方案,您就可以停止搜索

?- ordered_common([a, b, c, d], [e, c, d, b], Cs).
Cs = [c, d]
Yes (0.00s cpu, solution 1, maybe more)

“abc”和“cba”将产生三种解决方案:“a”、“b”和“c”?在prolog中,您可以使用
atom\u chars(abc[a,b,c])
在atom和它的字符列表之间切换。然后编写谓词来处理元素列表。首先,是的,它将产生a,b,c,然后你需要一个谓词,它接受两个原子字符串并产生一个列表。谓词应该使用
atom\u chars
将原子字符串转换为字符列表,然后它可以生成两个列表之间匹配的原子字符列表序列,然后选择最长的列表,最后使用
atom\u chars
转换回原子字符串。@mbrach我不知道如何做,我用atom\u chars做了一个列表,但我不知道下一步要做什么。你能给我举个例子吗?谢尔盖,这不一定能给出正确的答案。例如,
sl(abcdef,acbedf,L)。
产生,
L=abcdef
,而在这种情况下正确的答案是
acef
acdf
abef
,以及
abdf
。我认为,
intersection
在这里造成了麻烦,因为它没有强制执行列表顺序(这是一个集合操作)。很好。
common/3
可以取代我的
matchl/3
。根据字符串的不同,
matchl
是较少的推断。例如,如果您使用
[a,b,c,d,e,f]
[a,c,b,e,d,f]
,那么
match
大约是
common/3
用于查找所有解决方案的推理数量的40%。
?- ordered_common([a, b, c, d], [e, c, d, b], Cs).
Cs = [c, d]
Yes (0.00s cpu, solution 1, maybe more)