如何获取列表方案和序言的第一个、中间和最后一个元素? [英] How to get the first, middle and last element of a list scheme and prolog?
问题描述
我正在尝试在 Scheme 和 Prolog 中编写一个返回列表的第一项、中间项和最后一项的函数.例如,find([4,5,8,7,9],L), L = [4,8,9]
.
我想出了这段 Scheme 语言的代码,但是我是 Prolog 的新手,知道的不多,所以我如何在 Prolog 中得到相同的结果?
(定义(第一个 L)(车L))(定义(最后一个 L)(如果(空?(cdr L))(车L)(最后(cdr L))))(定义(第 n 个 L x)(如果(= x 1)(车L)(nth (cdr L) (- x 1))))(定义(firstMidLast L)(列表(第一个 L)(nth L (天花板 (/(长度 L) 2)))(最后一个 L)))
这是另一种方法!
- 诀窍"是以两种不同的速度走同一个列表.
- 第一个参数索引保持目标
list_first_mid_last(+,?,?,?)
确定性.
我们这样定义list_first_mid_last/4
:
list_first_mid_last([E|Es],E,M,L) :-ahead_of_mid_last([E|Es],[E|Es],M,L).提前中途([],[M|_],M,M).ahead_of_mid_last([F|Fs],Es,M,L) :-more_ahead_of_mid_last(Fs,F,Es,M,L).more_ahead_of_mid_last([],L,[E|_],E,L).more_ahead_of_mid_last([F|Fs],_,Es,E,L) :-evenmore_ahead_of_mid_last(Fs,F,Es,E,L).evenmore_ahead_of_mid_last([],L,[E|_],E,L).evenmore_ahead_of_mid_last([F|Fs],_,[_|Es],M,L) :-more_ahead_of_mid_last(Fs,F,Es,M,L).
让我们运行一些查询并将 Prolog1 和 Scheme2 结果并排放置!
<上一页>% 序言 % ;方案?- list_first_mid_last([1],F,M,L).% > (firstMidLast `(1))F = M,M = L,L = 1.% (1 1 1)%?- list_first_mid_last([1,2],F,M,L).% > (firstMidLast `(1 2))F = M,M = 1,L = 2.% (1 1 2)%?- list_first_mid_last([1,2,3],F,M,L).% > (firstMidLast `(1 2 3))F = 1,M = 2,L = 3.% (1 2 3)%?- list_first_mid_last([1,2,3,4],F,M,L).% > (firstMidLast `(1 2 3 4))F = 1,M = 2,L = 4.% (1 2 4)%?- list_first_mid_last([1,2,3,4,5],F,M,L).% > (firstMidLast `(1 2 3 4 5))F = 1,M = 3,L = 5.% (1 3 5)%?- list_first_mid_last([1,2,3,4,5,6],F,M,L).% > (firstMidLast `(1 2 3 4 5 6))F = 1,M = 3,L = 6.% (1 3 6)%?- list_first_mid_last([1,2,3,4,5,6,7],F,M,L).% > (firstMidLast `(1 2 3 4 5 6 7))F = 1,M = 4,L = 7.% (1 4 7)<小时>
脚注 1: 使用 swi-prolog 版本 7.3.11(64 位).
脚注 2: 使用 方案 解释器 SCM 版本 5e5(64 位).支持>
I am trying to write a function in Scheme and Prolog that returns first, middle and last item of a list. E.g., find([4,5,8,7,9],L), L = [4,8,9]
.
I came up with this piece of code for Scheme language, but I am new to Prolog and don't know much, so how I can get the same result in Prolog?
(define (frst L)
(car L))
(define (last L)
(if (null? (cdr L))
(car L)
(last (cdr L))))
(define (nth L x)
(if (= x 1)
(car L)
(nth (cdr L) (- x 1))))
(define (firstMidLast L)
(list (frst L)
(nth L (ceiling (/ (length L) 2)))
(last L)))
Here's another way to do it!
- The "trick" is to walk down the same list at two different speeds.
- First argument indexing keeps goals
list_first_mid_last(+,?,?,?)
deterministic.
We define list_first_mid_last/4
like this:
list_first_mid_last([E|Es],E,M,L) :-
ahead_of_mid_last([E|Es],[E|Es],M,L).
ahead_of_mid_last([],[M|_],M,M).
ahead_of_mid_last([F|Fs],Es,M,L) :-
more_ahead_of_mid_last(Fs,F,Es,M,L).
more_ahead_of_mid_last([],L,[E|_],E,L).
more_ahead_of_mid_last([F|Fs],_,Es,E,L) :-
evenmore_ahead_of_mid_last(Fs,F,Es,E,L).
evenmore_ahead_of_mid_last([],L,[E|_],E,L).
evenmore_ahead_of_mid_last([F|Fs],_,[_|Es],M,L) :-
more_ahead_of_mid_last(Fs,F,Es,M,L).
Let's run a few queries and put Prolog1 and Scheme2 results side-by-side!
% Prolog % ; Scheme ?- list_first_mid_last([1],F,M,L). % > (firstMidLast `(1)) F = M, M = L, L = 1. % (1 1 1) % ?- list_first_mid_last([1,2],F,M,L). % > (firstMidLast `(1 2)) F = M, M = 1, L = 2. % (1 1 2) % ?- list_first_mid_last([1,2,3],F,M,L). % > (firstMidLast `(1 2 3)) F = 1, M = 2, L = 3. % (1 2 3) % ?- list_first_mid_last([1,2,3,4],F,M,L). % > (firstMidLast `(1 2 3 4)) F = 1, M = 2, L = 4. % (1 2 4) % ?- list_first_mid_last([1,2,3,4,5],F,M,L). % > (firstMidLast `(1 2 3 4 5)) F = 1, M = 3, L = 5. % (1 3 5) % ?- list_first_mid_last([1,2,3,4,5,6],F,M,L). % > (firstMidLast `(1 2 3 4 5 6)) F = 1, M = 3, L = 6. % (1 3 6) % ?- list_first_mid_last([1,2,3,4,5,6,7],F,M,L).% > (firstMidLast `(1 2 3 4 5 6 7)) F = 1, M = 4, L = 7. % (1 4 7)
Footnote 1: Using swi-prolog version 7.3.11 (64-bit).
Footnote 2: Using the scheme interpreter SCM version 5e5 (64-bit).
这篇关于如何获取列表方案和序言的第一个、中间和最后一个元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!