Удалить членов данного списка, которые появляются после подсписка - PullRequest
2 голосов
/ 17 ноября 2011

Я пытаюсь удалить всех членов списка, появляющихся после подсписка [z, z, z] в Прологе. f.ex removeafterZZZ([a,b,c,z,z,z,a], X) -> X = [a,b,c,z,z,z].

У меня есть методы sublist и join учитывая.

    % first argument is a sublist of the second argument
    sublist(Sublist, List):-
       join(_List1, List2, List),
       join(Sublist,_List3, List2).


    % we get the list in third argument by joining lists from first two arguments
    join([], L, L).
    join([Head | Tail1], List2, [Head | Tail3]):-
    join(Tail1, List2, Tail3).

Итак, я думал о 3 возможных «вариантах» ввода:

1) []

2) что-то вроде [a, b, c], [a, b, c, z, z], где автоматически выводится == input

3) что-то вроде [a, b, c, z, z, z, a]

Итак, я подумал о 3 правилах:

removeafterZZZ([],[]).   %for empty lists
removeafterZZZ(List,X) :=                   %for lists with no [z,z,z] sublist
       not ( sublist ( [z,z,z], List)) , 
       X = List.

removeafterZZZ([H|T], X) :=           %for lists with sublist [z,z,z]
       join(H, X, X),                 %join the head of list with X
       removeafterZZZ(T, X).          %call function again with tail

Так что это, очевидно, не работает таким образом, как я узнаю, что я уже записал z, z, z в список вывода? Должен ли я использовать счетчик? Как?

Ответы [ 3 ]

1 голос
/ 17 ноября 2011

Если вам разрешено использовать append (это стандартный предикат списка, поставляемый с прологом), вот общий метод для удаления суффикса -

% removeAfterSuff(Original List, Suffix To Remove, Result)
removeAfterSuff(X, [], X) :- !.
removeAfterSuff(X, Y, X) :- \+ sublist(Y,X).
removeAfterSuff(X, Y, Z) :- append(A, B, X), append(Y, _, B), append(A,Y,Z).

Он использует вырез, так что это немногонекрасиво, но в противном случае предикат 2 даст кучу результатов, если вы передадите [] (да, красный, что угодно).

Вот как это работает, если суффикс НЕ является членом списка,Опция 2 активируется и X и Z равны.В противном случае он говорит: «Существуют два списка, A и B, которые могут составить мой первоначальный список. Этот второй список, B, начинается с моего суффикса, а затем содержит все (и мне все равно, что это за штука). Поскольку я знаю,что A - это все до суффикса, тогда мой результат - это A, объединенный с Y. "

Обратите внимание, что это даст вам несколько результатов для списка, подобного

[a,b,z,z,z,a,b,z,z,z]

Изменить, чтобы добавить: Выможете удалить первую строку, если у вас все в порядке с пустым списком, возвращающим результаты вроде

removeAfterSuff([a,b,c], [], Z).
Z = []
Z = [a]
Z = [a,b]
Z = [a,b,c]
1 голос
/ 17 ноября 2011

Даже если это домашнее задание, полный ответ уже дан, так что ...

remove_after([], _, []).
remove_after([H|L], P, O) :-
        (   append(P, _, [H|L])
        ->  O = P
        ;   O = [H|O1],
            remove_after(L, P, O1) ).
1 голос
/ 17 ноября 2011

Я думаю, вам нужно беспокоиться о трех случаях (так, три правила ...)

  1. Пустой список []
  2. Список начинается с [z,z,z]
  3. Непустой список, который не начинается с [z,z,z]

Подумайте, как бы вы решили это на традиционном языке - вы ходите по списку, пока он не заканчивается, или вы найдете [z,z,z]узор посередине.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...