将数字列表划分为多个列表,每个列表都是原始列表中最长的负数或非负数序列。 例如:
?- plus_or_minus([278,31,-3,-6,18,0,0,5,101,-45,0], RunList).
RunList = [[278,31], [-3,-6], [18,0,0,5,101], [-45],[0]]
答案 0 :(得分:0)
您只需以这种方式修改代码:
same([X],[[X]]).
same([H|T], Tail):-
same(T,Tail1),
finish(H, Tail1, Tail).
finish(H, [[X| T1]|Tail], New_Tail):-
H >= 0,
X >= 0
New_Tail = ... .
finish(H, [[X| T1]|Tail], New_Tail):-
H >= 0,
...
....
finish(H, [[X| T1]|Tail], New_Tail):-
...
...
...
finish(H, [[X| T1]|Tail], New_Tail):-
...
...
...
答案 1 :(得分:0)
您声明不允许析取。但是,在构造输出列表时,必须在当前整数的 sign 与下一个整数(如果有)之间进行比较。无需分离的便携式解决方案:
plus_or_minus([], []).
plus_or_minus([I| Tail1], [[I|Is]| Tail2]) :-
integer_sign(I, Sign),
plus_or_minus_sign(Sign, Tail1, Is, Tail2).
plus_or_minus_sign(-1, Tail1, Is, Tail2) :-
plus_or_minus_sign_negative(Tail1, Is, Tail2).
plus_or_minus_sign(+1, Tail1, Is, Tail2) :-
plus_or_minus_sign_positive(Tail1, Is, Tail2).
plus_or_minus_sign_negative([], [], []).
plus_or_minus_sign_negative([I| Tail1], Is, Tail2) :-
integer_sign(I, Sign),
plus_or_minus_sign_negative_same(Sign, I, Tail1, Is, Tail2).
plus_or_minus_sign_negative_same(-1, I, Tail1, [I| Is], Tail2) :-
plus_or_minus_sign(-1, Tail1, Is, Tail2).
plus_or_minus_sign_negative_same(+1, I, Tail1, [], [[I| Is]| Tail2]) :-
plus_or_minus_sign(+1, Tail1, Is, Tail2).
plus_or_minus_sign_positive([], [], []).
plus_or_minus_sign_positive([I| Tail1], Is, Tail2) :-
integer_sign(I, Sign),
plus_or_minus_sign_positive_same(Sign, I, Tail1, Is, Tail2).
plus_or_minus_sign_positive_same(-1, I, Tail1, [], [[I| Is]| Tail2]) :-
plus_or_minus_sign(-1, Tail1, Is, Tail2).
plus_or_minus_sign_positive_same(+1, I, Tail1, [I| Is], Tail2) :-
plus_or_minus_sign(+1, Tail1, Is, Tail2).
integer_sign(Integer, Sign) :-
catch(Sign is abs(Integer)//Integer, _, Sign = 1).
此解决方案利用了大多数prolog系统实现的第一参数索引编制功能,避免了虚假的选择点。
通话示例:
?- plus_or_minus([278,31,-3,-6,18,0,0,5,101,-45,0], RunList).
RunList = [[278, 31], [-3, -6], [18, 0, 0, 5, 101], [-45], [0]].
但是,从避免歧义的角度来看,这种解决方案是否值得花时间进行 develop 或理解?疑。使用if-then-else控制结构->/2
的解决方案尽管声明性较低,但更容易编写和理解。
无论如何,一个样本调用或其中的几个采样都是相当有限的测试。 QuickCheck实施(例如Logtalk lgtunit
工具提供的实施)可以在此处提供帮助:
?- lgtunit::quick_check(plus_or_minus(+list(integer), -list(types([list(negative_integer),list(non_negative_integer)])))).
% 100 random tests passed
true.
?- lgtunit::quick_check(plus_or_minus(+list(integer), -list(types([list(negative_integer),list(non_negative_integer)]))), [n(1000)]).
% 1000 random tests passed
true.
lgtunit::quick_check/1-2
谓词带有谓词类型签名和可选的选项列表。在这种情况下,签名将第一个参数指定为整数的输入列表,第二个参数指定为负整数或非负整数的列表。