2017-05-08 71 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 
相關問題