Пролог расплющил список - PullRequest
4 голосов
/ 17 июня 2011
flatten([A|B],R):- (islist(A)->(flatten(A,R1),R=R1);(write(A),append([A],R1,R))), flatten(B,R1).
    flatten(X,X).
    islist([_|_]).

Это код, который я написал, но у меня странная проблема ..

Я получаю

257 ?- flatten([1,[],2,[3],[3,[3,5]]],R).
1[]23335335
R = [1, [], 2, [3], [3, [3, 5]]] .

Хотя числа из записи не являются списком, они добавляются в виде списка:S ...

1 Ответ

7 голосов
/ 17 июня 2011

В вашем определении flatten / 2 есть некоторые ошибки:

Ваше первое предложение не будет выполнено, потому что если A - список, он сначала создаст экземпляр R1 с R, а затем вы попытаетесь снова объединить его с flatten (B, R1).

сглаживаются (X, X).-> Этот пункт оставляет список «как есть» без выравнивания.

Проверьте эту другую реализацию:

flatten(List, Flattened):-
  flatten(List, [], Flattened).

flatten([], Flattened, Flattened).
flatten([Item|Tail], L, Flattened):-
  flatten(Item, L1, Flattened),
  flatten(Tail, L, L1).
flatten(Item, Flattened, [Item|Flattened]):-
  \+ is_list(Item).

Здесь мы используем два предиката: flatten / 2 и flatten / 3.«Работа» будет выполнена в flatten / 3, где второй аргумент будет содержать промежуточный плоский список.

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

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

Последнее предложение является «базовым случаем» для элементов, не входящих в список,Он добавляет элемент в начало промежуточного уплощенного списка, но делает это только для элементов, которые не являются списками, как это было учтено во втором пункте.

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