list - 将列表列表中的每个不同数字作为解决方案
问题描述
我需要做一个谓词,select(ListOfLists, X)
它作为解决方案返回列表列表中的每个不同数字,从列表中单独的数字开始,例如:
select([[1,2,3],[1,2],[4],[3]],X).
将返回:
X = 4 ;
X = 3 ;
X = 2 ;
X = 1
只要首先显示列表中单独的数字,顺序就无关紧要。
为此,首先我编写了 2 个其他谓词,它们是:
%OrderedList is Lists ordered by size.
orderListsBySize(Lists, OrderedLists).
示例:orderListsBySize([[1,2],[6],[3,4,5]], L).
->L = [[6], [1,2], [3,4,5]]
和
%ListsWithoutX is Lists without the X elements
removeFromLists(X, Lists, ListsWithoutX).
示例:removeFromLists(1,[[1,2],[3],[4,1,5]],L).
->L = [[2],[3],[4,5]]
两个谓词都有效。
然后,为了做select(ListOfLists, X)
谓词,我尝试了以下方法:
select([[X|[]]|_], X). select(L1,S) :-
orderListsBySize(L1, [[X|XS]|LS]),
length(XS, A),
A == 0,
select([[X|[]]|M], S),
removeFromLists(X, [XS|LS], M).
select([[X|_]|_], X).
但它不起作用。
用其他语言做这个练习并不难,问题是我仍然很难理解 prolog 的工作原理。我很感激任何帮助,谢谢!
解决方案
你可以从:
select2(ListOfLists,Element):-
length(List,_Len),
member(List,ListOfLists),
member(Element,List).
这将返回所有答案,但随后陷入寻找更大列表的循环中。这可以通过使用:-use_module(library(clpfd)).
和定义fd_length/2
不会继续寻找更大的列表然后存在于列表列表中来避免。
fd_length(L, N) :-
N #>= 0,
fd_length(L, N, 0).
fd_length([], N, N0) :-
N #= N0.
fd_length([_|L], N, N0) :-
N1 is N0+1,
N #>= N1,
fd_length(L, N, N1).
select(ListOfLists,Element):-
maplist(length,ListOfLists,Lengths),
sort(Lengths,SortedLength),
last(SortedLength,Biggest),
Biggest #>= Len,
fd_length(List,Len),
member(List,ListOfLists),
member(Element,List).
示例查询:
?-select([[1,2,3],[1,2],[4],[3]],X).
X = 4
X = 3
X = 1
X = 2
X = 1
X = 2
X = 3
false
如果您想要独特的解决方案,您可以将其包含在 a 中setof/3
,然后member/2
再次调用。
推荐阅读
- .net - 如何在点网框架类库的程序集级别指定 ExcludeFromCodeCoverage?
- java - Spring Data MongoDB - 使用 Pageable 查找数百万个数据 - 内存过载?
- r - 如何在基本 R 中为我的茎叶图添加标题?
- javascript - obj.hasOwnProperty 即使在属性创建后也总是返回 false
- ios - 如果用户拒绝了 AppTrackingTransparency 对话框,我们可以初始化 Firebase 吗?
- yugabyte-db - 手动刷新不会删除 YugabyteDB 中的所有 WAL 文件?
- r - 某些列和整个数据框的总和
- mysql - 如何根据以前的列值更新 sql 列
- python - 在为 django 模型创建 TextField 值时扫描三引号字符串文字时的 EOF。(如何正确连接字符串)
- javascript - CSS Rotate 与 Stacking Context Electron APP 混淆