我正在尝试检查第一个列表中的任何元素是否在第二个列表中匹配。如果找到匹配对该元素进行分类并与该元素分开,那么我们再次检查列表的其余部分。如果在特定分类中找到更多匹配项,则附加这些列表。
我尝试下面的一些分类代码,但它没有正确工作。这种格式的顺序只有效。
?- classify_substituens([1,2,ab,hj,de,as,t,pq,js,xy,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab],
De = [hj, de],
Pq = [as, t, pq],
Xy = [js, xy],
Rest = [ac].
我的代码:
classify_ab(N,Ab,R):-append(B,[ab|R],N),append(B,ab,Ab),!.
classify_de(N,De,R):-append(B,[de|R],N),append(B,de,De),!.
classify_pq(N,Pq,R):-append(B,[pq|R],N),append(B,pq,Pq),!.
classify_xy(N,Xy,R):-append(B,[xy|R],N),append(B,xy,Xy),!.
classify_substituens(List,Ab,De,Pq,Xy,Rest):-
classify_ab(List,Ab_1,Rest_1),
classify_de(Rest_1,De_1,Rest_2),
classify_pq(Rest_2,Pq_1,Rest_3),
classify_xy(Rest_3,Xy_1,Rest4),
classify_substituens(Rest_4,Ab_2,De_2,Pq_2,Xy2,Rest),
append(Ab_1,Ab_2,Ab),
append(De_1,De_2,De),
append(Pq_1,Pq_2,Pq),
append(Xy_1,Xy_2,Xy),
!.
classify_substituens(List,[],[],[],[],List).
我想要下面的目标。
?- classify_substituens([1,2,ab,a,b,xy,as,t,xy,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab],
De = [],
Pq = [],
Xy = [a,b,xy,as,t,xy],
Rest = [ac].
?- classify_substituens([1,2,ab,a,b,de,s,t,ab,i,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab,s,t,ab],
De = [a,b],
Pq = [],
Xy = [],
Rest = [i,ac].
答案 0 :(得分:1)
为了简化我的生活,我称之为原子ab
,de
,pq
和xy
“endcaps。”
endcap(ab).
endcap(de).
endcap(pq).
endcap(xy).
您的代码恰好与此匹配,我认为这更简单:
takeUpto(Token, List, PrefixToken, Remainder) :-
append(Prefix, [Token|Remainder], List),
append(Prefix, [Token], PrefixToken).
classify_substituens(List, Ab, De, Pq, Xy, Rest) :-
takeUpto(ab, List, Ab, R0),
takeUpto(de, R0, De, R1),
takeUpto(pq, R1, Pq, R2),
takeUpto(xy, R2, Xy, Rest).
遗憾的是,这仍然不起作用。你要做的是制作垃圾箱并将所有东西放入正确的箱子里。我看到了通过一次通过的方法,但它相当严重。我花了大约30分钟,发现调试太难了。一个口头草图就是这样:委托给一个带有累加器的辅助方法,一个“rest”变量,每个bin有两个变量:一个用于输入,一个用于输出。辅助方法有一个获取空列表的情况;将输入变量映射到输出变量,将累加器映射到“rest”变量。现在帮助器有一个每个“endcap”的大小写,它们看起来几乎相同:将累加器附加到endcap的单例列表,并将其转发给递归调用作为此endcap的新状态变量。这听起来很容易但是涉及11个变量并且有很多复制/粘贴。
我确实提出了一个解决方案,但对我来说,这似乎很容易读写。效率不高。遗憾。
首先,我希望得到感兴趣的“替代品”。我将它们组合在一起,然后用它们具有的特殊风味标记它们。
substituens(Acc, [], [], Acc).
substituens(Acc, [X|Xs], Subs, Rem) :-
( endcap(X) ->
append(Acc, [X], Substituen),
substituens([], Xs, RemainingSubs, Rem),
append([X-Substituen], RemainingSubs, Subs)
; append(Acc, [X], Acc1),
substituens(Acc1, Xs, Subs, Rem)
).
这样工作原理如下:
?- substituens([], [1,2,ab,a,b,de,s,t,ab,i,ac], Y, Rem).
Y = [ab-[1, 2, ab], de-[a, b, de], ab-[s, t, ab]],
Rem = [i, ac] ;
false.
我没有为此制作substituens/2
包装器,因为我只打算从classify_substituens/6
调用它。现在我说,假设我有一些endcap类别。让我从这个类似查找表的结构中获取所有东西
condense(Category, Groups, Condensed) :-
findall(Group, member(Category-Group, Groups), MyGroups),
append(MyGroups, Condensed).
这取决于append/2
,它不是ISO,但可能不是很难写,因为它只是append/3
的定点。
这两位助手做了classify_substituens/6
的简短工作:
classify_substituens(List, Ab, De, Pq, Xy, Rest) :-
substituens([], List, Subs, Rest),
condense(ab, Subs, Ab),
condense(de, Subs, De),
condense(pq, Subs, Pq),
condense(xy, Subs, Xy).
你有它:
?- classify_substituens([1,2,ab,a,b,de,s,t,ab,i,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab, s, t, ab],
De = [a, b, de],
Pq = Xy, Xy = [],
Rest = [i, ac] ;
false.
?- classify_substituens([1,2,ab,a,b,xy,as,t,xy,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab],
De = Pq, Pq = [],
Xy = [a, b, xy, as, t, xy],
Rest = [ac] ;
false.
顺便说一句,这也告诉我你的一个测试用例是错误的。 :) De
必须始终以de
结尾。
我确实有一种挥之不去的感觉,即使用DCG或差异列表可能有一种高效的和可读方式,但我的DCG功率不够强大,无法看到它。也许其他人会尝试一下?
所以,对于一个没有意义的难题感到荣幸!这是我在prolog很长一段时间内可以回忆的最奇怪的问题之一!我真的不明白为什么你会想要这个,但我希望我的代码有所帮助,即使它效率非常低效。