Prolog列表高原 [英] Prolog List Plateau

查看:76
本文介绍了Prolog列表高原的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是被介绍到序言中,试图通过一些简单的练习来完成,但是我一直对此卡住了. 我正在尝试编写一个输出输入列表的所有子列表的程序,其中每个子列表的长度均大于1,并且无法将其扩展为更大的子列表.它还将在子列表的列表中输出起始位置.因此,示例输出将为

Just got introduced to prolog, trying to get through some simple exercises, but I've been getting kind of stuck on this one. I'm trying to write a program that outputs all the sublists of the input list, where each sublist has length > 1 and it cannot be extended to a larger sublist. It will also output the starting position in the list of the sublist. So a sample output would be

| ?- plateau([a,a,b,2,2,2,a+1,a+1,s(1,2)], I, Len).
    I = 1,
    Len = 2 ? ;
    I = 4,
    Len = 3 ? ;
    I = 7,
    Len = 2 ? ;
    no

我仍然对整个声明式的事物感到困惑,并且在切换到命令式模式时遇到了很多麻烦. 我在想让我的程序做类似的事情

I'm still pretty confused by the whole declarative thing, and having a lot of trouble switching out of imperative mode. I'm thinking I want my program to do something like

program([H|T],I,L):-
    T = [H1|T1] %split the tail
    ([H] = [H1] -> Count is Count+1, program(T,I,Count) 
     %if First element = second element, recurse with new values
    ; length(T,Spot), 
      %get the spot where you are in the list, so we know where sublist starts
      program(T,Spot,L) %run again, from tail, since sublist didn't have another  element?
program([],I,L). %terminate when entire list has been run through?

因此,出于某些原因,我无法判断这是行不通的.我不重置计数",所以它可能会将所有子列表的值总计在一起?有什么办法可以解决这个问题?我的基本情况可能也不是我想要的-我只是不确定它到底应该是什么?我可能也错过了其他东西...任何帮助将不胜感激! :) 谢谢!

So this isn't working, from what I can tell for a couple reasons. I don't reset 'count', so its totaling up the values of all the sublists together maybe? Is there some way to work around for this? My base case might also not be what I want - I'm just not sure what it should be really? I'm probably missing other things too...any help is greatly appreciated! :) Thanks!

推荐答案

这里有很多复杂的答案.考虑一下这种不使用DCG或许多内置功能(对于初学者来说可能更简单)的方式:

There are quite a lot of complicated answers here. Consider this one which doesn't use DCGs or many built-ins (perhaps simpler for a beginner):

plateau([X|Xs], I, L) :-
    plateau(Xs, 1-1-X, I, L).

plateau([X1|Xs], I0-L0-X0, I, L) :-
    X0 == X1, !,
    NL0 is L0 + 1,
    plateau(Xs, I0-NL0-X0, I, L).

plateau(_, I-L-_, I, L) :-
    L > 1.

plateau([X|Xs], I0-L0-_, I, L) :-
    NI is I0 + L0,
    plateau(Xs, NI-1-X, I, L).

第一个子句建立一个调用,该调用累积一个(index)-(length)-(sublist element)元组.

The first clause sets up the call which accumulates the (index)-(length)-(sublist element) tuple, as a term.

如果下一个列表element是相同的,则next子句会增加length(请注意索引不会更改).

The next clause increments the length if the next list element is the same (note the index isn't altered).

仅当第二子句在测试子列表元素运行是否中断时(由于剪切!)失败,并且在运行的length> 1时返回解决方案时,才调用第三子句.

The third clause is called only if the second clause failed when testing if the sublist element run was broken (because of the cut !), and returns a solution iff the length of the run was > 1.

last子句使Prolog可以回溯并从上次运行重新开始搜索.

The last clause enables Prolog to backtrack and re-start the search from the last run.

编辑:gusbro的解决方案实际上与该解决方案非常接近... +1.

gusbro's solution is actually very close to this one... +1.

这篇关于Prolog列表高原的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆