所以,我最近开始学习Haskell,我遇到了一个问题,我需要计算所有可能的结果(2^n),如果投掷n个硬币。例如,如果投掷2枚硬币,输出应该是[[H, H], [H, T], [T, H], [T, T]]。同样,3硬币应该是[[H, H, H], [H, H T], [H T H], [T H, H], [H, T, T], [T, T H], [T H T], [T, T, T]]。我的函数对任意的n值都不起作用,它只在已知n的情况下起作用。我正在考虑使用递归,但我不确定语法。
这是我的代码:
outcomes(x:xs) = [[a, b] | a <- states x, b <- states (head xs)]
其中,函数状态为:
states _ = [True, False]
此函数适用于n = 2。请让我知道如何使它工作的任何输入n.
您可以在这里使用递归。我们可以构造一个函数,它接受一个包含元素[a]
和一个元素Int
的列表,因此:
outcomes :: [a] -> Int -> [[a]]
如果整数小于等于0,那么只有一个可能的结果:空列表。因此,返回一个包含一个空列表的列表:
outcomes _ n | n <= 0 = [[]]
对于递归的情况,可以从列表中取出一个元素,然后对相同的值列表进行递归,但是要创建少一个元素的结果,然后将取出的元素加到这些结果前面。
outcomes ls n = [ … | x < ls, xs <- … ]
这里我留下…
部分作为练习。在第一个…
片段中,需要在xs
前面加上x
。在第二个示例中,您需要进行递归调用。
outcomes
为:
outcomes :: [a] -> Int -> [[a]]
outcomes _ n | n <= 0 = [[]]
outcomes ls n = [ … | x < ls, xs <- … ]
因为你想让你的函数工作在任意数量的翻转n
,它应该接受一个Int形参:否则你怎么得到一个Int?而且,正如评论中建议的那样,递归是在Haskell中做类似循环的事情的方式,因此您将需要一个基本情况和一个递归情况。对于计数,0是一个自然的基础情况,也是这里使用的最佳情况,但是使用1作为基础情况对于初学者来说更容易理解,所以我们现在只让n=0
的函数中断。
outcomes :: Int -> [[Bool]]
outcomes 1 = _
outcomes n = _
1的结果应该是什么,即一次翻转?一旦你有了这个,你能在outcomes (n - 1)
的基础上实现outcomes n
吗?如果是这样,你就完蛋了。如果没有,你会有更好的材料来做新问题,因为你已经得到了解决方案的一半。
作为额外的学分,一旦这样做了,看看你是否能很好地理解递归,为outcomes 0
选择一个好的值,可以代替outcomes 1
作为你的基本情况。