List 在Prolog中查找列表长度时遇到问题
我找不到列表的长度。我知道如何处理列表,比如说List 在Prolog中查找列表长度时遇到问题,list,prolog,List,Prolog,我找不到列表的长度。我知道如何处理列表,比如说[a,b,c,d]或[a,b,[],d]甚至[a,[[[]],c,[]],每个列表的长度都是4。我遇到的问题是在这样的情况下试图计算列表的长度[a[b,c],d]。有4个元素,但当我运行代码时,它将打印3个元素。它将内部列表[b,c]视为一个单独的元素,我不知道如何分别计算这些元素 以下是我所拥有的: % this is the base case mylen([],0). % case where element is a single atom
[a,b,c,d]
或[a,b,[],d]
甚至[a,[[[]],c,[]]
,每个列表的长度都是4。我遇到的问题是在这样的情况下试图计算列表的长度[a[b,c],d]
。有4个元素,但当我运行代码时,它将打印3个元素。它将内部列表[b,c]
视为一个单独的元素,我不知道如何分别计算这些元素
以下是我所拥有的:
% this is the base case
mylen([],0).
% case where element is a single atom like a or []
mylen([_|T],Len) :- atom(_),Len is Len1+1.
% case that *should* deal with sublists [b,c]
mylen([[_|TH]|T],Len) :- mylen(TH,Len1), Len is Len1+1.
% general case
mylen([_|T],Len):- mylen(T,Len1),Len is Len1+1.
我希望我的问题是清楚的。谢谢大家!
另外,我看了其他关于这个问题的帖子,但找不到任何解决这个具体问题的方法
?- atom(_).
false.
那么第二条就没用了,永远都会失败。你不应该忽略列表头部的“形状”,因为它可能是一个列表。这个问题也出现在第三条中
那么第二条就没用了,永远都会失败。你不应该忽略列表头部的“形状”,因为它可能是一个列表。这个问题也出现在第三条中
那么第二条就没用了,永远都会失败。你不应该忽略列表头部的“形状”,因为它可能是一个列表。这个问题也出现在第三条中
那么第二条就没用了,永远都会失败。你不应该忽略列表头部的“形状”,因为它可能是一个列表。这个问题也出现在第三条中。您的问题来自这样一个事实,即当列表的头是非空列表时,您需要以特殊的方式对待它。例如:
strangelen([], 0).
strangelen([H|T], Len) :-
( H = [_|_] % head is a non-empty list
-> strangelen(H, LenH)
; LenH = 1
),
strangelen(T, LenT),
Len is LenH + LenT.
然后:
?- strangelen([a,b,c,d], Len).
Len = 4.
?- strangelen([a,b,[],d], Len).
Len = 4.
?- strangelen([a,[[[]]],c,[]], Len).
Len = 4.
?- strangelen([a,[b,c],d], Len).
Len = 4.
?- strangelen([[]], Len).
Len = 1.
?- strangelen([[[b,c]]], Len).
Len = 2.
此解决方案不适用于不是正确列表的第一个参数(请尝试
?-strangelen(list,Len)。
)您的问题来自这样一个事实,即当列表是非空列表时,您需要以特殊的方式处理列表头。例如:
strangelen([], 0).
strangelen([H|T], Len) :-
( H = [_|_] % head is a non-empty list
-> strangelen(H, LenH)
; LenH = 1
),
strangelen(T, LenT),
Len is LenH + LenT.
然后:
?- strangelen([a,b,c,d], Len).
Len = 4.
?- strangelen([a,b,[],d], Len).
Len = 4.
?- strangelen([a,[[[]]],c,[]], Len).
Len = 4.
?- strangelen([a,[b,c],d], Len).
Len = 4.
?- strangelen([[]], Len).
Len = 1.
?- strangelen([[[b,c]]], Len).
Len = 2.
此解决方案不适用于不是正确列表的第一个参数(请尝试
?-strangelen(list,Len)。
)您的问题来自这样一个事实,即当列表是非空列表时,您需要以特殊的方式处理列表头。例如:
strangelen([], 0).
strangelen([H|T], Len) :-
( H = [_|_] % head is a non-empty list
-> strangelen(H, LenH)
; LenH = 1
),
strangelen(T, LenT),
Len is LenH + LenT.
然后:
?- strangelen([a,b,c,d], Len).
Len = 4.
?- strangelen([a,b,[],d], Len).
Len = 4.
?- strangelen([a,[[[]]],c,[]], Len).
Len = 4.
?- strangelen([a,[b,c],d], Len).
Len = 4.
?- strangelen([[]], Len).
Len = 1.
?- strangelen([[[b,c]]], Len).
Len = 2.
此解决方案不适用于不是正确列表的第一个参数(请尝试
?-strangelen(list,Len)。
)您的问题来自这样一个事实,即当列表是非空列表时,您需要以特殊的方式处理列表头。例如:
strangelen([], 0).
strangelen([H|T], Len) :-
( H = [_|_] % head is a non-empty list
-> strangelen(H, LenH)
; LenH = 1
),
strangelen(T, LenT),
Len is LenH + LenT.
然后:
?- strangelen([a,b,c,d], Len).
Len = 4.
?- strangelen([a,b,[],d], Len).
Len = 4.
?- strangelen([a,[[[]]],c,[]], Len).
Len = 4.
?- strangelen([a,[b,c],d], Len).
Len = 4.
?- strangelen([[]], Len).
Len = 1.
?- strangelen([[[b,c]]], Len).
Len = 2.
此解决方案不适用于不是正确列表的第一个参数(请尝试
?-strangelen(list,Len)。
)您真正算作元素的是什么?似乎应该计算一个空列表:您声称[a,b,[],d]
的长度为4。但另一方面,空列表的长度为0,对吗?你如何决定你应该计算什么,什么不是?我认为一个空列表,如果它没有元素。例如:[]是一个空列表,但是如果像[[]这样的列表中有一个空列表,或者在您所说的例子[a,b,[],d]中,空列表是较大列表的一个元素。“长度”通常是部分长度的总和,但在您的情况下不是。你说的是:[]
的长度是0,但是[[]]
的长度是1。然后,[a,[]]
的长度是2,[a,[[b]]
的长度是2,[a,[[b]]]
的长度是2(对吗?),所以[]
的长度等于[b]
的长度等于[b]
的长度。谓词的第2和第3子句将尾部T
一起扔掉,因此这些将不计入您的解决方案中。正如卡佩莱克指出的,atom()
总是错误的。你的第二条和第四条的开头是相同的,所以这些情况没有区别。第二、第三和第四子句都忽略了列表的头(通过<代码> <代码> >,因此不考虑它的外观,也不考虑结果长度。你需要仔细地、逻辑地思考你的规则意味着什么。作为另一条线索,你实际上只有3种情况:(1)第一个参数是[]
,(2)第一个参数是[H | T]
,其中H
是一个原子(请记住原子([])
是真的),以及(3)第一个参数是[H | T]
其中H
是一个列表(或以其他方式编写,[[H|TH]|T]
)。你必须确保这个解决方案包含了参数所有组成部分的长度贡献。你算作元素的东西到底是什么?似乎应该计算一个空列表:您声称[a,b,[],d]
的长度为4。但另一方面,空列表的长度为0,对吗?你如何决定你应该计算什么,什么不是?我认为一个空列表,如果它没有元素。例如:[]是一个空列表,但是如果像[[]这样的列表中有一个空列表,或者在您所说的例子[a,b,[],d]中,空列表是较大列表的一个元素。“长度”通常是部分长度的总和,但在您的情况下不是。你说的是:[]
的长度是0,但是[[]]
的长度是1。然后,[a,[]]
的长度是2,[a,[[b]]
的长度是2,[a,[[b]]]
的长度是2(对吗?),所以[]
的长度等于[b]
的长度等于[b]
的长度。谓词的第2和第3子句将尾部T
一起扔掉,因此这些将不计入您的解决方案中。正如卡佩莱克指出的,atom()
总是错误的。你的第二条和第四条的开头是相同的,所以这些情况没有区别。第2、第3和第4条都忽略了列表的标题(通过\uu
),因此不考虑