【问题标题】:Prolog: Create sublist, given two indicesProlog:创建子列表,给定两个索引
【发布时间】:2013-05-07 19:32:45
【问题描述】:

基本上,我需要创建一个 sublist(S,M,N,L) 形式的谓词,其中 S 是由索引 M 和索引 N 之间的 L 的元素形成的新列表。

这是我得到的:

sublist([],_,_,[]).
sublist([],M,N,_) :- (M > N).
sublist(S,M,N,L) :- sublist2(S,M,N,L,-1).
sublist2([H|T],St,En,[H2|T2],Idx) :-
   (Idx2 is Idx + 1,
   St =< Idx2,
   En >= Idx2,
   H = H2,
   sublist2(T,St,En,T2,Idx2);
   Idx2 is Idx + 1,
   sublist2(T,St,En,T2,Idx2)).

与我所有的序言问题一样,我觉得我让它变得比它应该的更复杂。我的基本情况是正确的,但其他任何事情的评估结果都是错误的。关于这个问题的任何建议,以及序言的一般方法?我大部分都理解这种语言,但我似乎看不到简单的解决方案。

【问题讨论】:

    标签: prolog


    【解决方案1】:

    简单的解决方案遵循简单的前景。对于列表,它是递归的。递归编程很简单——想象一下你已经有了你的函数,遵循给定的接口/要求,所以你可以随时使用它(但在减少的情况下更好)。

    sublist(S,M,N,[_A|B]):- M>0, M<N, sublist(S,M-1,N-1,B).
    

    将其视为陈述子列表定律:较短列表中的子列表从减小的索引开始。

    sublist(S,M,N,[A|B]):- 0 is M, M<N, N2 is N-1, S=[A|D], sublist(D,0,N2,B).
    

    和,

    sublist([],0,0,_).
    

    它在第二个索引中是独占的。调整它。 :)

    【讨论】:

    • A前面的通配符是什么意思?
    • @AdamDuvall 如果你的意思是下划线_,它告诉prolog忽略这个变量。您可以单独使用下划线,但带名称的下划线更具描述性。
    • @Will Ness 我让它包容性地工作,但如果 M 由于基本情况最初为 0,它就不起作用。它没有得到索引 N 处的元素。
    • @AdamDuvall 它现在可以正常工作:?- sublist(S,0,4,[0,1,2,3,4,5,6]). S = [0, 1, 2, 3] .(调整是在两种情况下使用M=&lt;N而不是M&lt;N,并用两条规则替换基本情况:sublist([],0,0,[]). sublist([A],0,0,[A|_]).。)恭喜您达到 15 个代表,您现在有权投票! :) ;)
    • @WillNess 我现在正在尝试调整它,以便如果N &gt; length(L),而不是评估为假,它就像N = length(L)-1。例如,?- sublist(S,2,100,[0,1,2,3,4]). S = [2,3,4]. 我通过添加第二个谓词 sublist2 并更改 N 的值来实现这一点,但我很好奇是否有更简单的解决方案。
    【解决方案2】:

    有可能以类似于更传统语言的方式处理索引:

    sublist(L, M, N, S) :-
        findall(E, (nth1(I, L, E), I >= M, I =< N), S).
    

    或等效

    sublist(L, M, N, S) :-
        findall(E, (between(M, N, I), nth1(I, L, E)), S).
    

    nth1/3 用于从 1 开始索引,否则 nth0/3 允许 C 风格 - 从 0 开始。我已将子列表作为最后一个参数。 Prolog 中的一个常见约定是在输入之后放置输出参数。

    这里是一个(繁琐的)递归定义

    sublist(L,M,N,S) :- sublist2(1,L,M,N,S).
    
    sublist2(_,[],_,_,[]).
    sublist2(I,[X|Xs],M,N,[X|Ys]) :-
        between(M,N,I),
        J is I + 1,
        !, sublist2(J,Xs,M,N,Ys).
    sublist2(I,[_|Xs],M,N,Ys) :-
        J is I + 1,
        sublist2(J,Xs,M,N,Ys).
    

    【讨论】:

      猜你喜欢
      • 2014-01-12
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 2018-12-10
      • 1970-01-01
      相关资源
      最近更新 更多