作者yauhh (哟)
看板Programming
标题Re: [问题] prolog
时间Fri Dec 16 00:37:01 2011
※ 引述《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