我有這樣的問題,我需要找到最長的單詞由來自2個字的信,這信必須在相同的順序像原話,例如xabred
和pppaed
必須返回aed
。我不知道如何做到這一點在序言序言找到類似的信件在2個字
回答
如果我理解正確的要求,要求是將(經重列)謂詞找到最長子兩個給定的字符串(原子實際上)。如果長度相同,最長,則需要列出。這表示結果是一個或多個單詞的列表。
下面是它該做的作業的刺,但現在看來,這可能是一個有點「笨拙」,效率低下,特別是如果你考慮很長的字符串:
% 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
這是歸結爲Longest Common Sequence Problem。上面的代碼並不試圖實施本文提供的必要解決方案。
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.
謝爾蓋,這並不總是給出正確的答案。例如,'sl(abcdef,acbedf,L).'產生'L = abcdef',而在這種情況下的正確答案是'acef','acdf','abef'和'abdf'。我認爲'交集'在這裏引起麻煩,因爲它不強制列表順序(這是一個設置操作)。 – lurker
@mbratch是的,我只是誤解了這個問題。 –
讓我們先找到任何字符公共子序列(我假設我們正在與人物的名單工作):
common(Xs, Ys, [C|Cs]) :-
append(_,[C|Xs1],Xs),
append(_,[C|Ys1],Ys),
common(Xs1, Ys1, Cs).
common(_, _, []).
這將產生所有的解決方案在回溯:
?- 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)
不錯。 'common/3'可以代替我的'matchl/3'。根據字符串的不同,'matchl'的推理較少。例如,如果你使用'[a,b,c,d,e,f]'和'[a,c,b,e,d,f]',那麼'matchl'非常大約爲數量的40% 'common/3'使用的推論來找到所有的解決方案。 – lurker
- 1. Python在字符串中找到類似的序列
- 2. 找到類似的話在多個字符串(路口)
- 3. 如何在java中找到類似2 ^(10^9)的數字的功率
- 4. 如何找到在序言
- 5. 序言,找到一個圖的鄰居
- 6. 要找到兩個文件中的相似字(字符串)
- 7. 在mysql中找到類似的句子
- 8. TypeError:序列項目1:期望一個類似字節的對象,找到str
- 9. 查找類似字符串
- 10. Python在給定文件夾中找到類似的文件
- 11. 在PHP中通過類似的2個字段組?
- 12. 按類似的2個字段在PHP和結果總數?
- 13. 序言找到一個數字列表的GCD
- 14. 找不到類似liftM2
- 15. 比較2個類似字母的字符串
- 16. 在兩列中找到類似的字符串
- 17. jQuery的狀態信息(到Twitter類似)
- 18. 找到類似的文本在整個python的數據幀
- 19. 如何分2個字以上的彙編語言2個字
- 20. 我可以在Linux中找到與Pageant類似的軟件嗎?
- 21. 找到與類似領域值的記錄在另一個表
- 22. 用不同語言編寫的2個程序之間的通信 - 序列化?
- 23. MySQL - 合併2個類似的表
- 24. 重構2個類似的if語句
- 25. 組合2個類似的JSON
- 26. SQL加入2個類似的表
- 27. Lotus Notes - 查找類似的字段(SELECTION)
- 28. MySQL查找類似的字符串
- 29. 類似字符串上的2個表的內部連接
- 30. 在兩個文本文件中查找類似的行?
「abc」和「cba」會產生三種解答:「a」,「b」和「c」? – lurker
在序言中,您可以使用'atom_chars(abc,[a,b,c])'在原子及其字符列表之間移動。然後編寫你的謂詞來處理一系列元素。從那開始。 – lurker
是的,它會產生一個,b,c –