2
votes

J'ai des problèmes pour obtenir une liste de listes en une seule liste

J'écris une solution pour calculer les distances entre les nombres dans une liste en utilisant la récursivité, mais j'ai du mal à obtenir la sortie prévue. J'essaie d'obtenir une liste de listes dans une seule liste, mais les tentatives d'utilisation de flatten et append / 2 ne fonctionnent pas. J'ai essayé pendant des heures, et continue à tourner en rond, quelqu'un peut-il me dire ce que je fais de mal s'il vous plaît?

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

Voici l'entrée et la sortie prévues: -

XXX

Sortie actuelle:

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


4 commentaires

Veuillez inclure votre code dans la question afin que nous puissions voir ce que vous avez essayé


Désolé, je suis un débutant dans la publication de questions sur Stackoverflow et je suis un peu confus avec le formatage. Ça devrait être maintenant. Merci.


Code annulé que vous avez supprimé car il est spécifique à la question. Votre code a utilisé des contraintes dans l'exemple et a donc rendu les réponses plus spécifiques. En supprimant le code, les débutants peuvent penser que des contraintes sont nécessaires et qu'elles ne le sont pas.


Est-ce que cela répond à votre question? Obtenir des éléments de la liste de listes


3 Réponses :


2
votes
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].

?- dif(A,B), phrase(seqq([[A|_]|_]), [B|_]).
false.

2 commentaires

Désolé, cela m'a encore plus confus. Je suis vraiment un débutant en swi prolog, existe-t-il une solution plus simple s'il vous plaît?


Salut faux, voulez-vous dire configurer un autre prédicat pour convertir manuellement la liste? Comme le fait généralement append / 2? Pouvez-vous me dire pourquoi append / 2 ne fonctionne pas dans mon cas?



1
votes

Vous pouvez convertir votre prédicat distances / 3 en un prédicat distances / 4 qui renvoie une queue de liste pour les éléments qui vont suivre, en utilisant efficacement un open list :

distances(Bs, B, Ds) :-
    distances(Bs, B, Ds, []).

Exemple d'appel:

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

Pour mieux comprendre cette solution, considérez les résultats de la requête suivante: p>

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

Cette solution est plus efficace que l'appel des prédicats tels que append / 2 ou flatten / 3 à la fin. p>

PS Si vous avez encore besoin d'un prédicat distances / 3 à utiliser ailleurs, vous pouvez le définir facilement:

:- 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).


5 commentaires

Merci beaucoup Paulo, je vais essayer ça. Mon seul problème est que je suis limité à avoir un prédicat distances / 3. Je pourrais cependant en créer un autre en utilisant ce que vous avez suggéré? Ou y a-t-il une autre façon de garder les distances / 3?


@AntMan Vous pouvez définir facilement distances / 3 en utilisant distances / 4 : distances (Bs, B, Ds): - distances (Bs, B, Ds, [ ]). . Cela fonctionnera-t-il dans votre cas?


Parfait Paulo, merci! Cela m'a coincé pendant tant d'heures. J'essayais d'utiliser append (ds, DST) pendant des siècles après l'appel récursif du triangle, mais cela ne le mettrait tout simplement pas dans une liste séparée. Savez-vous pourquoi? C'est illogique lol, car append / 2 est censé prendre une liste de listes et la concaténer en une seule liste


@AntMan Notez que ma réponse est plus efficace que toute solution appelant des prédicats d'ajout ou d'aplatissement.


C'est bien. J'essayais également différentes façons de créer une autre liste et de mettre manuellement les éléments pendant des heures hier, et cela ne fonctionnait tout simplement pas. Essayer de comprendre comment ça marche quand même ... La queue supplémentaire prend tout ce qui reste de l'appel aux distances? Je suis un peu confus, mais super que ça marche



1
votes

Pourquoi ne pas utiliser le prédicat de bibliothèque append / 2 comme ça?

?- append([[1,3,8],[2,7],[5],[]], Xs).
Xs = [1,3,8,2,7,5].


5 commentaires

@repeat je n'ai pas pu le faire fonctionner avec mon code, je ne sais pas pourquoi. C'était ma question initiale


Il n'aimait pas utiliser Ds dans append, même si c'est une liste de listes que je suppose


Utilisez append / 2 : une fois à la fin comme solution rapide, pas dans la clause récursive.


Il doit être dans le prédicat récursif ou au moins appeler un autre prédicat du prédicat récursif à ajouter. Je n'ai pas pu le faire fonctionner de cette façon non plus. Je pense que j'ai besoin d'en savoir plus sur les principes fondamentaux de Prolog pour comprendre pourquoi


Pourquoi ne pas utiliser le prédicat de bibliothèque append / 2 comme ça? car append / 2 produit de nombreuses erreurs inutiles comme dans dif (A, B), append ([[A | _] | _] , [B | _]). qui pourrait échouer silencieusement