我正在尝试检查第一个列表中的任何元素是否与第二个列表匹配。如果找到匹配,则对该元素进行分类并与该元素进行拆分,然后我们再次检查列表的其余部分。如果在特定的分类中发现了更多的匹配项,则将这些列表追加。
我尝试了下面的一些分类代码,但没有正确工作。这种格式的顺序只是工作。
?- 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].
为了简化我的生活,我将原子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分钟在上面,发现它太难调试了。一个口头的草图是这样的:委托给一个带有累加器的helper方法,一个"rest"变量,每个bin有两个变量:一个用于输入,一个用于输出。helper方法有一个获取空列表的情况;将输入变量映射到输出变量,将累加器映射到"rest"变量。现在,helper为每个"endcap"都有一个case,它们看起来几乎相同:将累加器附加到endcap的singleton列表中,并将其转发到递归调用中,作为该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
调用它。现在我说,假设我有一些尾数类别。让我从这个类似查找表的结构中获取所有内容
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能力还不够强大。也许其他人会尝试一下?
所以,为一个毫无意义的难题喝彩!这是我很长一段时间以来在序言中回忆起的最奇怪的问题之一!我真的不明白你为什么会想要这个,但我希望我的代码能有所帮助,尽管它的效率非常低。