我想在Prolog中解决这个问题 . 我想给出一个自然数列表来查找列表中满足这个条件的所有元素:
All elements on the left of it are smaller than it and all the elements on the right of it are larger than it.
例如给出一个列表 [3,2,4,1,5,7,8,9,10,8]
答案是 5,7
到目前为止,我已经设法使这个函数给定列表的元素,如果元素满足上述条件,则返回true或false .
check(Elem, List) :-
seperate(Elem, List, List1, List2),
lesser(Elem, List1, X1),
bigger(Elem, List2, X2),
size(X1, L1),
size(X2, L2),
size(List, L3),
match(L1, L2, L3),
现在我想创建另一个给定列表的谓词,它为列表的每个元素执行上述计算 . 由于多个元素可能满足它,我想创建另一个列表,其中包含满足问题的所有元素 .
问题可能是 ?-predicate_name([[3,2,4,1,5,7,8,9,10,8],N).
,结果将是一个元素列表 .
Sry如果我没有使用Prolog的正确条款 . 我将用顺序逻辑语言描述我想要做的更具体,尽管这样思考并不是一个好主意 . 如果我们将谓词检查视为给定列表和列表元素的函数,则无论元素是否满足问题条件,它都将返回true或false . 现在我想解析列表中的每个元素,并为每个元素调用函数检查 . 如果那将返回true,那么我将在另一个列表a.k.a结果中添加该元素 . 我想在Prolog中这样做,但我不知道如何迭代列表 .
2 回答
我将对这个问题采取不同的方法 .
我们希望找到满足作为“中间”值的标准的所有值,这个值被定义为大于列表中之前的所有值,并且小于之后的所有值 .
将谓词
mid(L, M)
定义为含义M
是"mid"的"mid"值:每个查询都会找到下一个“mid”:
然后可以使用
findall
捕获它们:这可能不是计算效率最高的解决方案,因为它没有利用“中”的几个属性 . 例如,“mids”将全部连续聚集在一起,因此一旦找到“mid”,继续搜索是否随后遇到一个本身不是“mid”的元素是没有意义的 . 如果效率是目标,那么这些想法可以融入逻辑过程 .
ADDENDUM
由于@false提醒我
maplist
,上述谓词调用less(X, T)
可以替换为maplist(<(X), T)
,从而消除了上述实现中less
的定义 .这是一个使用DCG的版本,并假设我们想要进行算术比较 .
通常不值得进一步优化这一点 . 第一个
seq(Sm)
以及随后的maplist/2
可能会合并在一起 . 这有点棘手,因为必须单独处理Sm = []
和Sm = [_|_]
的情况 .