Как найти N-й элемент списка и распечатать его? - PullRequest
0 голосов
/ 06 декабря 2011

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

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

findthird([], Result).

findthird(List, Result) :- secondFunc(List, 0, Result).

secondFunc([Head|Tail], Count, Result) :- 
    Count < 3, Count is Count+1, secondFunc(Tail, Count, Result).

secondFunc([Head|Tail], Count, [Head|Result]).

Есть идеи для этого?

Вывод, который я получаю сейчас:

| ?- findthird([2,3,4], Result).

Result = [2|_]

yes

Мне все еще тяжело оборачиваться вокруг Пролога, я просто не могу этого понять.

Любая помощь ценится как всегда,

Спасибо.

Обновлено с новым кодом попытки ***

Обновлено ** Это код, который решил мою проблему:

findthird([], Result).
findthird(List, Result) :- secondFunc(List, 0, Result).

secondFunc([], Count, []).
secondFunc([Head|Tail], Count, Result) :- 
     Count1 is Count+1, Count1 < 3, secondFunc(Tail, Count1, Result).
secondFunc([Head|Tail], Count, Head).

Введите:

| ?- findthird([3,4,5], Result).

Вывод:

Result = 5 ? 

yes

Введите:

| ?- findthird([3,4,5,6,7], Result).

Выход:

Result = 5 ? 

yes

1 Ответ

4 голосов
/ 06 декабря 2011

Прежде всего, вы должны понимать, что в Прологе вы не манипулируете возвращаемыми значениями функции. Причина этого в том, что вы манипулируете не функциями, а предикатами. Таким образом, length (List) никогда не вычисляется как число, а как true или false, как любой другой предикат. Когда вы пишете findelement(List, length(List), len..., предикат findelement не будет вызываться с чем-то вроде [a, b, c] и 3, он будет вызываться с чем-то вроде [a, b, c] и length([a, b, c]). Так что ваша программа уже не может работать.

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

  • пункт для инициализации

  • пункт о наследственности

В вашей программе нет условия инициализации. Это означает, что когда рекурсия достигает [], никакое предложение не может с этим справиться, и это не помогает Остальное тоже неверно, но я думаю, что особенно важно сначала правильно сформулировать принципы рекурсии.

Чтобы проиллюстрировать это, не портя проблему для вас (в конце концов, это домашняя работа), я приведу пример: скажем, вы хотите проверить, безопасна ли овчарка. Овчарня безопасна, если в ней нет волка. Если мы представим овчарню списком, а волка - атомом wolf, мы можем написать предикат так:

Инициализация: если овчарня пуста, она в безопасности, там нет волка.

safe_sheepfold([]).

Наследственность: если овчарня безопасна с n-1 членами, то безопасно с n членами, если добавленный член не является волком:

safe_sheepfold([Animal|Sheepfold]) :-
    Animal =\= wolf,
    safe_sheepfold(Sheepfold).

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

Чтобы вы подумали об этом на более конкретном примере, вот классический предикат факториал (он также использует арифметику):

Вот наш пункт инициализации:

factorial(0, 1).

Вот наш пункт о наследственности:

factorial(N, F) :-
    N > 0,
    NextN is N - 1,
    factorial(NextN, NextF),
    F is NextF * N.

Для простоты я не делал этот хвост предиката рекурсивным и не использовал сокращения, вы узнаете об этом позже!

Надеюсь, мой бродяга поможет мне.

редактировать пост обновления:

Это почти так! Теперь просто еще несколько подсказок: желаемый результат - это не список, это просто элемент, поэтому попробуйте изменить последнее предложение, чтобы он просто возвращал элемент, а не список с элементом. И предложение инициализации на самом деле является вашим последним предложением здесь (то, что проверяет, если вы выше 3), так что вам не нужно это с []! Ты почти у цели:)

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