使用Haskell将数字拆分为数字

Gre*_*g B 32 haskell

给定一个任意数字,我如何单独处理数字的每个数字?

编辑 我添加了一个Foo可能做的事情的基本示例.

例如,在C#中,我可能会这样做:

static void Main(string[] args)
{
    int number = 1234567890;
    string numberAsString = number.ToString();

    foreach(char x in numberAsString)
    {
        string y = x.ToString();
        int z = int.Parse(y);
        Foo(z);
    }
}

void Foo(int n)
{
    Console.WriteLine(n*n);
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*rke 84

你听说过div和mod吗?

如果您想先处理最重要的数字,您可能想要反转数字列表.将数字转换为字符串是一种受损的做事方式.

135 `div` 10 = 13
135 `mod` 10 = 5
Run Code Online (Sandbox Code Playgroud)

概括为一个函数:

digs :: Integral x => x -> [x]
digs 0 = []
digs x = digs (x `div` 10) ++ [x `mod` 10]
Run Code Online (Sandbox Code Playgroud)

或者相反:

digs :: Integral x => x -> [x]
digs 0 = []
digs x = x `mod` 10 : digs (x `div` 10)
Run Code Online (Sandbox Code Playgroud)

这视为0没有数字.如果你愿意,一个简单的包装函数可以处理这种特殊情况.

请注意,此解决方案不适用于负数(输入x必须是整数,即整数).

  • [quotRem](http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Prelude.html#v%3AquotRem)。 (3认同)

muh*_*ten 19

digits :: Integer -> [Int]
digits = map (read . (:[])) . show
Run Code Online (Sandbox Code Playgroud)

或者你可以把它归还[]:

digits :: Integer -> [Int]
digits = map (read . return) . show
Run Code Online (Sandbox Code Playgroud)

或者,使用Data.Char.digitToInt:

digits :: Integer -> [Int]
digits = map digitToInt . show
Run Code Online (Sandbox Code Playgroud)

和丹尼尔一样,但是点免费使用Int,因为数字不应该超过maxBound :: Int.

  • 无论如何,`digitToInt`版本可能更好,而且`:[]`对我来说稍微明显一点.呃,我会编辑它.我不知道纯粹来自哪里,所以. (2认同)

ham*_*mar 13

您也可以digits从Hackage 重用.


Dan*_*iel 12

使用您帖子中使用的相同技术,您可以:

digits :: Integer -> [Int]
digits n = map (\x -> read [x] :: Int) (show n)
Run Code Online (Sandbox Code Playgroud)

看到它的实际效果:

Prelude> digits 123
[1,2,3]
Run Code Online (Sandbox Code Playgroud)

这有帮助吗?


jon*_*tar 11

教科书展开

import qualified Data.List as L
digits = reverse . L.unfoldr (\x -> if x == 0 then Nothing else Just (mod x 10, div x 10))
Run Code Online (Sandbox Code Playgroud)


Lan*_*dei 10

您可以使用

digits = map (`mod` 10) . reverse . takeWhile (> 0) . iterate (`div` 10)
Run Code Online (Sandbox Code Playgroud)

或反向订单

rev_digits = map (`mod` 10) . takeWhile (> 0) . iterate (`div` 10)
Run Code Online (Sandbox Code Playgroud)

迭代部分生成一个无限列表,将每个步骤中的参数除以10,因此12345变为[12345,1234,123,12,1,0,0 ..].takeWhile部分仅采用列表中有趣的非null部分.然后我们反转(如果我们想要)并取出每个数字列表的最后一位数字.

我在这里使用了无点样式,所以你可以想象"方程式"两侧的一个看不见的参数.但是,如果你想要把它写这样,你需要替换顶级.$:

digits n = map(`mod` 10) $ reverse $ takeWhile (> 0) $ iterate (`div`10) n
Run Code Online (Sandbox Code Playgroud)