2
votes

Prolog convertit une liste de chaînes en liste de nombres

Je suis nouveau chez Prolog et je souhaite convertir une liste de nombres de chaînes en une liste de nombres. J'apprécierais une explication, car j'ai du mal avec les opérations de liste dans cette langue.

Voici ce que j'ai jusqu'à présent (récursivement):

convert([], 0). # This is meant to be the simplest case, if there are no elements left in the list.
convert([H|T], L) :- # This is meant to be executed if there are elements in the list.
   string_to_atom(H, Elm), # Built in function from [here][1].
   convert([T|_],L1). # The recursive call to the tail T. Unsure about how to call this.

Merci d'avance!

Edit: lien vers la fonction string_to_atom:https://www.swi-prolog.org/pldoc/man?predicate=string_to_atom/2


2 commentaires

donc vous voulez transformer quelque chose comme ['' 1 '', '' 2 '', '' 3 ''] en [1,2,3] n'est-ce pas?


c'est correct!


4 Réponses :


1
votes

Vous y étiez presque! Notez que le caractère des commentaires est%, pas #

convert (Xs, Ys) est le prédicat établissant une relation entre Xs et Ys, de telle sorte que lorsqu'il y a des éléments dans Xs, alors l'élément head H est relation avec Elm, où string_to_atom (H, Elm). Donc Elm est l'équivalent atomique de H.

convert([], []). % there are no elements in list Xs
convert([H|Ts], [Elm|Es]) :- % This is meant to be executed if there are elements in the list.
   string_to_atom(H, Elm), % Built in function from [here][1].
   convert(Ts, Es). % The recursive call to the tail T

Vous devriez lire attentivement les explications des prédicats standard comme append / 2. Ils vous donnent la bonne façon de raisonner les relations.


4 commentaires

append / 2 n'est pas trop standard. Peut-être vouliez-vous dire append / 3 (avec trois arguments)?


Comprendre append / 3 m'a été utile quand j'étais (beaucoup) plus jeune! Mais alors, il n'y avait pas StackOverflow ...


Maintenant, j'ai un problème lié aux guillemets. J'ai besoin de convertir une liste de nombres entre guillemets simples en une liste de nombres, par exemple j'ai besoin de convertir: ['1','2','3'] en sortie: [1,2,3] . Tous les autres exemples fonctionnent uniquement avec une liste de nombres entre guillemets doubles vers une liste de nombres, comme: ["1","2","3"] à [1,2,3] .


J'ai découvert que c'était atom_number/2 j'avais besoin pour convertir une liste ['1','2','3'] en [1,2,3]



-1
votes

Tu peux essayer:

stringtonum(A,Y):-
    atom_number(A,K),
    number_codes(K,X1),
    maplist(plus(48),Y,X1).


?-stringtonum("1234",L)
L = [1,2,3,4]

?-stringtonum("548765456",P).
L = [5, 4, 8, 7, 6, 5, 4, 5, 6]


1 commentaires

La façon dont vous utilisez append / 3 n'est pas une bonne idée.



1
votes

Il y a quelques problèmes ici dans cet exemple. J'ai posté une solution ci-dessous pour faire ce que vous voulez.

  1. Les lignes sont commentées dans le prologue SWI avec%. Le code publié n'a pas été compilé avec ma version.
  2. L, L1 et Elm sont des singletons, ce qui indique généralement une erreur. Vous exprimez le programme comme une expression logique, et l'interpréteur ne pourra pas assumer de connexion entre eux. Dans la solution ci-dessous, j'ai combiné L et Elm en une liste combinée dans le terme résultant.
  3. H est toujours un élément et T est une liste. T ne peut donc pas être devant '|', mais peut être utilisé comme une liste à part.
  4. Le «type» de conversion est différent dans les deux faits, car vous utilisez une liste et un nombre dans les différents cas.
    convert([ ], [ ]). 
    convert([H|T], [Elm|L]) :- string_to_atom(H, Elm), convert(T,L). 
    % call with
    % ?- convert(["a","b","c"],L).
    % L=[a, b, c].


0 commentaires

2
votes

Vous ne devriez vraiment pas avoir besoin de faire la récursion manuellement. Utilisez maplist. Et il y a number_string/2 dans SWI-Prolog qui fonctionne dans les deux sens. Donc:

numbers_strings([], []).
numbers_strings([N|Ns], [S|Ss]) :-
    number_string(N, S),
    numbers_string(Ns, Ss).

L'explication est que number_string/2 fonctionne dans les deux sens: chaîne en nombre, ou nombre en chaîne. Consultez la documentation. Et maplist est ce que vous pouvez utiliser pour appliquer un prédicat (comme number_string/2 ) aux listes, sans faire la récursion vous-même. Sinon, vous devrez écrire:

?- maplist(number_string, Numbers, ["1", "-2.0", "0.3e-2"]).
Numbers = [1, -2.0, 0.003].


0 commentaires