因此,在此代码中,我相信我很接近,但是我想我在尝试在' b
'之后才在列表中计数' w
'时弄乱了,而不是以前。例如,h1([w,w,b,w,b,b],H)
将成功使用H=1
。
编辑:我相信我的基本案例是正确的。但是递归在第二部分是错误的。
h1([], 0).
h1([b|T], Count) :-
h1(T, TCount),
Count is TCount + 1.
我觉得自己很近。P.S."在那里,因为我不确定现在要放什么东西。
h1([H|T], Count) :-
"" == H,
h1(T, Count).
您想做的是逐步浏览列表中的每个元素,检查是否是您的状况字符,然后计算元素并将其返回到您的呼叫。
forFirstBCountW(List, Count) :- detect_b(List, Count).
detect_b([], _).
detect_b([b|T], Count) :- count_w(T, 0, Count), !.
detect_b([_|T], Count) :- detect_b(T, Count).
count_w([], TotalCount, TotalCount) :- !.
count_w([w|T], CurrentCount, TotalCount) :-
NewCount is CurrentCount + 1,
count_w(T, NewCount, TotalCount).
count_w([_|T], NewCount, TotalCount) :-
count_w(T, NewCount, TotalCount).
我真的可以推荐现在阅读Learn Prolog!要学习Prolog背后的概念,这是一种非常强大的语言。
编辑:为了清楚起见,将谓词分开,以便可以单独重复使用,因为detect_b
并未明确命名其所做的事情。我将旧程序留在那里,因此您可以比较它们如何达到相同的结果,同时采取不同的途径:
forFirstBCountW(List, Count) :-
detect_b(List, ListFromB),
count_w(ListFromB, 0, Count),
!.
detect_b([], []).
detect_b([b|T], T) :- !.
detect_b([_|T], ReturnList) :- detect_b(T, ReturnList).
count_w([], TotalCount, TotalCount) :- !.
count_w([w|T], CurrentCount, TotalCount) :-
NewCount is CurrentCount + 1,
count_w(T, NewCount, TotalCount).
count_w([_|T], NewCount, TotalCount) :-
count_w(T, NewCount, TotalCount).
这可以进一步抽象,这就是为什么Prolog如此有趣的原因:
forFirstBCountW(List, Count) :-
splitListOnChar(b, List, ListFromB),
count_Char(w, ListFromB, 0, Count),
!.
splitListOnChar(_, [], []).
splitListOnChar(Char, [Char|T], T) :- !.
splitListOnChar(Char, [_|T], ReturnList) :-
splitListOnChar(Char, T, ReturnList).
count_Char(_, [], TotalCount, TotalCount) :- !.
count_Char(Char, [Char|T], CurrentCount, TotalCount) :-
NewCount is CurrentCount + 1,
count_Char(Char, T, NewCount, TotalCount).
count_Char(Char, [_|T], NewCount, TotalCount) :-
count_Char(Char, T, NewCount, TotalCount).
您的语法不是'prolog'。您可能需要阅读一些基本文档,以了解有关Prolog语法的更多信息。
原因Prolog不使用循环而是递归,我建议一种非常直观的递归思维:
- 基本案例:空列表
- 基本案例:b是列表的负责人,然后只计数。列表其余部分的W。
- 递归情况:b不是头,然后只调用列表其余部分的功能。
我很确定还有其他优雅的方法可以解决这个问题。玩得开心。