首页 > 解决方案 > 如何删除嵌套列表中每隔一秒出现的元素 - PROLOG

问题描述

假设我有一个类似的列表[1,[2,1,[2],[3,1,1,[[3]],1,[1]],1],2,1,2,1,3],我想从中删除每第二个出现的 '1' 以获得[1,[2,[2],[3,1,[[3]],1,[]],1],2,2,1,3]. 到目前为止,我想出的是:

delete_second_occurrence([], [], _, _).
delete_second_occurrence([X|L], [X|R], X, N) :-
   0 is mod(N, 2),
   N1 is N + 1,
   delete_second_occurrence(L, R, X, N1).
delete_second_occurrence([X|L], R, X, N) :-
   1 is mod(N, 2),
   N1 is N + 1,
   delete_second_occurrence(L, R, X, N1).
delete_second_occurrence([E|L], [E|R], X, N) :-
   is_list(E),
   delete_second_occurrence(E, R, X, N),
   delete_second_occurrence(L, R, X, N).
delete_second_occurrence([E|L], [E|R], X, N) :-
   delete_second_occurrence(L, R, X, N).

澄清,

它会删除最低级别中的每一秒,但对嵌套列表不执行任何操作。我将如何删除嵌套列表中的重复项?

标签: prolog

解决方案


主要问题是第四条:

delete_second_occurrence([E|L], [E|R], X, N) :-
    is_list(E),
    delete_second_occurrence(E, R, X, N),
    delete_second_occurrence(L, R, X, N).

第二个条件为真,如果R是删除每第二次出现的Xin的结果E。第三个条件为真,如果R是删除每第二次出现的Xin的结果L。此外,在调用和N后必须具有相同的值。没有多少列表具有这些属性。有两个问题需要解决:delete_second_occurrenceEL

  1. 在第一次调用时选择不同的变量名delete_second_occurrence并适当地更新子句的头部。
  2. 引入另一个参数,表示递归调用后累加器的状态。

X您可以使用布尔变量,而不是计算遇到的次数。不需要执行模运算。完成此操作后,您会注意到您的程序生成了一个正确的解决方案和几个不正确的解决方案。例如,考虑第五个子句:

delete_second_occurrence([E|L], [E|R], X, N) :-
   delete_second_occurrence(L, R, X, N).

该子句指出,如果是[E|R]每第二次出现的Xin删除一次的结果是删除一次in的结果。这并非总是如此。例如,如果is并与统一,您当然不想包含在输出列表中。同样,如果是一个包含 的列表,您可能不应该生成简单地添加到递归调用结果的解决方案。[E|L]RXLN1EXEEXE


推荐阅读