2016-05-31 70 views
1

所以我不期望今天發佈更多,但我不知道做這個任務,我傻了。我有工作代碼旅行輸入列表3乘3元素。但我只是意識到它只適用於3個元素的列表,當我輸入4時失敗。說得通。因此,我試圖制定一個規則,逐個接收每個元素,以這種方式傳送兩個列表,並且由於這兩個列表同樣長,所以它們應該同時停止,並且我的輸出列表應該與之前一樣!如何旅行一個列表n由n元素

但不是一個機會,它直線上升失敗。我認爲我以錯誤的方式看待這個問題,因爲這不是一件非常困難的事情。

原來,工作了3種元素的想法:

crearEnum(_, [], []). 
crearEnum([Ha,Hb,Hc], [[H1,H2,H3]| PermNodes], [[enum(H1,Ha), enum(H2,Hb), enum(H3,Hc)] |SalidaCreacionEnum]):- 
    crearEnum([Ha,Hb,Hc], PermNodes, SalidaCreacionEnum). 

我得到了什麼至今:

我稱之爲這個(一個更大的規則,它的一部分):

crearEnum(NodeListUnique, IDsPermuted, [], SalidaCreacionEnum), 


crearEnum(_, [], L, L). 
crearEnum(NodeListUnique, [CabezaPermNodes| PermNodes], [EnumsFormados |EntradaCreacionEnum], SalidaCreacionEnum):- 
    formaEnums(NodeListUnique, CabezaPermNodes, EnumsFormados), 
    crearEnum(NodeListUnique, PermNodes, EntradaCreacionEnum, SalidaCreacionEnum). 

formaEnums([],[],_). 
formaEnums([Ha|NodeListUnique], [H1|CabezaPermNodes], [enum(H1,Ha)|EnumsFormados]):- 
    formaEnums(NodeListUnique, CabezaPermNodes, EnumsFormados). 

而一絲痕跡,令我d目結舌,對我而言,這難以爲繼:

Call:crearEnum([c, b, a], [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]], [], _G5349) 
Fail:crearEnum([c, b, a], [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]], [], _G5349) 

基本上,因爲我一直在做類似的操作,但是這個直接失敗了。我想這是因爲統一或基本情況?但是我沒有看到與其他列表有很大差異,我可以看到他們是如何旅行和工作的,所以並不真正瞭解這方面的問題。

回答

1

好吧,找到它。我試圖分開一個空列表的頭部和尾部,所以答案是,它失敗了,無法完成。

因此,它應該是這樣的:

crearEnum(NodeListUnique, [CabezaPermNodes| PermNodes], [EntradaCreacionEnum], SalidaCreacionEnum):- 

,如果它要對空列表調用。這使得WAY的時間超過了它應該的時間。

+0

我以某種方式懷疑這是正確的解決方案。最好是使用[tag:dcg]來描述列表,或者進一步實例化給定列表。後者意味着你可能會在某個地方有一個像'Ls = [First | Rest]這樣的目標,或者像這個子句的* head *中的[First | Rest]這樣的模式。 – mat

+0

我能否看到一些已經完成的例子,以進一步實例化給定的列表?我覺得這樣會讓我的代碼更容易閱讀,但它也是性能,但現在我堅持使用這種解決方案(就像我現在認爲這是解決這類問題的方法,並且不真的看到另一個)。至於dcg,我可能會嘗試它,但我不確定我會掌握它的時間,我有:( – keont

3

在這種情況下的基金問題是,[First|Rest]意味着不同於你認爲的 。這意味着列表的第一個元素First。它確實是而不是的意思是「以的元素First開始的列表」。因此,如果First本身是列表,則[First|Rest]是其列表的第一個元件是列表。

該問題特別體現在[EnumsFormados|EntradaCreacionEnum],其中EnumsFormados本身的一個列表。

Reasonsing有關貫穿多個謂詞的描述可以很容易出錯和繁瑣,因爲這個原因列表,我們有DCG  符號  ()在序言:它使描述列出要容易得多,特別是如果單個列表的描述跨越多個規則。

我給你一個與你的用例鬆散相關的例子。只需稍作修改,您可以使用此DCG來描述對您而言很重要的列表。我將描述表格  enum(Unique,Node)的條款清單。

 
enums([], _) --> []. 
enums([U|Us], Nodes) --> 
    enums_(Nodes, U), 
    enums(Us, Nodes). 

enums_([], _) --> []. 
enums_([N|Nodes], U) --> 
    [enum(U,N)], 
    enums_(Nodes, U). 

樣品的查詢和答案:

 
?- phrase(enums([a,b], [x,y,z]), Ls). 
Ls = [enum(a, x), enum(a, y), enum(a, z), enum(b, x), enum(b, y), enum(b, z)]. 

注意參數不用具有相同的長度!還要注意,該定義跨越了多個子句,但它很容易描述列表的元素。 DCG  語法[Terminal]用於聲明特定的Prolog術語  Terminal發生在所描述的列表中的該位置。