将数字列表转换为自然数

时间:2019-01-06 23:08:17

标签: haskell

给出一个代表自然数的数字列表,然后以2为底的基数,如何输出正确的自然数。即给定[1,2,3]和以10为底,我们得到123。给定[1,0,1]和以2为底,我们得到5。

有一些示例涉及使用div和mod将数字转换为列表,但是我不知道如何进行反向转换(对于二进制数,对于小数,它很容易将数字列表直接转换为int,但是我假设在两种情况下都可以使用一种数学方法)。

--For decimal conversion:
fromDigits :: [Integer] -> Integer
fromDigits xs = aux xs 0
where aux [] acc = acc
      aux (x:xs) acc  = aux xs ((acc * 10) + x)

1 个答案:

答案 0 :(得分:5)

具有基数 r 的位置数字系统的结构如下:数字 a 1 a 2 ... a n ,其中 a i 为数字,值:

sum of a_i times r^(n-i)

所以这意味着我们可以通过以下方式获取数字序列的数字:

fromDigits :: (Num a, Foldable f) => a -> f a -> a
fromDigits r = foldl (\a x -> r * a + x) 0

或者从语法上讲更加紧凑:

fromDigits :: (Num a, Foldable f) => a -> f a -> a
fromDigits r = foldl ((+) . (r *)) 0

因此,每次迭代时,我们将累加器与基数r相乘,然后将下一个数字加到它上。如果数字中包含 n 个数字,则最后一个数字因此将与基数r n 相乘。

例如,数字1425对于不同的半径具有不同的值:

Prelude> fromDigits 6 [1,4,2,5]
377
Prelude> fromDigits 7 [1,4,2,5]
558
Prelude> fromDigits 8 [1,4,2,5]
789
Prelude> fromDigits 9 [1,4,2,5]
1076
Prelude> fromDigits 10 [1,4,2,5]
1425