繁体   English   中英

Haskell关于列表函数中的递归

[英]Haskell about recursion in list function

我正在尝试创建一个函数(我是haskell中的新手),该函数需要两个列表并返回一个列表。 该列表应具有第一个列表的所有元素,这些元素不在第二个列表中,所有第二个列表的元素不在第一个列表中。

因此: func [3,2,1,4] [2,5,1]应该返回[3,4,5]

我认为我的《规范》朝着正确的方向发展,但是其中的一个大错误是。

func :: [Int] -> [Int] -> [Int]
func [] a = a
func a [] = a
func (x:xs) (y:ys) | elem x (y:ys) = filter (/=x) (y:ys)
                   | otherwise = func ys xs

假装对这方面的问题没有任何经验或对base的功能非常熟悉,我将重新编写您的问题说明以描述我们想要的操作,并向您展示如何解决该问题:

在两个列表上获得fun的结果是:第一个列表中的所有元素不在第二个列表中,第二个列表中的所有元素不在第一个中。

要开始用代码表示,请将“ is”替换为=

func l1 l2 = (elementsOfFirstNotInSecond l1 l2) ++(elementsOfFirstNotInSecond l2 l1)

现在我们需要实现elementsOfFirstNotInSecond ,所以让我们从单词开始:

elementsOfFirstNotInSecond两个名单是:如果l1是空列表,则空单,否则,如果头l1 (我们将其称为“ x ”)是其成员l2x consed到elementsOfFirstNotInSecond 尾部l1l2 否则(如果x 不在 l2 ),则只是 l1l2尾部的elementsOfFirstNotInSecond

看看是否可以使用尚未实现的函数将其转换为haskell(例如,您可能要使用( isAMemberOf :: Int -> [Int] -> Bool ),然后重复该过程。

输出顺序重要吗?

如果没有,您可以只使用Data.List列表差异(\\\\)

Prelude > import Data.List
Prelude Data.List> as = [3,2,1,4]
Prelude Data.List> bs = [2,5,1]
Prelude Data.List> notinSec = as \\ bs
Prelude Data.List> notinFst = bs \\ as
Prelude Data.List> ans = notinSec ++ notinFst 
Prelude Data.List> ans
[3,4,5]

由于您想要递归并且是haskell的新手,因此解决方案(朝您的方向移动)将类似于

func (x:xs) (y:ys) | elem x (y:ys) && (not (elem y (x:xs))) = func xs (filter (/=x) (y:ys))
                   | (not (elem x (y:ys))) && (elem y (x:xs)) = func (filter (/=y) (x:xs)) ys
                   | (elem x (y:ys)) && (elem y (x:xs)) = func (filter (/=y) (xs)) (filter (/=x) (ys))
                   | otherwise = x : y : (func xs ys)

但是您可以看到在学习路径的后期,这是多么的丑陋和混乱。 我建议您使用更简单明了的替代方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM