У меня проблемы с получением списка списков в один список - PullRequest
2 голосов
/ 04 апреля 2019

Я пишу решение для определения расстояний между числами в списке, используя рекурсию, но изо всех сил пытался получить ожидаемый результат. Я пытаюсь получить список списков в один список, но попытки использовать flatten и append / 2 не работают. Я пытался часами и продолжаю ходить кругами, может кто-нибудь сказать мне, что я делаю не так, пожалуйста?

:- use_module(library(clpfd)).

difference([],_,[]).
differwnce([L|Ls],X,[DST|Ds]) :-
   DST #= abs(X - L),
   difference(Ls,X,Ds).

differences[],[]).
differences([L|Ls], [DST|Tail]) :-
   difference(Ls,X,DST),
   differences(Ls, Tail).

Вот предполагаемый ввод и вывод: -

?- differences([1,2,4,9],Ds).
Ds = [1,3,8,2,7,5].

Токовый выход:

Ds = [[1,3,8],[2,7],[5],[]].

Ответы [ 3 ]

2 голосов
/ 04 апреля 2019
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

seqq([]) --> [].
seqq([Es|Ess]) -->
  seq(Es),
  seqq(Ess).

?- phrase(seqq([[1,3,8],[2,7],[5],[]]), Es).
Es = [1,3,8,2,7,5].
1 голос
/ 04 апреля 2019

Почему бы не использовать предикат библиотеки append/2, как это?

?- append([[1,3,8],[2,7],[5],[]], Xs).
Xs = [1,3,8,2,7,5].
1 голос
/ 04 апреля 2019

Вы можете преобразовать свой предикат distances/3 в предикат distances/4, который возвращает хвост списка для последующих элементов, эффективно используя открытый список :

:- use_module(library(clpfd)).

distances([], _, Tail, Tail).
distances([BN| Bs], B, [DST| Ds], Tail) :-
   DST #= abs(B - BN),
   distances(Bs, B, Ds, Tail).

triangle([], []).
triangle([BN| Bs], Ds) :-
    distances(Bs, BN, Ds, Tail),
    triangle(Bs, Tail).

Пример вызова:

?- triangle([1,2,4,9], Ds).
Ds = [1, 3, 8, 2, 7, 5].

Чтобы лучше понять это решение, рассмотрим результаты следующего запроса:

?- distances([2,4,9], 1, Ds, Tail).
Ds = [1, 3, 8| Tail].

Это решение более эффективно, чем вызов предикатов, таких как append/2 или flatten/3 в конце.

PS Если вам все еще нужен предикат distances/3 для использования в другом месте, вы можете легко определить его:

distances(Bs, B, Ds) :-
    distances(Bs, B, Ds, []).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...