проломить список

71
8

Пример такой:

?- runs([3,4,5,4,2,7,5,6,6,8,3], RunList).
RunList = [[3, 4, 5], [4], [2, 7], [5, 6, 6, 8], [3]]

Список необходимо разбить на несколько неубывающих последовательностей последовательных чисел. Мой код:

next([],0).
next([H|_],R):-
R is H.

runs1([],[]).
runs1([H|T],R):-
runs1(T,R1),
next(T,X),
H=<X,
R = [H|R1].
runs1([H|T],R):-
runs1(T,R1),
next(T,X),
H>X,
R = [[H]|R1].

Я пробовал много методов, но до сих пор не знаю, как его написать...

Надеюсь, кто-то может мне помочь.

Заранее спасибо.

спросил(а) 2015-04-04T14:49:00+03:00 5 лет, 6 месяцев назад
1
Решение
58

Для логически чистой и монотонной реализации взгляните на мой ответ на соответствующий вопрос " Извлечение последовательностей (списки) Prolog ".

Я представляю мета-предикат splitlistIfAdj/3 основанный на if_/3 предложенный @false в этом ответе. splitlistIfAdj/3 обеспечивает логическую устойчивость, оставаясь при этом детерминированным.

Предикат, переданный в splitlistIfAdj/3 должен подчиняться тому же соглашению, что и (=)/3 и memberd_truth/3. Для вашего случая нам нужно определение (#>)/3:

#>(X,Y,Truth) :- X #> Y #<==> B, =(B,1,Truth).

Позвольте использовать splitlistIfAdj/3 и (#>)/3 в примере, который вы splitlistIfAdj/3:

?- splitlistIfAdj(#>,[3,4,5,4,2,7,5,6,6,8,3],Pss).
Pss = [[3,4,5],[4],[2,7],[5,6,6,8],[3]]. % succeeds deterministically

Теперь позвольте задать более общий запрос:

?- splitlistIfAdj(#>,[A,B],Pss).
Pss = [[A],[B]], A#>=_X, B+1#=_X ;
Pss = [[A,B]], A#>=_Y#<==>_Z, B+1#=_Y, _Z in 0..1, dif(_Z,1).

Наконец, запустите запрос, который @lurker предложил в своем комментарии к @rrrfer:

?- splitlistIfAdj(#>, Ls, [[3,4,5],[4],[2,7],[5,6,6,8],[3]]).
Ls = [3,4,5,4,2,7,5,6,6,8,3] ;
false.

ответил(а) 2015-05-02T17:20:00+03:00 5 лет, 5 месяцев назад
-4

runs([], []):-!.
runs([H|T], S):-
runs(T, TS),
ins(H, TS, S).

ins(E, [], [[E]]):-!.
ins(E, [[H|T]|TL], [[E, H|T]|TL]):-
H >= E, !.
ins(E, TL, [[E]|TL]).

ответил(а) 2015-04-04T16:03:00+03:00 5 лет, 6 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема