Удалите дубликаты в списке (Пролог)

Я абсолютно плохо знаком с Прологом и пробующий некоторые упражнения. Один из них:

Запишите набор предиката (InList, OutList), который берет в качестве входа произвольный список и возвращает список, в котором каждый элемент входного списка появляется только однажды.

Вот мое решение:

member(X,[X|_]).
member(X,[_|T]) :- member(X,T).

set([],[]).
set([H|T],[H|Out]) :-
    not(member(H,T)),
    set(T,Out).
set([H|T],Out) :-
    member(H,T),
    set(T,Out).

Мне не разрешают использовать ни один из встроенных предикатов (Это было бы лучше, даже не используют not/1). Проблема, это set/2 дает несколько тех же решений. Чем больше повторений во входном списке, тем закончится больше решений. Что я делаю неправильно? Заранее спасибо.

15
задан evgeniuz 14 February 2010 в 10:49
поделиться

1 ответ

Для вашего приложения нет официальной домашней папки. В blackberry вы в основном можете читать/писать только о чем угодно/где угодно (ну, вы можете получить SecurityException / IOException , если вы попытаетесь изменить некоторые файлы). Запись в SDCard/внутреннюю память можно выполнить с помощью путей, описанных здесь . Если вы беспокоитесь о том, что кто-то увидит и изменит ваши данные, вы можете сделать не так много, кроме как настроить ваши файлы и каталоги как скрытые с помощью FileConnection.setHidden (true) , но это очень плохо, так как их можно увидеть даже из собственного браузера файлов BlackBerry, если пользователь выберет отображение скрытых файлов из меню.

Edit: Вы, конечно, можете зашифровать/расшифровать свои данные, но это не помешает кому-то удалить их.

-121--5044389-

Имеет смысл, поскольку высота элемента, естественно, больше, чем задана. входным элементам присваивается высота, которой в этом случае должно быть достаточно для того, чтобы содержать текст элемента, но устанавливается меньшее значение. Чтобы показать это, удалите настройку высоты.

-121--3238842-

Вы получаете несколько решений из-за задержки Prolog. Технически каждое предоставленное решение является правильным, поэтому оно генерируется. Если нужно создать только одно решение, в какой-то момент придется прекратить обратное отслеживание. Для этого используется Prolog cut . Вы можете найти, что чтение об этом поможет вам с этой проблемой.

Обновление: справа. Предикат членов () вычисляется как true несколькими различными способами, если первая переменная находится в нескольких позициях во второй переменной.

Я использовал имя mymember () для этого предиката, чтобы не конфликтовать с предикатом GNU Prolog членов () . Моя база знаний теперь выглядит следующим образом:

mymember(X,[X|_]).
mymember(X,[_|T]) :- mymember(X,T).

not(A) :- \+ call(A).

set([],[]).
set([H|T],[H|Out]) :-
    not(mymember(H,T)),
    set(T,Out).
set([H|T],Out) :-
    mymember(H,T),
    set(T,Out).

Итак, mymber (1, [1, 1, 1]). оценивает как true в трёх различных путях:

| ?- mymember(1, [1, 1, 1]).

true ? a

true

true

no

Если вы хотите иметь только один ответ, вам придется использовать вырез. Изменение первого определения mymber () на следующее:

mymember(X,[X|_]) :- !.

Решает проблему.

Кроме того, вы можете избежать не () вообще, если хотите, путем определения предиката notamember () . Выбор за вами.

10
ответ дан 1 December 2019 в 02:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: