Comment mettre en œuvre Décimal à Binaire de la fonction en Haskell
J'ai mis en place un binaire à décimal fonction en Haskell et je suis actuellement en train de travailler sur une fonction qui permettrait de convertir un nombre décimal en une valeur binaire. (Je suis conscient que ces fonctionnalités sont disponibles quelque part même si ils ne font pas partie de Prélude.hs)
Je suis venu avec le code suivant pour un C-type langue de la procédure, mais j'ai du mal à l'adapter dans le paradigme fonctionnel.
while (n > 0)
{
if (n % 2 == 1)
str = str + "1";
else
str = str + "0";
n = n / 2;
}
Je me suis aventuré dans la programmation fonctionnelle en Haskell seulement récemment, donc je suis assez nouveau dans le fonctionnel manière de penser. J'ai tenté ci-dessus en utilisant à la fois la récursivité et d'une compréhension de liste, mais je ne suis pas sûr de la manière de placer les gardes et la logique correctement puisque cela implique de multiples conditions. J'utilise un Int list pour tenir le séparer les bits binaires.
--Decimal to binary
toBin:: Int -> [Int]
toBin 0 = [0]
toBin n | (n % 2 == 1) =
|(n % 2 == 0) =
J'ai compris que ce modèle serait de laisser le programme choisir de garde et de fin de l'évaluation de la fonction. Suis-je sur la mauvaise voie?
Ci-dessous est ce que je suis venu avec la récursion primitive de convertir n'importe quelle base (moins de 10, à la place de l'2) décimales.
toDecimal :: [Int] -> Int
toDecimal [] = 0
toDecimal (x:xs) = (x * 2 ^(length xs)) + bin xs
Merci d'avance.
OriginalL'auteur Tru | 2012-02-06
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas
%
opérateur, vous êtes probablement à la recherche pour`mod`
à la place:Gardes vous laissent le choix entre plusieurs branches d'une fonction. Dans ce cas, chaque
...
sera le résultat detoBin n
si son correspondant condition est vraie. Pour ajouter deux listes ensemble, vous pouvez utiliser le++
opérateur, et`div`
correspond à la division entière:Cependant, ce qui a un peu de problèmes. Pour commencer, il commence toujours le résultat avec
0
, ce qui est redondant; en outre, à l'aide de++ [1]
est lent, car il doit passer par l'ensemble de la liste pour ajouter un élément à la fin; il serait préférable de ajouter chaque élément que nous allons, et puis inverse le résultat à la fin.Pour résoudre ces deux choses, nous allons les diviser
toBin
dans une fonction principale et une fonction d'assistance:Dans cette version, nous utilisons la
:
opérateur, qui prend une valeur et une liste et retourne la liste avec la valeur ajouté au début. Nous avons également retourne un résultat vide pour 0 dans notre aide, et de gérer l'0 cas danstoBin
au lieu de cela, de sorte qu'il n'y a pas plus de 0 que nécessaire dans le résultat.Nous pouvons simplifier
helper
le code en sautant les gardes tout à fait, puisque nous venons d'écrire le résultat den `mod` 2
de nouveau sur le côté droit:Enfin, il y a une fonction qui fait un
div
et unmod
d'un seul coup, ce qui peut être plus efficace:Comme une note complémentaire, ce n'est pas vraiment convertir un nombre décimal en binaire, il convertit un entier en binaire; Haskell implémentations sont peu susceptibles de stocker des entiers en format décimal, même si elles sont écrites et imprimées dans ce format. Pour écrire un complet de conversion de décimal à binaire, une fonction qui analyse une chaîne décimale en un entier serait nécessaire.
read
?Oui, mais on peut supposer que l'OP est en train d'essayer de mettre en œuvre ce à partir de zéro 🙂 Après tout,
showIntAtBase
existe aussi.OriginalL'auteur ehird
OriginalL'auteur mordo
0 et 1 sont des cas triviaux.
si n est pair, alors vous devriez ajouter à zéro à la fin, sinon vous l'ajouter.
C'est une bonne pratique pour attraper tout ce qui dans votre dernier garde d'expression (c'est pourquoi j'ai utilisé autrement, qui est le même que le Vrai)
OriginalL'auteur Mariy
Vous pouvez utiliser le
unfoldr
fonction de laData.List
module etintToDigit
deData.Char
:Ce qui se passe ici est la
unfoldr
fonction processus l'entrée à l'aide des fonction anonyme jusqu'à ce qu'il retourneNothing
, tandis que le regroupement de la première valeur deJust
dans une liste. Cette liste contientInt
s, de sorte qu'ils doivent être convertis àChar
s à l'aide deintToDigit
et ensuite inversée, puisqu'ils sont recueillis dans un ordre inverse. Une liste deChar
s est une chaîne de caractères en Haskell, de sorte que vous avez terminé.OriginalL'auteur Wojciech Gac