2017-05-08 76 views
2

我试图开发代码在序言中捕捉到的物品与频率0看一下例子,元组:捕获值,并添加到另一个列表

[[1,31],[2,0],[3,21],[4,0],[5,0]] 

每个元素其他与每个2个元素,使应检测的部件的东西是2,图4和图5,用于频率为0下面的代码表示的想法:

match([],_). 
match([[A,Y]|Tail],[A|Tail2]):- Y==0,match(Tail,[Tail2|A]),!. 
match([[_,_]|Tail],X):- match(Tail,X). 

两个参数被传递:包含所述组的元组目标值和频率,

(["Target value", "frequency"], ["target value", "frequency"], ...] 

而第二个参数是变量,它接收目标元素。然而,我不得不开发代码的抽象是不正确的,因为结果并不如预期。我已经一步一步地理解,修改了几件事情,结果总是一样的......只有2个元素的列表在任何情况下都会返回(即使只有一个频率为0的目标)。

实施例3倍的频率的目标0:

?- match([[1,31],[2,0],[3,312],[4,0],[5,0]],X). 
X = [2|4]. 

预期结果为这种情况下:X = [2,4,5]。

实施例用1频率靶0:对于这种情况

?- match([[1,31],[2,0],[3,312],[4,312],[5,123]],X). 
X = [2|_9998]. 

预期结果:X = [2]。

有人可以帮助我吗?

回答

1

你非常接近!只是两个小问题:

  • 当前当一个空列表通过它,你说结果可以是任何东西(_)。我非常怀疑这是你想要的;空列表的输出也应该是一个空列表。
  • 第二个子句中的递归调用不正确。你想要的结果是A,然后是递归调用的结果(Tail2)。然而,由于某种原因,你也用A写了递归调用。我无法告诉你如何解决这个问题,但你应该自己获得Tail2

此外,你可以避免写Y==0直接写在子句的头部。然后将得到的代码如下所示:

match([],[]). 
match([[A,0]|Tail], [A|Tail2]) :- match(Tail, Tail2), !. 
match([[_,_]|Tail], X) :- match(Tail, X). 

?- match([[1,31],[2,0],[3,312],[4,0],[5,0]],X). 
X = [2, 4, 5] 

?- match([[1,31],[2,0],[3,312],[4,312],[5,123]],X). 
X = [2] 
+0

哇,非常感谢!我现在开始在序言中使用递归逻辑编程对我来说是新事物。有时候我很难理解我必须做的事情。 –

2

你可以选择与DCG中描述像这样的结果列表:

match(Pairs,ZFs) :-   % the items with frequency 0 
    phrase(zeros(Pairs),ZFs). % are described by zeros//1 

zeros([]) -->     % the empty list 
    [].      % contains no items 
zeros([[I,0]|Is]) -->   % if the frequency is 0 
    [I],      % the item is in the list 
    zeros(Is).     % the same for the remaining items 
zeros([[I,F]|Is]) -->   % if the frequency 
    {dif(F,0)},    % is not 0, the item isn't in the list 
    zeros(Is).     % the same for the remaining items 

因此,在您的文章两个示例查询产生预期的结果:

?- match([[1,31],[2,0],[3,21],[4,0],[5,0]],X). 
X = [2,4,5] ? ; 
no 
    ?- match([[1,31],[2,0],[3,312],[4,312],[5,123]],X). 
X = [2] ? ; 
no 
相关问题