2014-10-23 2 views
2

Я хочу написать предикат split(List, Pivot, Result) имеет место, когда Result - это список подписок, которые List делится на Pivot. Например, split(['_', '_', '#', '_', '#', '_'], '#', [['_','_'], ['_'], ['_']]) - true.Как разбить список в Prolog?

Мой код, как это и он не работает:

split(List, Pivot, Result) :- 
split(List, Pivot, _, _, Result). 

split(List, Pivot, Left, Right, X|Xs) :- 
    append(Left, [Pivot|Right], List), 
    !, 
    member(Pivot, Right) 
    -> X = [Left], 
     split(Right, Pivot, _, _, Xs) 
    ; X = [[Left]|[Right]]. 

Я не думаю, что мой подход понятнее либо. Может ли кто-нибудь дать мне совет? Спасибо.

ответ

2

Вот один из способов сделать это:

split(L,P,R):-split(L,P,[],R). 
split([],_,[],[]). 
split([],_,S,[S]) :- S \= []. 
split([P|T],P,[],R) :- split(T,P,[],R). 
split([P|T],P,L,[L|R]) :- L \= [], split(T,P,[],R). 
split([H|T],P,S,R) :- H \= P, append(S, [H], S2), split(T,P,S2,R). 

Demo.

split/4 предикат добавляет параметр в положении 3, что означает "список построенных до сих пор". split/3 - это простое перенаправление с установленным «списком до» [].

Оговорки о строках 2 и 4 описывают ситуации, когда два Pivot s находятся в строке, и когда шарнир обнаружен в конце последовательности. Эти положения предотвращают вставку пустых списков.

+0

Я все еще пытаюсь понять ваш ответ, но это работает! Благодаря! – user3928256

2

Мы можем сохранить и выполнить работу в кратчайшие сроки, просто используя нужные инструменты!

Давайте использовать splitlistIf/3 и reified equality predicate(=)/3 в запросе:

?- Xs = ['_','_',#,'_',#,'_'], splitlistIf(=(#),Xs,Ys). 
Xs = [ '_','_' ,#,'_',#,'_' ] 
Ys = [['_','_'], ['_'],['_']].  % succeeds deterministically 
Смежные вопросы