代码之家  ›  专栏  ›  技术社区  ›  CodeClown42

递归中的变量赋值

  •  1
  • CodeClown42  · 技术社区  · 7 年前

    useAdd(List, What) :-                                         
        addToList(List, What, New),                               
        reverseList(New, T),                                      
        write("done "),                                           
        write(T), nl, !.                                          
    
    addToList(List, What, [ What | List]).                        
    
    reverseList([], List) :- write(List), nl.                     
    reverseList([H | Old], []) :- reverseList(Old, [ H ]).        
    reverseList([ H | Old], New) :- reverseList(Old, [ H | New]). 
    

    为什么会发生这种情况(在swipl中)?

    ?- useAdd([42, 100, ok], hello).
    [ok,100,42,hello]
    done []
    true.
    

    New 在里面 useAdd 由于将正确的列表传递给 reverseList . 但是,不像 刚出现的 T 在里面 是空的。

    • 这两个作业有什么不同?为什么一个工作而另一个不工作?
    • 我如何才能将反向列表放入 T 在里面 ?
    1 回复  |  直到 7 年前
        1
  •  1
  •   Will Ness Derri Leahy    7 年前

    你对 reverseList/2 使用 T 作为反向列表的尾部。反向列表是在递归的最深层构建和打印的,然后对所创建的值不做任何处理:

    2 ?- reverseList( [1,2,3,4], [0]).
    [4,3,2,1,0]
    true.

    相反,将其作为新的逻辑变量传入,作为第三个参数,在两次调用之间原封不动地传递,最后将其设置为最深层:

    reverseList([], List, T) :- List = T, write(List), nl. 
    reverseList([H | Old], [], T) :- reverseList(Old, [ H ], T).
    reverseList([ H | Old], New, T) :- reverseList(Old, [ H | New], T). 

    那就称它为 reverseList( [1,2,3,4], Newtail, T) 得到你的 T 在递归的最深层设置:

    6 ?- reverseList( [1,2,3,4], [0], T).
    [4,3,2,1,0]
    T = [4, 3, 2, 1, 0].
    

    定义到处都是,命名很糟糕,而且被使用了 可能是“tail”,所以你应该给这个新的参数命名如下 R 相反,至少暗示它将持有 颠倒的 列为

    推荐文章