我是Prolog
的新手。考虑以下示例:
MainList = [["A","a","0"],["A","b","0"],["B","a","0"],["B","b","0"],["A","a","1"],["B","b","1"],["C","c","1"],["C","a","0"]]
SubList = ["A","b","-']
MainList
的格式:第一个索引应该是大写字母,第二个索引应该是小写字母,第三个索引应该是数字。 MainList
可以包含其他格式(和长度),但我选择此格式是因为它更易于解释。我只想解释一下,每个子列表的索引都分为几类-每个列表的第一个元素属于category1
,第二个元素属于category2
,依此类推。 "-"
符号表示我们确实知道该元素与其他元素的结合。
我要创建的关系应通过MainList
并删除所有不遵循SubList
的子列表。对于上面的示例,它应该返回:
Output = [["A","b","0"],["B","a","0"],["C","c","1"],["C","a","0"]]
说明:"A"
与"b"
一起工作,因此应检查包含这些元素之一的每个子列表。如果它们都存在,那就没关系(没有重复项)。否则,如果仅存在其中之一,那就不行了,我们不应该将其插入Output
列表中。
另一个示例(MainList
与之前的示例有点不同):
MainList = [["A","a","0"],["A","b","0"],["B","a","0"],["B","b","0"],["A","b","1"],["B","b","1"],["C","c","1"],["C","a","0"]]
SubList = ["C","a","0"]
Output = [["A","b","1"],["B","b","1"],["C","a","0"]]
我确实了解算法-我们应该遍历MainList
的每个子列表,并检查input-sublist的连接是否正常工作,如果可以,我们将其插入Output
列表中。问题是,我不知道如何正确实施它。如果子列表包含多于2
个连接(如第二个示例所示),该怎么办?我应该如何区别于子列表?
编辑:我将尝试说明更多内容。每个元素的位置都很重要。每个地方代表一个不同的类别。例如,第一位可能代表大写字母,第二位代表小写字母,第三位代表数字(类别可能更多)。
我们得到一个sublist
,它表示两个或多个元素之间的键。例如,我们在"A"
和"b"
之间有一个键:["A","b","-"]
。我们应该遍历MainList
的子列表,并检查每个子列表是否包含那些元素之一("A"
和"b"
)。如果是这样,我们应该检查绑定是否正确。例如,如果我们有一个带有A
的子列表(当然是在第一个索引中),那么我们应该转到第二个索引并检查"b"
是否在那里。如果不存在,则不应将其插入Output
列表中,否则将插入。例如,我们有一个债券["A","b","-"]
,并且进入了MainList
的子列表,其子目录如下:["A","a","0"]
或["B","b","2"]
。我们不会将这些列表插入Output
中。但是,如果我们进入["A","b","1"]
,["A","b","2"]
和["B","a","1"]
这样的子列表,我们会将这些列表插入Output
。
答案 0 :(得分:2)
我写了一个代码,可以满足您给出的示例的输出条件,但是没有尝试其他情况或考虑代码的效率,因此您可以在上面进行改进。这是代码:
subList(List,SubL,Out):-
(member("-",SubL),
select("-",SubL,SubRem)
;
\+ member("-",SubL),
SubRem = SubL),
findall(L,((member(L,List),checkEq(SubRem,L));
(member(L,List),checkNeq(SubRem,L))),Out).
checkEq([],_).
checkEq([S|Rest],[E|List]):-
S == E,
checkEq(Rest,List).
checkNeq([],_).
checkNeq([S|Rest],List) :-
\+ member(S,List),
checkNeq(Rest,List).
说明:我所做的是,首先,我从子数组(如果存在)中删除了“-”字符,以便于计算。然后,我要么检查 SubList 中每个元素与 MainList 中所选 sublist 中的元素顺序是否一致的条件。如果失败,则检查所选子列表中是否没有 SubList 的元素。如果两项检查均失败,我将移至下一个子列表。使用findall / 3谓词,我找到满足这些条件之一的所有组合,并将它们组合在列表 Out
中编辑:为checkEq
谓词添加附加子句:
checkEq([S|Rest],[E|List]):-
S \= E,
member(S,List),
checkEq([S|Rest],List).
所以最终版本是:
checkEq([],_).
checkEq([S|Rest],[E|List]):-
S == E,
checkEq(Rest,List).
checkEq([S|Rest],[E|List]):-
S \= E,
member(S,List),
checkEq([S|Rest],List).