【问题标题】:Prefix in PrologProlog 中的前缀
【发布时间】:2015-05-08 14:50:12
【问题描述】:

我是 Prolog 的新手。 我对谓词前缀有疑问,但有点不同。

我想得到一个列表的前缀,但直到一个元素 列表可以有重复元素。

一个例子:

prefix(Element, List, Prefix)
prefix(c, [a,b,c,d,e,f], [a, b])

不包含该元素。

我目前拥有的是这个

prefix(X, [X|T], []).
prefix(X, [Y|T], [Y|Z]):-
    prefix(X, T, Z).

但它不起作用。

L = [a,b,c] ? prefix(b, L, Prefix).

no
?- 

谢谢

【问题讨论】:

  • “:-”前缺少右括号。
  • 请解释一下不起作用
  • 你最后一段代码中的问号是什么?它应该是一个分号。
  • @Danick:我更新了我的答案。

标签: list prolog prefix


【解决方案1】:

使用dif/2,您可以在ElementX \== Element 之前为任何成员X 明确声明:

prefix(Element, [Element|_], []).
prefix(Element, [Head|List], [Head|Prefix]) :-
    dif(Element, Head),
    prefix(Element, List, Prefix).

或者同样,因为我想在我的答案的第一次迭代中使用append/3

prefix(Element, List, Prefix) :-
    append(Prefix, [Element|_Suffix], List),
    maplist(dif(Element), Prefix).

后缀基本一致:

suffix(Element, List, Suffix) :-
    append(_Prefix, [Element|Suffix], List),
    maplist(dif(Element), Suffix).

如果你不想使用maplist(dif(Element), List)

all_dif(_, []).
all_dif(X, [H|T]) :- dif(X, H), all_dif(X, T).

【讨论】:

  • 还有一个问题,如果我想做同样的事情,但从最后一个开始,比如后缀,怎么样?
  • @Danick,如果您使用append/2 变体,则基本相同。我将其添加到我的答案中。
  • 没有maplist有什么方法可以实现吗?因为我们不能使用库
【解决方案2】:

这是使用定句语法 和非终结符all_seq//2 的解决方案:

prefix(X, Xs, Ys) :-
   phrase( ( all_seq(dif(X), Ys), [X], ... ), Xs).

... --> [] | [_], ... .

所以语法(phrase/2 内)为:

有 1. 一个初始序列Ys,所有元素都不同于X,然后是2.X,然后是3.任何东西。

还有一个缺点,在使用 DCG 时通常会出现这种情况:实现没有尽可能确定,因此会留下多余的选择点。

【讨论】:

  • 您的解决方案对于 OP 的目的和技能水平来说似乎太复杂了。
  • @migfilg:你可以随意给出一个不太复杂的答案。
  • 我们不能使用复杂的解决方案
  • @danick:是的,我希望如此。 @false:@danick 的解决方案对我来说几乎没问题,我会在第一个子句中使用一个 cut 来避免例如对 prefix(a,[a,b,a,c],L) 有第二个错误的解决方案。我认为我不应该将此作为答案发布。
  • @migfilg:切???我在这里看不到干净的用途(除非您付出了很多额外的努力)
【解决方案3】:
prefix(X,[X|T],[]).
prefix(X,[Y|T],Z) :- prefix(X,T,M)  , Z = [Y|M].

输出:

?- L = [a,b,c,d,e,f] ,前缀(d,L,G)。
L = [a, b, c, d, e, f],
G = [a, b, c]。

?- L = [a,b,c,d,e,f] , 前缀(e,L,G)。
L = [a, b, c, d, e, f], G = [a, b, c, d]。

编辑 #1
原始代码正在运行,请使用 (,) 而不是 (?) 如下。

prefix(X,[X|T],[]).
prefix(X,[Y|T],[Y|Z]) :- prefix(X,T,Z).

输出:

?- 前缀(d , [a,b,c,d,e] , G)。
G = [a, b, c]
?- L = [a,b,c] , 前缀(b, L, Prefix)。
L = [a, b, c],
前缀 = [a] .

编辑 #2 正如评论中提到的用户false,我可以确认您是对的,但在我的解决方案中,我假设列表包含唯一元素:
prefix(d,[d,d],[d]) 成功 - 它应该失败,

【讨论】:

  • prefix(d,[d,d],[d]) 成功 - 它应该失败。
  • 在我修改答案后希望有人投票^_^。
  • 它看起来仍然不正确,您无法添加自己的假设。
  • 是的,错误是正确的。抱歉没有提到列表可以有重复元素。它应该只给出第一个答案。
  • @Danick:你说“直到一个元素”。我看不出你原来的问题有任何歧义。
猜你喜欢
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
相关资源
最近更新 更多