我希望能够获取一个数字列表并获得有序的最大数字序列。例如:
?- in_order([1,2,3,4,5],N).
N = 5. % expected result
?- in_order([1,2,5,6,7,8,4],N).
N = 4. % expected result
到目前为止,我已经生成了一些基本代码来计算一系列数字的长度,但是一旦列表为空,它就会返回轨道,因此返回的数字为N,与列表中的第一个元素相同。我知道我需要停止追踪,但似乎无法做到。有人会善意地指出我正确的方向。
到目前为止我的代码(都是有点hacky):
in_order([],_) :-
!.
in_order([H|T],N):-
( var(N),
N is H
; true
),
H = N,
M is N+1,
in_order(T,M).
我确实理解我当前的解决方案在给出的第二个示例中不起作用,并且该方面的指针将再次有用,因为我不太确定如何解决这个问题。我正在使用SICStus Prolog。
非常感谢提前!
答案 0 :(得分:2)
让我称之为zs_maxInOrder/2
的关系,它基于clpfd
并使用reified constraints:
:- use_module(library(clpfd)).
zs_maxInOrder([] ,0).
zs_maxInOrder([Z|Zs],N) :-
zs_prev_n_max0_max(Zs,Z,1,1,N). % use "lagging"
zs_prev_n_max0_max([] ,_ ,_ ,M ,M).
zs_prev_n_max0_max([Z1|Zs],Z0,N0,M0,M) :-
Z1 #= Z0 + 1 #<=> B, % with SWI-Prolog use `(#<==>)/2`
N1 #= N0 * B + 1,
M1 #= max(M0,N1),
zs_prev_n_max0_max(Zs,Z1,N1,M1,M).
让我们看一下使用SICStus Prolog 4.3.1:
?- zs_maxInOrder([1,2,3,4,5],N). N = 5 ? ; no ?- zs_maxInOrder([1,2,5,6,7,8,4],N). N = 4 ? ; no
角落案件怎么样?
?- zs_maxInOrder([1],N).
N = 1 ? ;
no
?- zs_maxInOrder([],N).
N = 0 ? ;
no
答案 1 :(得分:1)
你的尝试失败了,因为你混合了不同的东西。当你写
N is H
您基本上是在输出列表中的一个元素。这是你在任何情况下都不想做的事情。基本情况也是错误的,应该是“空列表的有序序列为零”。
尝试使用“累加器”参数来跟踪以当前头H终止的连续元素。
答案 2 :(得分:1)
这是解决问题的一个相当强力的解决方案:P(我知道我会受到批评,但我无法抗拒使用更高阶的谓词)。
my_prefix(List,Prefix) :-
append(Prefix,_,List).
my_suffix(List,Suffix) :-
append(_,Suffix,List).
my_sublist(List,Sublist) :-
my_suffix(List,Suffix),
my_prefix(Suffix,Sublist).
all_sublists(List,AllSublists) :-
findall(Sub,my_sublist(List,Sub),AllSublists).
good_list([]) :-
!.
good_list([H]) :-
!.
good_list([H1,H2|T]) :-
H1 is H2-1,
good_list([H2|T]),
!.
in_order(List,Length) :-
all_sublists(List,AllSublists),
findall(L,(member(Sublist,AllSublists),
good_list(Sublist),
length(Sublist,L)),
InOrderSizes),
max_list(InOrderSizes,Length).
答案 3 :(得分:0)
“空列表的有序序列为零”。
谢谢你。它让我走上正轨(我认为)
到目前为止,这是我的解决方案:
in_order([], _, 0).
in_order([H|T], Prev, N):-
% Split the list
in_order(T, H, M),
% Increment the expected Head value
H1 is Prev + 1,
(
H = H1,
N is M + 1
;
M1 is M + 1,
format('M1 is ~w~n', [M1]),
N is 0
).
我添加了格式,以便我可以看到最后阶段正在打印的内容,并且我得到输入值[1,2,5,6,7,8,4]的值1和4 - 是正确的。谓词返回2(序列的最后一个长度),但当我回溯试图获得更多答案时,我没有得到值4或1.我认为我非常接近答案,任何额外的最终帮助将是赞赏。
非常感谢