Prolog:测试任意列表是否对称

发布于 2024-08-15 09:02:17 字数 405 浏览 12 评论 0原文

有没有办法测试任意列表是否对称?

例如:

?- symmetric([a,b,b,a]).
true.

?- symmetric([a,b,c,a]).
false.

?- symmetric([a,a]).
true.

我的尝试是将第一个元素与最后一个元素进行比较,如果它们相等,则删除它们并继续处理列表的其余部分;否则失败。如果列表有 2 个元素并且它们相等,则成功。否则失败。

然而,使用此谓词“查找”列表的末尾并不是真正有效:

last(L,[L]).
last(L,[H|T]):-last(L,T).

有谁知道执行此操作的好方法吗?任何帮助将不胜感激!

顺便说一句:我不关心元素数量不均匀的列表。

Is there a way to test wether an arbitrary list is symmetric?

For example:

?- symmetric([a,b,b,a]).
true.

?- symmetric([a,b,c,a]).
false.

?- symmetric([a,a]).
true.

My attemp was to compare the first element to the last element and if they are equal to remove them and proceed with the rest of the list; otherwise fail. Succeed if the list has 2 elements and they are equal. Otherwise fail.

However "finding" the end of the list using this predicate is not really performant:

last(L,[L]).
last(L,[H|T]):-last(L,T).

Does anyone know of a good way to do this? Any help would really be appreciated!

Btw: I don't care for lists with an uneven amount of elements.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ι不睡觉的鱼゛ 2024-08-22 09:02:17

我找到了我的问题的答案。

对称列表是一个回文(有时你只见树木不见森林)......这个简单的谓词测试了这一点:

is_palindrome(L) :- reverse(L,L).

I found the answer to my question.

A symmetric list is a palindrome (Sometimes you don't see see the forest for the trees)... And this simple predicate tests for that:

is_palindrome(L) :- reverse(L,L).
゛清羽墨安 2024-08-22 09:02:17

但你的算法还是很有趣。有一个 last/2 内置函数(至少在 SWI Prolog 中),它不会受到递归方法性能损失的影响。有了这个,这里是一个实现您的想法的版本:

symmetric([]).
symmetric([L]).
symmetric([H|T]):-
    last(T,H),        % this forces the last element to equal the first
    append(T1,[H],T), % this deconstructs the rest list in one without the last elem.
    symmetric(T1).    % and recurses on that

有趣的是使用 append/3 谓词,将初始剩余列表解构为没有最后一个元素的剩余列表。

编辑:我意识到即使没有 last/2,只需使用 append/3 也可以做到。所以这里是改进的版本:

symmetric([]).
symmetric([L]).
symmetric([H|T]):-
    append(T1,[H],T), % deconstruct and assure symmetry
    symmetric(T1).    % and recurse

现在,这里 append 执行两个操作:解构以获取 T1,并确保列表的最后一个元素与第一个元素匹配:-)。

But your algorithm was interesting nevertheless. There is a last/2 built-in (at least in SWI Prolog) that doesn't suffer from the performance penalty of your recursive approach. With this, here is a version that implements your idea:

symmetric([]).
symmetric([L]).
symmetric([H|T]):-
    last(T,H),        % this forces the last element to equal the first
    append(T1,[H],T), % this deconstructs the rest list in one without the last elem.
    symmetric(T1).    % and recurses on that

Interesting is the use of the append/3 predicate, to deconstruct the initial rest list into the rest list without the last element.

EDIT: I realized I can do even without last/2, just with append/3. So here is the improved version:

symmetric([]).
symmetric([L]).
symmetric([H|T]):-
    append(T1,[H],T), % deconstruct and assure symmetry
    symmetric(T1).    % and recurse

Now, here append does both, the deconstruction to get T1, as well as assuring that the last element of the list matches the first :-).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文