2016-05-23 12 views
3

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

compare([L1,L2,L3,L4],[W1,W2,W3,W4]) :- 
((W1 \= L1, W2 = L2, W3 = L3, W4 = L4); 
(W1 = L1, W2 \= L2, W3 = L3, W4 = L4); 
(W1 = L1, W2 = L2, W3 \= L3, W4 = L4); 
(W1 = L1, W2 = L2, W3 = L3, W4 \= L4)). 

Это работает, но есть упрощенный способ?

Спасибо.

ответ

3

Вы правы, что, несмотря на то, что ваше решение работает, оно не очень чистое и непригодное для использования, поскольку оно работает только для списков длины 4. Попробуем определить рекурсивный предикат, который работает для списков любого размера.

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

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

compare([H|T1], [H|T2]) :- compare(T1, T2). 

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

compare([H1|T1], [H2|T1]) :- H1 \= H2. 

Там, вот и все! Теперь вы можете заметить выход, такие как это:

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

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

Собираем все вместе и код становится:

compare([H|T1], [H|T2]) :- !, compare(T1, T2). 
compare([_|T], [_|T]). 
+1

Это то, что нужно! Спасибо! – KonaKona

+1

Работает нормально (+1), но с оговоркой: оба списка должны быть без переменных, иначе код ведет себя немонотонно ... – repeat

 Смежные вопросы

  • Нет связанных вопросов^_^