有没有办法检查字符串是否是Prolog中另一个字符串的子字符串?我尝试将字符串转换为字符列表,然后检查第一个集合是否是第二个集合的子集,这似乎不够限制。这是我目前的代码:
isSubstring(X,Y):-
stringToLower(X,XLower),
stringToLower(Y,YLower),
isSubset(XLower,YLower).
isSubset([],_).
isSubset([H|T],Y):-
member(H,Y),
select(H,Y,Z),
isSubset(T,Z).
stringToLower([],[]).
stringToLower([Char1|Rest1],[Char2|Rest2]):-
char_type(Char2,to_lower(Char1)),
stringToLower(Rest1,Rest2).
如果我用
进行测试于issubstring( “测试”, “tesZting”)。
它返回yes,但是应该返回no。
答案 0 :(得分:5)
目前尚不清楚字符串是什么意思。但既然你说你把它转换成一个列表,你可能意味着原子。 ISO Prolog为此目的提供atom_concat/3
和sub_atom/5
。
| ?- atom_concat(X,Y,'abc').
X = '', Y = abc
; X = a, Y = bc
; X = ab, Y = c
; X = abc, Y = ''.
| ?- sub_atom('abcbcbe',Before,Length,After,'bcb').
Before = 1, Length = 3, After = 3
; Before = 3, Length = 3, After = 1.
否则,请使用DCG!这是
的方式seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
... --> [] | [_], ... .
subseq([]) --> [].
subseq(Es) --> [_], subseq(Es).
subseq([E|Es]) --> [E], subseq(Es).
seq_substring(S, Sub) :-
phrase((...,seq(Sub),...),S).
seq_subseq(S, Sub) :-
phrase(subseq(Sub),S).
...
的上述定义的第一次出现在p。
David B. Searls,用明确的条款语法研究DNA的语言学。 NACLP 1989,第1卷。
答案 1 :(得分:1)
Prolog字符串是列表,其中列表的每个元素是表示所讨论字符的代码点的整数值。字符串"abc"
与列表[97,98,99]
完全等效(假设您的prolog实现使用Unicode或ASCII,否则值可能不同)。这导致了这个(从Big-O角度来看可能不是最理想的)解决方案,它基本上说X是S的子串,如果
以下是代码:
substring(X,S) :-
append(_,T,S) ,
append(X,_,T) ,
X \= []
.
我们将X限制为除空列表之外的其他内容(也就是nil字符串""
),因为在概念上可以在任何字符串中找到大量的零长度子字符串:一个长度为的字符串n 有2 +( n -1)个nil子串,一个在字符串中的每个字符之间,一个在第一个字符之前,一个在最后一个字符之后。
答案 2 :(得分:1)
问题在于您的isSubset/2
您尝试在一个谓词中捕获两种不同的情况。要么你正在寻找第一个尝试匹配你的子串的位置,要么你已经找到了这一点并且正在检查字符串是否排列'。
isSubset([], _).
isSubSet(Substring, String) :-
findStart(Substring, String, RestString),
line_up(Substring, RestString).
findStart([], String, String).
findStart([H|T], [H|T1], [H|T1]).
findStart(Substring, [_|T], RestString) :-
findStart(Substring, T, RestString).
line_up([], _).
line_up([H|T], [H|T1]) :-
line_up(T, T1).
你可以将这些组合成一个谓词,如下所示:
isSublist([], L, L).
isSublist([H|T], [H|T1], [H|T1]) :-
isSublist(T, T1, T1).
isSublist(L, [_|T], Rest) :-
isSublist(L, T, Rest).
答案 3 :(得分:1)
使用DCG,您可以执行以下操作:(SWI)
% anything substring anything
substr(String) --> ([_|_];[]), String, ([_|_];[]).
% is X a substring of Y ?
substring(X,Y) :- phrase(substr(X),Y).