2016-10-20 85 views
0

背景複雜列表操作

我有下面的代碼,將取出第一列表元素中的內部列表。

實施例: getFirstElement([[1,DATA1],[[2,DATA2],[3,DATA3],[[4,DATA4],[5,DATA5]]]],O) Ø會返回爲[2]。

getFirstElement([H | T], [X| Tn]) :- 
    [[X, _] | _] = H. 

getFirstElement([H | T], O) :- 
    getFirstElement(H, O) ; 
    getFirstElement(T, O). 

問:

如何擴展功能,以便將返回所有occurenses的列表,而不是僅僅是第一次?有用輸出的

實施例:

getFirstElement([[1,DATA1],[[2,DATA2],[3,DATA3],[[4,DATA4],[5,DATA5]]]] ,O)。 O將返回[2,4]。

+1

你是什麼意思「內部列表中的第一個元素」?爲什麼你需要這樣一個複雜的嵌套列表?你意識到'[1,2,3]'實際上是'。(1,。(2,。(3,[])))',對吧?你顯示的嵌套列表奇怪地類似於「平面」列表的嵌套項。 –

+0

@boris您的權利,我試圖刪除所有非法的數據,以便使問題更容易理解,我現在改爲普通結構。問題是我必須跟蹤內部列表發生的位置,而我的方法是在發生嵌套列表時存儲第一個元素,如[2,data2]和[4,data4]中發生的示例 – LamaCoder

+1

仍然不存在不明白你的答案中的「1」不合格。是否因爲它不是列表中列表中第一個元素的第一個元素?順便說一句,這是一個非常複雜的結構,你確定你需要它嗎?它背後的理由是什麼? –

回答

1

我認爲混亂的原因之一是您使用列表來表示對。如果您使用X-Y來代表對(如在Prolog中是常規的那樣),則會更清楚發生了什麼。所以,你的第一個例子是:

getFirstElement([1-data1, [2-data2, 3-data3, [4-data4, 5-data5]] ], O) 

我從Ø應該在任何深度綁定到的「內部」列表中的第一個元素的謂詞的名字假設和不確定地返回所有的解決方案(即在回溯)。

你可以通過提取這些「內部」列表然後返回它們的第一個元素來做到這一點。

get_first_element(Xs, E) :- 
    inner_list(Xs, Y), 
    Y = [E|_]. 

inner_list([X|_], Inner) :- 
    is_list(X), 
    X = Inner. 
inner_list([X|_], Inner) :- 
    inner_list(X, Inner). 
inner_list([_|Xs], Inner) :- 
    inner_list(Xs, Inner). 

例如:

?- get_first_element([1-data1, [2-data2, 3-data3, [4-data4, 5-data5]]], E). 
E = 2-data2 ; 
E = 4-data4 ; 
0
getE([Num, Data], O) :- 
    not(is_list(Num)), 
    not(is_list(Data)). 

getE([H | T], [X | Tn]) :- 
    [[X, _] | _] = H, 
    getE(T, Tn), 
    getE(H, Tn). 

getE([H | T], O) :- 
    getE(T, O), 
    getE(H, O). 

getE([], O). 

事情,我錯過了:

  • 分裂的頭時,它是一個內部列表(缺少內部列表中的所有內部列表)
  • 在處理沒有任何內部列表的列表時處理案件,沒有規則讓Prolog繼續搜索是否已經達到。
  • 終於有一個基本的情況下需要。

雖然代碼有一個問題,但當在序言中運行以下代碼時,它返回O = [2,4,5 | _G12383],而不是O = [2,4,5]。 trace,getE([[1,data1],[[2,data2],[3,data3],[[4,data4]],[[5,data5]]]],O)。