Re: [問題] prolog
※ 引述《RZAddict (鴆羅)》之銘言:
: 要練習prolog寫了一個簡單的題目
: 要把list裡面找到的第二個element拿出來
: takeoutSecond(A,B,C)
: 把Blist裡面找到的第二個A拿掉
: 我寫了這樣
: takeout(A,[A|B],B).
: takeout(A,[B|C],[B|D]) :- takeout(A,C,D).
你寫的takeout/3意思是從第二個參數中將第一個參數取走一次.
: takeoutSecond(A,[B|C],[B|D]):- takeoutSecond(A,C,D).
: takeoutSecond(A,[A|B],[A|C]):- takeout(A,B,C).
: 可是出來的結果是把最後一個A拿掉
然後takeoutSecond/3這個是只把最後一個第一個參數拿走嗎? 好像不是.
takeout/3是拿走任何一個可以拿走的第一個參數, (而且 takeout(1,[2,3,4],L)
為false... 這個,沒有意義吧!? ) 所以,第二句的意思是
如果你可以從B把A拿走而得到C, 就可以從 [A|B] 中拿走 B 中的 A 而得到 [A|C].
根據第二句的意思,會出現拿走最後一個A的答案.
然後看第一句: 如果你從C list,使用takeoutSecond/3規則,拿走A而得到D,
那麼就可以從 [B|C] 的 C 中拿走A,而得到 [B|D].
結論是因為 takeout/3 可以拿走所出現的任何一個第一個參數, 所以
takeoutSecond(2, [1,2,3,2,4,2,5], L) 的結果是:
L = [1, 2, 3, 2, 4, 5] ; %%拿走最後一個
L = [1, 2, 3, 4, 2, 5] ; %%拿走倒數第二個
L = [1, 2, 3, 2, 4, 5] ; %%拿走最後一個
false.
重複出現同一結果,是因為某個規則重複執行.
: 如果加一行takeoutSecond(A,[],[]).
: 就變成完全不會拿掉
: 請問哪裡出錯了??
加一行 takeoutSecond(_, [], []). 會增加一個沒有任何項目被拿掉的結果.
takeoutSecond(2, [1,2,3,2,4,2,5], L) 會多得到一個
L = [1, 2, 3, 2, 4, 2, 5] ;
這一筆結果. 這是因為第一句規則中,可以對第二和第三個參數一直將head拿走,
最後就變成 takeoutSecond(A, [], []). 執行為 true.
所以什麼都沒有拿掉.
------------------------
接下來是我的解題: 從一列中拿走第二個occurrence,
首先可以想到拿走第一個occurrence很簡單:
remove_first(A, [A|B], B) :- !. %%從 [A|B] 中拿走第一個出現的A.
此外也不要忘了另一種情況:
remove_first(A, [B|C], [B|D]) :- remove_first(A, C, D).
注意第一句要有一個cut. 然後你可以確定:
?- remove_first(2, [1,3,4,5,2,6,2], L).
L = [1, 3, 4, 5, 6, 2].
若已經有 remove_first/3 而且你相信它完全正確,那就可以寫 remove_second/3:
remove_second(A, [A|B], [A|C]) :- remove_first(A, B, C).
remove_second(A, [B|C], [B|D]) :- A \== B, remove_second(A, C, D).
--
/yau
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.231.70.30
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
Programming 近期熱門文章
PTT數位生活區 即時熱門文章