【发布时间】:2011-11-24 09:15:50
【问题描述】:
我是 Haskell 的菜鸟,但对 ActionScript 3.0 Object Orientated 有一些经验。因此,致力于重大的编程过渡。我已经阅读了有关 Haskel 的基本知识,例如算术。我可以编写简单的函数。
作为一项实际任务,我必须在 Haskell 中通过计算机生成名为 tms1 的Thue-Morse sequence。所以应该是这样的:
>tms1 0
0
>tms1 1
1
>tms1 2
10
>tms1 3
1001
>tms1 4
10010110
等等...根据维基百科,我应该使用公式。
t0 = 0
t2n = tn
t2n + 1 = 1 − tn
我不知道如何在 Haskell 中实现这个公式。你能指导我创建一个吗? 这是我到目前为止得到的:
module ThueMorse where
tms1 :: Int -> Int
tms1 0 = 0
tms1 1 = 1
tms1 2 = 10
tms1 3 = 1001
tms1 x = tms1 ((x-1)) --if x = 4 the output will be 1001, i don't know how to make this in a recursion function
我在互联网上做了一些研究,发现了这段代码。
来源: http://pastebin.com/Humyf6Kp
代码:
module ThueMorse where
tms1 :: [Int]
tms1 = buildtms1 [0] 1
where buildtms1 x n
|(n `rem` 2 == 0) = buildtms1 (x++[(x !! (n `div` 2))]) (n+1)
|(n `rem` 2 == 1) = buildtms1 (x++[1- (x !! ((n-1) `div` 2))]) (n+1)
custinv [] = []
custinv x = (1-head x):(custinv (tail x))
tms3 :: [Int]
tms3 = buildtms3 [0] 1
where buildtms3 x n = buildtms3 (x++(custinv x)) (n*2)
intToBinary :: Int -> [Bool]
intToBinary n | (n==0) = []
| (n `rem` 2 ==0) = intToBinary (n `div` 2) ++ [False]
| (n `rem` 2 ==1) = intToBinary (n `div` 2) ++ [True]
amountTrue :: [Bool] -> Int
amountTrue [] = 0
amountTrue (x:xs) | (x==True) = 1+amountTrue(xs)
| (x==False) = amountTrue(xs)
tms4 :: [Int]
tms4= buildtms4 0
where buildtms4 n
|(amountTrue (intToBinary n) `rem` 2 ==0) = 0:(buildtms4 (n+1))
|(amountTrue (intToBinary n) `rem` 2 ==1) = 1:(buildtms4 (n+1))
但是这段代码没有给出想要的结果。非常感谢任何帮助。
【问题讨论】:
-
问题似乎是,您丢弃了前导零。使用列表而不是数字也可以避免一次又一次地转换数字。我一直在想:如果我用大量代码解决一个小问题,那我就做错了。
-
您可以写:
a `rem` 2 == 0/1为even a和odd a。custinv x可以定义为map (\a -> 1-a) x,甚至是custinv = map (1-)。amountTrue x = sum (fromEnum x)或amountTrue x = length (filter id x).
标签: function haskell recursion