2012-02-15 4 views
1

Мне нужно написать предикат Пролога, чтобы проверить, равен ли все элемент на диагонали матрицы NxN сумме всех других элементов в той же строке.Предикат для проверки каждого элемента диагонали матрицы NxN

Например:

check([[1, 0, 1], [1, 2, 1], [7, 8, 15]]) => true 

Любая помощь (совет, ресурс для чтения, ...) очень ценится.

+0

Думаю, мне нужно использовать рекурсию, но я не знаю, как это сделать (алгоритм). –

ответ

1

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

check(Xs) :- check_all(Xs, 0). 
check_all([X|Xs], Index) :- 
    /* do work */ 
    Index1 is Index + 1, check_all(Xs, Index1). 

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

check_all([], _). 

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

check_row(Row, Index) :- 
    ... 

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

nth0(Index, Row, Desired), 

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

nth0(Index, Row, _, Remainder), sumlist(Remainder, Desired) 

Так что производит в общей сложности:

check_row(Row, Index) :- 
    nth0(Index, Row, Desired, Remainder), sumlist(Remainder, Desired). 
check_all([], _). 
check_all([Row|Rows], Index) :- 
    check_row(Row, Index), 
    Index1 is Index + 1, check_all(Rows, Index1). 
check(Xs) :- check_all(Xs, 0). 

Я не проверял этот код, так что я не знаю, работает ли он, и я определенно зависим от библиотеки списков SWI-Prolog, но я надеюсь, что это немного иллюстрирует процесс декларативного программирования.

+0

> Я не тестировал этот код. Хорошая стратегия! –

+0

@ ДМИТРИЙМАЛИКОВ Моя техника дробовика редко производит код, который работает с первой попытки, поэтому я надеюсь, что это компенсирует то, что я делаю чью-то домашнюю работу для них. :) –

1

SWI-Prolog 'библиотека (списки) реализует nth1/3 и sumlist/2.

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

Другим ключевым элементом является forall/2, см. Страницу для иллюстрирующего примера.

Я позволю вам объединить эти элементы в качестве полезного упражнения: заполнить эллипсис ..., будет еще один nth1, sumlist и арифметика, чтобы проверить, что суммированный в 2 раза диагональный элемент.

check(M) :- 
     forall(nth1(I, M, Row), (...)). 

Отметьте примечание, если вам нужен код.

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