我有一个问题。
我们有一个未排序的列表:
(1 4 5 3 6 7)
你能帮我制作2个名单吗?
一个奇数编号,增加的列表:
(1 3 5 7)
和另一个偶数编号,递减列表:
(6 4)
不要使用sort!
我在尝试计划。但是在prolog中,我不知道如何制作它。
下面:
(define (split lst)
(let loop ((a '()) (b '()) (lst lst))
(if (null? lst)
(values a (reverse b))
(let ((cur (car lst)))
(if (odd? cur)
(loop (cons cur a) b (cdr lst))
(loop a (cons cur b ) (cdr lst))
)))
)
)
(split '(1 2 3 4 5 6 7 8 9 10 11 12 13 14))
答案 0 :(得分:2)
嗯,首先,我们可以很容易地将这些事情与这些事情分开:
separate_even_odd([], [], []).
separate_even_odd([X|Xs], [X|Even], Odd) :-
0 is X mod 2,
separate_even_odd(Xs, Even, Odd).
separate_even_odd([X|Xs], Even, [X|Odd]) :-
1 is X mod 2,
separate_even_odd(Xs, Even, Odd).
这不是非常有效 - 尾递归版本不会更难,并且使用条件表达式会更有效,但这似乎是一种非常直接的启动方式。这当然不能完全符合您的要求:
?- separate_even_odd([1,4,5,3,6,7], X, Y).
X = [4, 6],
Y = [1, 5, 3, 7]
由于我们无法排序,我们需要维护一个排序列表。基本案例列表由于是空的而排序,因此我们只需要想出一种方法将值插入到排序列表中,从而维护sort属性。在一种情况下这不是很难:
insert_into_sorted_list(X, [], [X]).
insert_into_sorted_list(X, [Y|Ys], [X, Y|Ys]) :-
X =< Y.
insert_into_sorted_list(X, [Y|Ys], [Y|Zs]) :-
X > Y,
insert_into_sorted_list(X, Ys, Zs).
同样,基于相同的原因,这并不是特别有效。显而易见的下一步是复制和粘贴并更改方向,给它一个不同的名称,但这是Prolog,我们可以传递我们想要使用的运算符,并用call/2
调用它。
insert_into_sorted_list(_, X, [], [X]).
insert_into_sorted_list(Op, X, [Y|Ys], Result) :-
( call(Op, X, Y) ->
Result = [X, Y|Ys]
; insert_into_sorted_list(Op, X, Ys, Zs),
Result = [Y|Zs]
).
你可以看到它有效:
?- insert_into_sorted_list(=<, 8, [1,2,4,5,6], X).
X = [1, 2, 4, 5, 6, 8]
?- insert_into_sorted_list(>, 8, [6,5,4,3,2,1], X).
X = [8, 6, 5, 4, 3, 2, 1].
?- insert_into_sorted_list(<, 8, [6,5,4,3,2,1], X).
X = [6, 5, 4, 3, 2, 1, 8] ;
false.
?- insert_into_sorted_list(<, 0, [1,2,4,5,6], X).
X = [0, 1, 2, 4, 5, 6].
?- insert_into_sorted_list(<, 3, [1,2,4,5,6], X).
X = [1, 2, 3, 4, 5, 6].
我怀疑你现在可以看到即将发生的事情:将insert_into_sorted_list/4
和separate_odd_even/3
捆绑在一起:
separate_even_odd([], [], []).
separate_even_odd([X|Xs], Even, Odd) :-
separate_even_odd(Xs, Even0, Odd0),
( 0 is X mod 2 ->
insert_into_sorted_list(>, X, Even0, Even),
Odd = Odd0
; insert_into_sorted_list(<, X, Odd0, Odd),
Even = Even0
).
检查出来,它有效:
?- separate_even_odd([1,4,5,3,6,7], Even, Odd).
Even = [6, 4],
Odd = [1, 3, 5, 7]