Ответ в теме: Список элементов, встречающихся ровно один раз

      Комментарии к записи Ответ в теме: Список элементов, встречающихся ровно один раз отключены
#2498

В целом подход к решению этой задачи точно такой же, как к “получить список элементов, встречающихся более одного раза“. Мы также будем использовать метод накапливающего параметра, поэтому основная функция будет вызывать вспомогательную, инициализируя буфер. Однако, нам нужен список элементов, встречающихся лишь один раз, поэтому нам потребуется еще один буфер для хранения списка уже обработанных элементов, иначе мы не сможем отличить последнее вхождение повторяющегося элемента он уникального. Изначально оба буфера инициализируются пустыми списками:

single_set(List, Result):-
  single_set(List, [], [], Result).

Вспомогательная функция:

  • присваивает результату накапливающий параметр если исходный список кончился;
  • дописывает первый элемент списка в накопитель результата и список обработанных элементов если он отсутствует среди обработанных элементов и среди хвоста (еще необработанных элементов) во время рекурсивного вызова;
  • добавляет первый элемент к списку уже обработанных узлов, оставляя накопитель неизменным во время рекурсивной обработки хвоста списка если не выполнилось ни одной из других условий (элемент не является уникальным):

single_set([], _Processed, BufferResult, BufferResult):-!.
single_set([Head|Tail], Processed, BufferResult, Result):-
  NOT(member(Head, Tail)),
  NOT(member(Head, Processed)), !,
  single_set(Tail, [Head|Processed], [Head|BufferResult], Result).
single_set([Head|Tail], Processsed, BufferResult, Result):-
  single_set(Tail, [Head|Processsed], BufferResult, Result).

Для поиска элементов в списке в этом решении используется функция member, код которой надо скопировать в свою программу при использовании Visual/Turbo Prolog (во многих других диалектах она является встроенной).

Вложения: