Prolog-如何确定字符串列表中的所有元素是否相等?

时间:2019-02-22 18:33:25

标签: list prolog

我正在处理此序言分配,在其中必须解析用户输入的字符串字符列表(特别是“ u”),并确定所有元素是否都等于字符串“ u”。如果是,则返回元素数,否则返回false。例如:

uA(-Length,+String,+Leftover) //Prototype

?- uA(L,["u","u","u"],[]).
L = 3 .

?- uA(L,["u","u","d"],[]).
false.

我对序言如何工作有很好的了解,但是我对列表的操作方式感到困惑。任何帮助将不胜感激。谢谢!

编辑:排序功能取得了一些进展(谢谢!),但是我遇到了一个单独的问题。

uA(Length, String) :-
   sort(String, [_]),
   member("u", String),
   length(String, Length).

这基本上满足了我的需要,但是,当我运行它时:

?- uA(L, ["u", "u", "u"]).
L = 3 ;
L = 3 ;
L = 3. 

有没有办法使它只打印一次L = 3?谢谢!

3 个答案:

答案 0 :(得分:1)

如果要声明所有列表项都相等,则无需先对列表进行排序。

只需将库谓词maplist/2与内置谓词(=)/2一起使用:

?- maplist(=(X), Xs).
   Xs = []
;  Xs = [X]
;  Xs = [X, X]
;  Xs = [X, X, X]
;  Xs = [X, X, X, X]
…                             % ... and so on ...

答案 1 :(得分:0)

首先,在Prolog中使用双引号引起注意。它们的解释取决于标准double_quotes标志的值。此标志的最可移植的值为codes,例如"123"被解释为[49,50,51]。此标志的其他可能值为atomchars。某些Prolog系统,例如SWI-Prolog也支持string值。

但是回到您的问题。一种检查基本列表中所有元素是否相等的快速方法是使用标准sort/2谓词(这将消除重复的元素)。例如:

| ?- sort(["u","u","u"], [_]).

yes
| ?- sort(["u","u","d"], [_]).

no

由于[_]与任何单例列表统一,因此只有在排序结果中包含单个元素的列表时,调用才能成功;只有在其所有元素都相等的情况下,才对非空地面列表进行调用。请注意,此解决方案与double_quotes标志的值无关。另请注意,您需要单独处理一个空列表。

答案 2 :(得分:0)

我的方法是检查列表中的每个元素是否相同(通过检查列表的开头及其相邻元素是否相同)。如果相同,则返回True,否则返回false。然后计算列表中每个元素的长度是相同的。

isEqual([X,Y]):- X == Y , !.
isEqual([H,H1|T]):- H == H1 , isEqual([H1|T]).


len([],0).
len([_|T],L):- len(T,L1) , L is L1+1.

goal(X):- isEqual(X) , len(X,Length) , write('Length = ') , write(Length).

输出

?- goal(["u","u","u"]).
   Length = 3
   true

?- goal(["u","u","a"]).
   false

您可以这样做。希望这对您有所帮助。